UNPKG

611 kBJavaScriptView Raw
1/**
2 * Make a map and return a function for checking if a key
3 * is in that map.
4 * IMPORTANT: all calls of this function must be prefixed with
5 * \/\*#\_\_PURE\_\_\*\/
6 * So that rollup can tree-shake them if necessary.
7 */
8function makeMap(str, expectsLowerCase) {
9 const map = Object.create(null);
10 const list = str.split(',');
11 for (let i = 0; i < list.length; i++) {
12 map[list[i]] = true;
13 }
14 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
15}
16
17/**
18 * dev only flag -> name mapping
19 */
20const PatchFlagNames = {
21 [1 /* TEXT */]: `TEXT`,
22 [2 /* CLASS */]: `CLASS`,
23 [4 /* STYLE */]: `STYLE`,
24 [8 /* PROPS */]: `PROPS`,
25 [16 /* FULL_PROPS */]: `FULL_PROPS`,
26 [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
27 [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
28 [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
29 [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
30 [512 /* NEED_PATCH */]: `NEED_PATCH`,
31 [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
32 [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
33 [-1 /* HOISTED */]: `HOISTED`,
34 [-2 /* BAIL */]: `BAIL`
35};
36
37/**
38 * Dev only
39 */
40const slotFlagsText = {
41 [1 /* STABLE */]: 'STABLE',
42 [2 /* DYNAMIC */]: 'DYNAMIC',
43 [3 /* FORWARDED */]: 'FORWARDED'
44};
45
46const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
47 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
48 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
49const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
50
51const range = 2;
52function generateCodeFrame(source, start = 0, end = source.length) {
53 // Split the content into individual lines but capture the newline sequence
54 // that separated each line. This is important because the actual sequence is
55 // needed to properly take into account the full line length for offset
56 // comparison
57 let lines = source.split(/(\r?\n)/);
58 // Separate the lines and newline sequences into separate arrays for easier referencing
59 const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
60 lines = lines.filter((_, idx) => idx % 2 === 0);
61 let count = 0;
62 const res = [];
63 for (let i = 0; i < lines.length; i++) {
64 count +=
65 lines[i].length +
66 ((newlineSequences[i] && newlineSequences[i].length) || 0);
67 if (count >= start) {
68 for (let j = i - range; j <= i + range || end > count; j++) {
69 if (j < 0 || j >= lines.length)
70 continue;
71 const line = j + 1;
72 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
73 const lineLength = lines[j].length;
74 const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
75 if (j === i) {
76 // push underline
77 const pad = start - (count - (lineLength + newLineSeqLength));
78 const length = Math.max(1, end > count ? lineLength - pad : end - start);
79 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
80 }
81 else if (j > i) {
82 if (end > count) {
83 const length = Math.max(Math.min(end - count, lineLength), 1);
84 res.push(` | ` + '^'.repeat(length));
85 }
86 count += lineLength + newLineSeqLength;
87 }
88 }
89 break;
90 }
91 }
92 return res.join('\n');
93}
94
95/**
96 * On the client we only need to offer special cases for boolean attributes that
97 * have different names from their corresponding dom properties:
98 * - itemscope -> N/A
99 * - allowfullscreen -> allowFullscreen
100 * - formnovalidate -> formNoValidate
101 * - ismap -> isMap
102 * - nomodule -> noModule
103 * - novalidate -> noValidate
104 * - readonly -> readOnly
105 */
106const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
107const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
108/**
109 * Boolean attributes should be included if the value is truthy or ''.
110 * e.g. `<select multiple>` compiles to `{ multiple: '' }`
111 */
112function includeBooleanAttr(value) {
113 return !!value || value === '';
114}
115
116function normalizeStyle(value) {
117 if (isArray(value)) {
118 const res = {};
119 for (let i = 0; i < value.length; i++) {
120 const item = value[i];
121 const normalized = isString(item)
122 ? parseStringStyle(item)
123 : normalizeStyle(item);
124 if (normalized) {
125 for (const key in normalized) {
126 res[key] = normalized[key];
127 }
128 }
129 }
130 return res;
131 }
132 else if (isString(value)) {
133 return value;
134 }
135 else if (isObject(value)) {
136 return value;
137 }
138}
139const listDelimiterRE = /;(?![^(]*\))/g;
140const propertyDelimiterRE = /:(.+)/;
141function parseStringStyle(cssText) {
142 const ret = {};
143 cssText.split(listDelimiterRE).forEach(item => {
144 if (item) {
145 const tmp = item.split(propertyDelimiterRE);
146 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
147 }
148 });
149 return ret;
150}
151function normalizeClass(value) {
152 let res = '';
153 if (isString(value)) {
154 res = value;
155 }
156 else if (isArray(value)) {
157 for (let i = 0; i < value.length; i++) {
158 const normalized = normalizeClass(value[i]);
159 if (normalized) {
160 res += normalized + ' ';
161 }
162 }
163 }
164 else if (isObject(value)) {
165 for (const name in value) {
166 if (value[name]) {
167 res += name + ' ';
168 }
169 }
170 }
171 return res.trim();
172}
173function normalizeProps(props) {
174 if (!props)
175 return null;
176 let { class: klass, style } = props;
177 if (klass && !isString(klass)) {
178 props.class = normalizeClass(klass);
179 }
180 if (style) {
181 props.style = normalizeStyle(style);
182 }
183 return props;
184}
185
186// These tag configs are shared between compiler-dom and runtime-dom, so they
187// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
188const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
189 'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
190 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
191 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
192 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
193 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
194 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
195 'option,output,progress,select,textarea,details,dialog,menu,' +
196 'summary,template,blockquote,iframe,tfoot';
197// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
198const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
199 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
200 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
201 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
202 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
203 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
204 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
205 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
206 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
207 'text,textPath,title,tspan,unknown,use,view';
208const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
209/**
210 * Compiler only.
211 * Do NOT use in runtime code paths unless behind `true` flag.
212 */
213const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
214/**
215 * Compiler only.
216 * Do NOT use in runtime code paths unless behind `true` flag.
217 */
218const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
219/**
220 * Compiler only.
221 * Do NOT use in runtime code paths unless behind `true` flag.
222 */
223const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
224
225function looseCompareArrays(a, b) {
226 if (a.length !== b.length)
227 return false;
228 let equal = true;
229 for (let i = 0; equal && i < a.length; i++) {
230 equal = looseEqual(a[i], b[i]);
231 }
232 return equal;
233}
234function looseEqual(a, b) {
235 if (a === b)
236 return true;
237 let aValidType = isDate(a);
238 let bValidType = isDate(b);
239 if (aValidType || bValidType) {
240 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
241 }
242 aValidType = isSymbol(a);
243 bValidType = isSymbol(b);
244 if (aValidType || bValidType) {
245 return a === b;
246 }
247 aValidType = isArray(a);
248 bValidType = isArray(b);
249 if (aValidType || bValidType) {
250 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
251 }
252 aValidType = isObject(a);
253 bValidType = isObject(b);
254 if (aValidType || bValidType) {
255 /* istanbul ignore if: this if will probably never be called */
256 if (!aValidType || !bValidType) {
257 return false;
258 }
259 const aKeysCount = Object.keys(a).length;
260 const bKeysCount = Object.keys(b).length;
261 if (aKeysCount !== bKeysCount) {
262 return false;
263 }
264 for (const key in a) {
265 const aHasKey = a.hasOwnProperty(key);
266 const bHasKey = b.hasOwnProperty(key);
267 if ((aHasKey && !bHasKey) ||
268 (!aHasKey && bHasKey) ||
269 !looseEqual(a[key], b[key])) {
270 return false;
271 }
272 }
273 }
274 return String(a) === String(b);
275}
276function looseIndexOf(arr, val) {
277 return arr.findIndex(item => looseEqual(item, val));
278}
279
280/**
281 * For converting {{ interpolation }} values to displayed strings.
282 * @private
283 */
284const toDisplayString = (val) => {
285 return isString(val)
286 ? val
287 : val == null
288 ? ''
289 : isArray(val) ||
290 (isObject(val) &&
291 (val.toString === objectToString || !isFunction(val.toString)))
292 ? JSON.stringify(val, replacer, 2)
293 : String(val);
294};
295const replacer = (_key, val) => {
296 // can't use isRef here since @vue/shared has no deps
297 if (val && val.__v_isRef) {
298 return replacer(_key, val.value);
299 }
300 else if (isMap(val)) {
301 return {
302 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
303 entries[`${key} =>`] = val;
304 return entries;
305 }, {})
306 };
307 }
308 else if (isSet(val)) {
309 return {
310 [`Set(${val.size})`]: [...val.values()]
311 };
312 }
313 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
314 return String(val);
315 }
316 return val;
317};
318
319const EMPTY_OBJ = Object.freeze({})
320 ;
321const EMPTY_ARR = Object.freeze([]) ;
322const NOOP = () => { };
323/**
324 * Always return false.
325 */
326const NO = () => false;
327const onRE = /^on[^a-z]/;
328const isOn = (key) => onRE.test(key);
329const isModelListener = (key) => key.startsWith('onUpdate:');
330const extend = Object.assign;
331const remove = (arr, el) => {
332 const i = arr.indexOf(el);
333 if (i > -1) {
334 arr.splice(i, 1);
335 }
336};
337const hasOwnProperty = Object.prototype.hasOwnProperty;
338const hasOwn = (val, key) => hasOwnProperty.call(val, key);
339const isArray = Array.isArray;
340const isMap = (val) => toTypeString(val) === '[object Map]';
341const isSet = (val) => toTypeString(val) === '[object Set]';
342const isDate = (val) => toTypeString(val) === '[object Date]';
343const isFunction = (val) => typeof val === 'function';
344const isString = (val) => typeof val === 'string';
345const isSymbol = (val) => typeof val === 'symbol';
346const isObject = (val) => val !== null && typeof val === 'object';
347const isPromise = (val) => {
348 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
349};
350const objectToString = Object.prototype.toString;
351const toTypeString = (value) => objectToString.call(value);
352const toRawType = (value) => {
353 // extract "RawType" from strings like "[object RawType]"
354 return toTypeString(value).slice(8, -1);
355};
356const isPlainObject = (val) => toTypeString(val) === '[object Object]';
357const isIntegerKey = (key) => isString(key) &&
358 key !== 'NaN' &&
359 key[0] !== '-' &&
360 '' + parseInt(key, 10) === key;
361const isReservedProp = /*#__PURE__*/ makeMap(
362// the leading comma is intentional so empty string "" is also included
363',key,ref,ref_for,ref_key,' +
364 'onVnodeBeforeMount,onVnodeMounted,' +
365 'onVnodeBeforeUpdate,onVnodeUpdated,' +
366 'onVnodeBeforeUnmount,onVnodeUnmounted');
367const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
368const cacheStringFunction = (fn) => {
369 const cache = Object.create(null);
370 return ((str) => {
371 const hit = cache[str];
372 return hit || (cache[str] = fn(str));
373 });
374};
375const camelizeRE = /-(\w)/g;
376/**
377 * @private
378 */
379const camelize = cacheStringFunction((str) => {
380 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
381});
382const hyphenateRE = /\B([A-Z])/g;
383/**
384 * @private
385 */
386const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
387/**
388 * @private
389 */
390const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
391/**
392 * @private
393 */
394const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
395// compare whether a value has changed, accounting for NaN.
396const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
397const invokeArrayFns = (fns, arg) => {
398 for (let i = 0; i < fns.length; i++) {
399 fns[i](arg);
400 }
401};
402const def = (obj, key, value) => {
403 Object.defineProperty(obj, key, {
404 configurable: true,
405 enumerable: false,
406 value
407 });
408};
409const toNumber = (val) => {
410 const n = parseFloat(val);
411 return isNaN(n) ? val : n;
412};
413let _globalThis;
414const getGlobalThis = () => {
415 return (_globalThis ||
416 (_globalThis =
417 typeof globalThis !== 'undefined'
418 ? globalThis
419 : typeof self !== 'undefined'
420 ? self
421 : typeof window !== 'undefined'
422 ? window
423 : typeof global !== 'undefined'
424 ? global
425 : {}));
426};
427
428function warn(msg, ...args) {
429 console.warn(`[Vue warn] ${msg}`, ...args);
430}
431
432let activeEffectScope;
433class EffectScope {
434 constructor(detached = false) {
435 /**
436 * @internal
437 */
438 this.active = true;
439 /**
440 * @internal
441 */
442 this.effects = [];
443 /**
444 * @internal
445 */
446 this.cleanups = [];
447 if (!detached && activeEffectScope) {
448 this.parent = activeEffectScope;
449 this.index =
450 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
451 }
452 }
453 run(fn) {
454 if (this.active) {
455 const currentEffectScope = activeEffectScope;
456 try {
457 activeEffectScope = this;
458 return fn();
459 }
460 finally {
461 activeEffectScope = currentEffectScope;
462 }
463 }
464 else {
465 warn(`cannot run an inactive effect scope.`);
466 }
467 }
468 /**
469 * This should only be called on non-detached scopes
470 * @internal
471 */
472 on() {
473 activeEffectScope = this;
474 }
475 /**
476 * This should only be called on non-detached scopes
477 * @internal
478 */
479 off() {
480 activeEffectScope = this.parent;
481 }
482 stop(fromParent) {
483 if (this.active) {
484 let i, l;
485 for (i = 0, l = this.effects.length; i < l; i++) {
486 this.effects[i].stop();
487 }
488 for (i = 0, l = this.cleanups.length; i < l; i++) {
489 this.cleanups[i]();
490 }
491 if (this.scopes) {
492 for (i = 0, l = this.scopes.length; i < l; i++) {
493 this.scopes[i].stop(true);
494 }
495 }
496 // nested scope, dereference from parent to avoid memory leaks
497 if (this.parent && !fromParent) {
498 // optimized O(1) removal
499 const last = this.parent.scopes.pop();
500 if (last && last !== this) {
501 this.parent.scopes[this.index] = last;
502 last.index = this.index;
503 }
504 }
505 this.active = false;
506 }
507 }
508}
509function effectScope(detached) {
510 return new EffectScope(detached);
511}
512function recordEffectScope(effect, scope = activeEffectScope) {
513 if (scope && scope.active) {
514 scope.effects.push(effect);
515 }
516}
517function getCurrentScope() {
518 return activeEffectScope;
519}
520function onScopeDispose(fn) {
521 if (activeEffectScope) {
522 activeEffectScope.cleanups.push(fn);
523 }
524 else {
525 warn(`onScopeDispose() is called when there is no active effect scope` +
526 ` to be associated with.`);
527 }
528}
529
530const createDep = (effects) => {
531 const dep = new Set(effects);
532 dep.w = 0;
533 dep.n = 0;
534 return dep;
535};
536const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
537const newTracked = (dep) => (dep.n & trackOpBit) > 0;
538const initDepMarkers = ({ deps }) => {
539 if (deps.length) {
540 for (let i = 0; i < deps.length; i++) {
541 deps[i].w |= trackOpBit; // set was tracked
542 }
543 }
544};
545const finalizeDepMarkers = (effect) => {
546 const { deps } = effect;
547 if (deps.length) {
548 let ptr = 0;
549 for (let i = 0; i < deps.length; i++) {
550 const dep = deps[i];
551 if (wasTracked(dep) && !newTracked(dep)) {
552 dep.delete(effect);
553 }
554 else {
555 deps[ptr++] = dep;
556 }
557 // clear bits
558 dep.w &= ~trackOpBit;
559 dep.n &= ~trackOpBit;
560 }
561 deps.length = ptr;
562 }
563};
564
565const targetMap = new WeakMap();
566// The number of effects currently being tracked recursively.
567let effectTrackDepth = 0;
568let trackOpBit = 1;
569/**
570 * The bitwise track markers support at most 30 levels of recursion.
571 * This value is chosen to enable modern JS engines to use a SMI on all platforms.
572 * When recursion depth is greater, fall back to using a full cleanup.
573 */
574const maxMarkerBits = 30;
575let activeEffect;
576const ITERATE_KEY = Symbol('iterate' );
577const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
578class ReactiveEffect {
579 constructor(fn, scheduler = null, scope) {
580 this.fn = fn;
581 this.scheduler = scheduler;
582 this.active = true;
583 this.deps = [];
584 this.parent = undefined;
585 recordEffectScope(this, scope);
586 }
587 run() {
588 if (!this.active) {
589 return this.fn();
590 }
591 let parent = activeEffect;
592 let lastShouldTrack = shouldTrack;
593 while (parent) {
594 if (parent === this) {
595 return;
596 }
597 parent = parent.parent;
598 }
599 try {
600 this.parent = activeEffect;
601 activeEffect = this;
602 shouldTrack = true;
603 trackOpBit = 1 << ++effectTrackDepth;
604 if (effectTrackDepth <= maxMarkerBits) {
605 initDepMarkers(this);
606 }
607 else {
608 cleanupEffect(this);
609 }
610 return this.fn();
611 }
612 finally {
613 if (effectTrackDepth <= maxMarkerBits) {
614 finalizeDepMarkers(this);
615 }
616 trackOpBit = 1 << --effectTrackDepth;
617 activeEffect = this.parent;
618 shouldTrack = lastShouldTrack;
619 this.parent = undefined;
620 if (this.deferStop) {
621 this.stop();
622 }
623 }
624 }
625 stop() {
626 // stopped while running itself - defer the cleanup
627 if (activeEffect === this) {
628 this.deferStop = true;
629 }
630 else if (this.active) {
631 cleanupEffect(this);
632 if (this.onStop) {
633 this.onStop();
634 }
635 this.active = false;
636 }
637 }
638}
639function cleanupEffect(effect) {
640 const { deps } = effect;
641 if (deps.length) {
642 for (let i = 0; i < deps.length; i++) {
643 deps[i].delete(effect);
644 }
645 deps.length = 0;
646 }
647}
648function effect(fn, options) {
649 if (fn.effect) {
650 fn = fn.effect.fn;
651 }
652 const _effect = new ReactiveEffect(fn);
653 if (options) {
654 extend(_effect, options);
655 if (options.scope)
656 recordEffectScope(_effect, options.scope);
657 }
658 if (!options || !options.lazy) {
659 _effect.run();
660 }
661 const runner = _effect.run.bind(_effect);
662 runner.effect = _effect;
663 return runner;
664}
665function stop(runner) {
666 runner.effect.stop();
667}
668let shouldTrack = true;
669const trackStack = [];
670function pauseTracking() {
671 trackStack.push(shouldTrack);
672 shouldTrack = false;
673}
674function resetTracking() {
675 const last = trackStack.pop();
676 shouldTrack = last === undefined ? true : last;
677}
678function track(target, type, key) {
679 if (shouldTrack && activeEffect) {
680 let depsMap = targetMap.get(target);
681 if (!depsMap) {
682 targetMap.set(target, (depsMap = new Map()));
683 }
684 let dep = depsMap.get(key);
685 if (!dep) {
686 depsMap.set(key, (dep = createDep()));
687 }
688 const eventInfo = { effect: activeEffect, target, type, key }
689 ;
690 trackEffects(dep, eventInfo);
691 }
692}
693function trackEffects(dep, debuggerEventExtraInfo) {
694 let shouldTrack = false;
695 if (effectTrackDepth <= maxMarkerBits) {
696 if (!newTracked(dep)) {
697 dep.n |= trackOpBit; // set newly tracked
698 shouldTrack = !wasTracked(dep);
699 }
700 }
701 else {
702 // Full cleanup mode.
703 shouldTrack = !dep.has(activeEffect);
704 }
705 if (shouldTrack) {
706 dep.add(activeEffect);
707 activeEffect.deps.push(dep);
708 if (activeEffect.onTrack) {
709 activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo));
710 }
711 }
712}
713function trigger(target, type, key, newValue, oldValue, oldTarget) {
714 const depsMap = targetMap.get(target);
715 if (!depsMap) {
716 // never been tracked
717 return;
718 }
719 let deps = [];
720 if (type === "clear" /* CLEAR */) {
721 // collection being cleared
722 // trigger all effects for target
723 deps = [...depsMap.values()];
724 }
725 else if (key === 'length' && isArray(target)) {
726 depsMap.forEach((dep, key) => {
727 if (key === 'length' || key >= newValue) {
728 deps.push(dep);
729 }
730 });
731 }
732 else {
733 // schedule runs for SET | ADD | DELETE
734 if (key !== void 0) {
735 deps.push(depsMap.get(key));
736 }
737 // also run for iteration key on ADD | DELETE | Map.SET
738 switch (type) {
739 case "add" /* ADD */:
740 if (!isArray(target)) {
741 deps.push(depsMap.get(ITERATE_KEY));
742 if (isMap(target)) {
743 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
744 }
745 }
746 else if (isIntegerKey(key)) {
747 // new index added to array -> length changes
748 deps.push(depsMap.get('length'));
749 }
750 break;
751 case "delete" /* DELETE */:
752 if (!isArray(target)) {
753 deps.push(depsMap.get(ITERATE_KEY));
754 if (isMap(target)) {
755 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
756 }
757 }
758 break;
759 case "set" /* SET */:
760 if (isMap(target)) {
761 deps.push(depsMap.get(ITERATE_KEY));
762 }
763 break;
764 }
765 }
766 const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
767 ;
768 if (deps.length === 1) {
769 if (deps[0]) {
770 {
771 triggerEffects(deps[0], eventInfo);
772 }
773 }
774 }
775 else {
776 const effects = [];
777 for (const dep of deps) {
778 if (dep) {
779 effects.push(...dep);
780 }
781 }
782 {
783 triggerEffects(createDep(effects), eventInfo);
784 }
785 }
786}
787function triggerEffects(dep, debuggerEventExtraInfo) {
788 // spread into array for stabilization
789 const effects = isArray(dep) ? dep : [...dep];
790 for (const effect of effects) {
791 if (effect.computed) {
792 triggerEffect(effect, debuggerEventExtraInfo);
793 }
794 }
795 for (const effect of effects) {
796 if (!effect.computed) {
797 triggerEffect(effect, debuggerEventExtraInfo);
798 }
799 }
800}
801function triggerEffect(effect, debuggerEventExtraInfo) {
802 if (effect !== activeEffect || effect.allowRecurse) {
803 if (effect.onTrigger) {
804 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
805 }
806 if (effect.scheduler) {
807 effect.scheduler();
808 }
809 else {
810 effect.run();
811 }
812 }
813}
814
815const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
816const builtInSymbols = new Set(
817/*#__PURE__*/
818Object.getOwnPropertyNames(Symbol)
819 // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
820 // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
821 // function
822 .filter(key => key !== 'arguments' && key !== 'caller')
823 .map(key => Symbol[key])
824 .filter(isSymbol));
825const get = /*#__PURE__*/ createGetter();
826const shallowGet = /*#__PURE__*/ createGetter(false, true);
827const readonlyGet = /*#__PURE__*/ createGetter(true);
828const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
829const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
830function createArrayInstrumentations() {
831 const instrumentations = {};
832 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
833 instrumentations[key] = function (...args) {
834 const arr = toRaw(this);
835 for (let i = 0, l = this.length; i < l; i++) {
836 track(arr, "get" /* GET */, i + '');
837 }
838 // we run the method using the original args first (which may be reactive)
839 const res = arr[key](...args);
840 if (res === -1 || res === false) {
841 // if that didn't work, run it again using raw values.
842 return arr[key](...args.map(toRaw));
843 }
844 else {
845 return res;
846 }
847 };
848 });
849 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
850 instrumentations[key] = function (...args) {
851 pauseTracking();
852 const res = toRaw(this)[key].apply(this, args);
853 resetTracking();
854 return res;
855 };
856 });
857 return instrumentations;
858}
859function createGetter(isReadonly = false, shallow = false) {
860 return function get(target, key, receiver) {
861 if (key === "__v_isReactive" /* IS_REACTIVE */) {
862 return !isReadonly;
863 }
864 else if (key === "__v_isReadonly" /* IS_READONLY */) {
865 return isReadonly;
866 }
867 else if (key === "__v_isShallow" /* IS_SHALLOW */) {
868 return shallow;
869 }
870 else if (key === "__v_raw" /* RAW */ &&
871 receiver ===
872 (isReadonly
873 ? shallow
874 ? shallowReadonlyMap
875 : readonlyMap
876 : shallow
877 ? shallowReactiveMap
878 : reactiveMap).get(target)) {
879 return target;
880 }
881 const targetIsArray = isArray(target);
882 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
883 return Reflect.get(arrayInstrumentations, key, receiver);
884 }
885 const res = Reflect.get(target, key, receiver);
886 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
887 return res;
888 }
889 if (!isReadonly) {
890 track(target, "get" /* GET */, key);
891 }
892 if (shallow) {
893 return res;
894 }
895 if (isRef(res)) {
896 // ref unwrapping - skip unwrap for Array + integer key.
897 return targetIsArray && isIntegerKey(key) ? res : res.value;
898 }
899 if (isObject(res)) {
900 // Convert returned value into a proxy as well. we do the isObject check
901 // here to avoid invalid value warning. Also need to lazy access readonly
902 // and reactive here to avoid circular dependency.
903 return isReadonly ? readonly(res) : reactive(res);
904 }
905 return res;
906 };
907}
908const set = /*#__PURE__*/ createSetter();
909const shallowSet = /*#__PURE__*/ createSetter(true);
910function createSetter(shallow = false) {
911 return function set(target, key, value, receiver) {
912 let oldValue = target[key];
913 if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
914 return false;
915 }
916 if (!shallow && !isReadonly(value)) {
917 if (!isShallow(value)) {
918 value = toRaw(value);
919 oldValue = toRaw(oldValue);
920 }
921 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
922 oldValue.value = value;
923 return true;
924 }
925 }
926 const hadKey = isArray(target) && isIntegerKey(key)
927 ? Number(key) < target.length
928 : hasOwn(target, key);
929 const result = Reflect.set(target, key, value, receiver);
930 // don't trigger if target is something up in the prototype chain of original
931 if (target === toRaw(receiver)) {
932 if (!hadKey) {
933 trigger(target, "add" /* ADD */, key, value);
934 }
935 else if (hasChanged(value, oldValue)) {
936 trigger(target, "set" /* SET */, key, value, oldValue);
937 }
938 }
939 return result;
940 };
941}
942function deleteProperty(target, key) {
943 const hadKey = hasOwn(target, key);
944 const oldValue = target[key];
945 const result = Reflect.deleteProperty(target, key);
946 if (result && hadKey) {
947 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
948 }
949 return result;
950}
951function has(target, key) {
952 const result = Reflect.has(target, key);
953 if (!isSymbol(key) || !builtInSymbols.has(key)) {
954 track(target, "has" /* HAS */, key);
955 }
956 return result;
957}
958function ownKeys(target) {
959 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
960 return Reflect.ownKeys(target);
961}
962const mutableHandlers = {
963 get,
964 set,
965 deleteProperty,
966 has,
967 ownKeys
968};
969const readonlyHandlers = {
970 get: readonlyGet,
971 set(target, key) {
972 {
973 warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
974 }
975 return true;
976 },
977 deleteProperty(target, key) {
978 {
979 warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
980 }
981 return true;
982 }
983};
984const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
985 get: shallowGet,
986 set: shallowSet
987});
988// Props handlers are special in the sense that it should not unwrap top-level
989// refs (in order to allow refs to be explicitly passed down), but should
990// retain the reactivity of the normal readonly object.
991const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
992 get: shallowReadonlyGet
993});
994
995const toShallow = (value) => value;
996const getProto = (v) => Reflect.getPrototypeOf(v);
997function get$1(target, key, isReadonly = false, isShallow = false) {
998 // #1772: readonly(reactive(Map)) should return readonly + reactive version
999 // of the value
1000 target = target["__v_raw" /* RAW */];
1001 const rawTarget = toRaw(target);
1002 const rawKey = toRaw(key);
1003 if (!isReadonly) {
1004 if (key !== rawKey) {
1005 track(rawTarget, "get" /* GET */, key);
1006 }
1007 track(rawTarget, "get" /* GET */, rawKey);
1008 }
1009 const { has } = getProto(rawTarget);
1010 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1011 if (has.call(rawTarget, key)) {
1012 return wrap(target.get(key));
1013 }
1014 else if (has.call(rawTarget, rawKey)) {
1015 return wrap(target.get(rawKey));
1016 }
1017 else if (target !== rawTarget) {
1018 // #3602 readonly(reactive(Map))
1019 // ensure that the nested reactive `Map` can do tracking for itself
1020 target.get(key);
1021 }
1022}
1023function has$1(key, isReadonly = false) {
1024 const target = this["__v_raw" /* RAW */];
1025 const rawTarget = toRaw(target);
1026 const rawKey = toRaw(key);
1027 if (!isReadonly) {
1028 if (key !== rawKey) {
1029 track(rawTarget, "has" /* HAS */, key);
1030 }
1031 track(rawTarget, "has" /* HAS */, rawKey);
1032 }
1033 return key === rawKey
1034 ? target.has(key)
1035 : target.has(key) || target.has(rawKey);
1036}
1037function size(target, isReadonly = false) {
1038 target = target["__v_raw" /* RAW */];
1039 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
1040 return Reflect.get(target, 'size', target);
1041}
1042function add(value) {
1043 value = toRaw(value);
1044 const target = toRaw(this);
1045 const proto = getProto(target);
1046 const hadKey = proto.has.call(target, value);
1047 if (!hadKey) {
1048 target.add(value);
1049 trigger(target, "add" /* ADD */, value, value);
1050 }
1051 return this;
1052}
1053function set$1(key, value) {
1054 value = toRaw(value);
1055 const target = toRaw(this);
1056 const { has, get } = getProto(target);
1057 let hadKey = has.call(target, key);
1058 if (!hadKey) {
1059 key = toRaw(key);
1060 hadKey = has.call(target, key);
1061 }
1062 else {
1063 checkIdentityKeys(target, has, key);
1064 }
1065 const oldValue = get.call(target, key);
1066 target.set(key, value);
1067 if (!hadKey) {
1068 trigger(target, "add" /* ADD */, key, value);
1069 }
1070 else if (hasChanged(value, oldValue)) {
1071 trigger(target, "set" /* SET */, key, value, oldValue);
1072 }
1073 return this;
1074}
1075function deleteEntry(key) {
1076 const target = toRaw(this);
1077 const { has, get } = getProto(target);
1078 let hadKey = has.call(target, key);
1079 if (!hadKey) {
1080 key = toRaw(key);
1081 hadKey = has.call(target, key);
1082 }
1083 else {
1084 checkIdentityKeys(target, has, key);
1085 }
1086 const oldValue = get ? get.call(target, key) : undefined;
1087 // forward the operation before queueing reactions
1088 const result = target.delete(key);
1089 if (hadKey) {
1090 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
1091 }
1092 return result;
1093}
1094function clear() {
1095 const target = toRaw(this);
1096 const hadItems = target.size !== 0;
1097 const oldTarget = isMap(target)
1098 ? new Map(target)
1099 : new Set(target)
1100 ;
1101 // forward the operation before queueing reactions
1102 const result = target.clear();
1103 if (hadItems) {
1104 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
1105 }
1106 return result;
1107}
1108function createForEach(isReadonly, isShallow) {
1109 return function forEach(callback, thisArg) {
1110 const observed = this;
1111 const target = observed["__v_raw" /* RAW */];
1112 const rawTarget = toRaw(target);
1113 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1114 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
1115 return target.forEach((value, key) => {
1116 // important: make sure the callback is
1117 // 1. invoked with the reactive map as `this` and 3rd arg
1118 // 2. the value received should be a corresponding reactive/readonly.
1119 return callback.call(thisArg, wrap(value), wrap(key), observed);
1120 });
1121 };
1122}
1123function createIterableMethod(method, isReadonly, isShallow) {
1124 return function (...args) {
1125 const target = this["__v_raw" /* RAW */];
1126 const rawTarget = toRaw(target);
1127 const targetIsMap = isMap(rawTarget);
1128 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
1129 const isKeyOnly = method === 'keys' && targetIsMap;
1130 const innerIterator = target[method](...args);
1131 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1132 !isReadonly &&
1133 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
1134 // return a wrapped iterator which returns observed versions of the
1135 // values emitted from the real iterator
1136 return {
1137 // iterator protocol
1138 next() {
1139 const { value, done } = innerIterator.next();
1140 return done
1141 ? { value, done }
1142 : {
1143 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1144 done
1145 };
1146 },
1147 // iterable protocol
1148 [Symbol.iterator]() {
1149 return this;
1150 }
1151 };
1152 };
1153}
1154function createReadonlyMethod(type) {
1155 return function (...args) {
1156 {
1157 const key = args[0] ? `on key "${args[0]}" ` : ``;
1158 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
1159 }
1160 return type === "delete" /* DELETE */ ? false : this;
1161 };
1162}
1163function createInstrumentations() {
1164 const mutableInstrumentations = {
1165 get(key) {
1166 return get$1(this, key);
1167 },
1168 get size() {
1169 return size(this);
1170 },
1171 has: has$1,
1172 add,
1173 set: set$1,
1174 delete: deleteEntry,
1175 clear,
1176 forEach: createForEach(false, false)
1177 };
1178 const shallowInstrumentations = {
1179 get(key) {
1180 return get$1(this, key, false, true);
1181 },
1182 get size() {
1183 return size(this);
1184 },
1185 has: has$1,
1186 add,
1187 set: set$1,
1188 delete: deleteEntry,
1189 clear,
1190 forEach: createForEach(false, true)
1191 };
1192 const readonlyInstrumentations = {
1193 get(key) {
1194 return get$1(this, key, true);
1195 },
1196 get size() {
1197 return size(this, true);
1198 },
1199 has(key) {
1200 return has$1.call(this, key, true);
1201 },
1202 add: createReadonlyMethod("add" /* ADD */),
1203 set: createReadonlyMethod("set" /* SET */),
1204 delete: createReadonlyMethod("delete" /* DELETE */),
1205 clear: createReadonlyMethod("clear" /* CLEAR */),
1206 forEach: createForEach(true, false)
1207 };
1208 const shallowReadonlyInstrumentations = {
1209 get(key) {
1210 return get$1(this, key, true, true);
1211 },
1212 get size() {
1213 return size(this, true);
1214 },
1215 has(key) {
1216 return has$1.call(this, key, true);
1217 },
1218 add: createReadonlyMethod("add" /* ADD */),
1219 set: createReadonlyMethod("set" /* SET */),
1220 delete: createReadonlyMethod("delete" /* DELETE */),
1221 clear: createReadonlyMethod("clear" /* CLEAR */),
1222 forEach: createForEach(true, true)
1223 };
1224 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
1225 iteratorMethods.forEach(method => {
1226 mutableInstrumentations[method] = createIterableMethod(method, false, false);
1227 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
1228 shallowInstrumentations[method] = createIterableMethod(method, false, true);
1229 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
1230 });
1231 return [
1232 mutableInstrumentations,
1233 readonlyInstrumentations,
1234 shallowInstrumentations,
1235 shallowReadonlyInstrumentations
1236 ];
1237}
1238const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
1239function createInstrumentationGetter(isReadonly, shallow) {
1240 const instrumentations = shallow
1241 ? isReadonly
1242 ? shallowReadonlyInstrumentations
1243 : shallowInstrumentations
1244 : isReadonly
1245 ? readonlyInstrumentations
1246 : mutableInstrumentations;
1247 return (target, key, receiver) => {
1248 if (key === "__v_isReactive" /* IS_REACTIVE */) {
1249 return !isReadonly;
1250 }
1251 else if (key === "__v_isReadonly" /* IS_READONLY */) {
1252 return isReadonly;
1253 }
1254 else if (key === "__v_raw" /* RAW */) {
1255 return target;
1256 }
1257 return Reflect.get(hasOwn(instrumentations, key) && key in target
1258 ? instrumentations
1259 : target, key, receiver);
1260 };
1261}
1262const mutableCollectionHandlers = {
1263 get: /*#__PURE__*/ createInstrumentationGetter(false, false)
1264};
1265const shallowCollectionHandlers = {
1266 get: /*#__PURE__*/ createInstrumentationGetter(false, true)
1267};
1268const readonlyCollectionHandlers = {
1269 get: /*#__PURE__*/ createInstrumentationGetter(true, false)
1270};
1271const shallowReadonlyCollectionHandlers = {
1272 get: /*#__PURE__*/ createInstrumentationGetter(true, true)
1273};
1274function checkIdentityKeys(target, has, key) {
1275 const rawKey = toRaw(key);
1276 if (rawKey !== key && has.call(target, rawKey)) {
1277 const type = toRawType(target);
1278 console.warn(`Reactive ${type} contains both the raw and reactive ` +
1279 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
1280 `which can lead to inconsistencies. ` +
1281 `Avoid differentiating between the raw and reactive versions ` +
1282 `of an object and only use the reactive version if possible.`);
1283 }
1284}
1285
1286const reactiveMap = new WeakMap();
1287const shallowReactiveMap = new WeakMap();
1288const readonlyMap = new WeakMap();
1289const shallowReadonlyMap = new WeakMap();
1290function targetTypeMap(rawType) {
1291 switch (rawType) {
1292 case 'Object':
1293 case 'Array':
1294 return 1 /* COMMON */;
1295 case 'Map':
1296 case 'Set':
1297 case 'WeakMap':
1298 case 'WeakSet':
1299 return 2 /* COLLECTION */;
1300 default:
1301 return 0 /* INVALID */;
1302 }
1303}
1304function getTargetType(value) {
1305 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1306 ? 0 /* INVALID */
1307 : targetTypeMap(toRawType(value));
1308}
1309function reactive(target) {
1310 // if trying to observe a readonly proxy, return the readonly version.
1311 if (isReadonly(target)) {
1312 return target;
1313 }
1314 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1315}
1316/**
1317 * Return a shallowly-reactive copy of the original object, where only the root
1318 * level properties are reactive. It also does not auto-unwrap refs (even at the
1319 * root level).
1320 */
1321function shallowReactive(target) {
1322 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1323}
1324/**
1325 * Creates a readonly copy of the original object. Note the returned copy is not
1326 * made reactive, but `readonly` can be called on an already reactive object.
1327 */
1328function readonly(target) {
1329 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1330}
1331/**
1332 * Returns a reactive-copy of the original object, where only the root level
1333 * properties are readonly, and does NOT unwrap refs nor recursively convert
1334 * returned properties.
1335 * This is used for creating the props proxy object for stateful components.
1336 */
1337function shallowReadonly(target) {
1338 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1339}
1340function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1341 if (!isObject(target)) {
1342 {
1343 console.warn(`value cannot be made reactive: ${String(target)}`);
1344 }
1345 return target;
1346 }
1347 // target is already a Proxy, return it.
1348 // exception: calling readonly() on a reactive object
1349 if (target["__v_raw" /* RAW */] &&
1350 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1351 return target;
1352 }
1353 // target already has corresponding Proxy
1354 const existingProxy = proxyMap.get(target);
1355 if (existingProxy) {
1356 return existingProxy;
1357 }
1358 // only specific value types can be observed.
1359 const targetType = getTargetType(target);
1360 if (targetType === 0 /* INVALID */) {
1361 return target;
1362 }
1363 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1364 proxyMap.set(target, proxy);
1365 return proxy;
1366}
1367function isReactive(value) {
1368 if (isReadonly(value)) {
1369 return isReactive(value["__v_raw" /* RAW */]);
1370 }
1371 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1372}
1373function isReadonly(value) {
1374 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1375}
1376function isShallow(value) {
1377 return !!(value && value["__v_isShallow" /* IS_SHALLOW */]);
1378}
1379function isProxy(value) {
1380 return isReactive(value) || isReadonly(value);
1381}
1382function toRaw(observed) {
1383 const raw = observed && observed["__v_raw" /* RAW */];
1384 return raw ? toRaw(raw) : observed;
1385}
1386function markRaw(value) {
1387 def(value, "__v_skip" /* SKIP */, true);
1388 return value;
1389}
1390const toReactive = (value) => isObject(value) ? reactive(value) : value;
1391const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1392
1393function trackRefValue(ref) {
1394 if (shouldTrack && activeEffect) {
1395 ref = toRaw(ref);
1396 {
1397 trackEffects(ref.dep || (ref.dep = createDep()), {
1398 target: ref,
1399 type: "get" /* GET */,
1400 key: 'value'
1401 });
1402 }
1403 }
1404}
1405function triggerRefValue(ref, newVal) {
1406 ref = toRaw(ref);
1407 if (ref.dep) {
1408 {
1409 triggerEffects(ref.dep, {
1410 target: ref,
1411 type: "set" /* SET */,
1412 key: 'value',
1413 newValue: newVal
1414 });
1415 }
1416 }
1417}
1418function isRef(r) {
1419 return !!(r && r.__v_isRef === true);
1420}
1421function ref(value) {
1422 return createRef(value, false);
1423}
1424function shallowRef(value) {
1425 return createRef(value, true);
1426}
1427function createRef(rawValue, shallow) {
1428 if (isRef(rawValue)) {
1429 return rawValue;
1430 }
1431 return new RefImpl(rawValue, shallow);
1432}
1433class RefImpl {
1434 constructor(value, __v_isShallow) {
1435 this.__v_isShallow = __v_isShallow;
1436 this.dep = undefined;
1437 this.__v_isRef = true;
1438 this._rawValue = __v_isShallow ? value : toRaw(value);
1439 this._value = __v_isShallow ? value : toReactive(value);
1440 }
1441 get value() {
1442 trackRefValue(this);
1443 return this._value;
1444 }
1445 set value(newVal) {
1446 newVal = this.__v_isShallow ? newVal : toRaw(newVal);
1447 if (hasChanged(newVal, this._rawValue)) {
1448 this._rawValue = newVal;
1449 this._value = this.__v_isShallow ? newVal : toReactive(newVal);
1450 triggerRefValue(this, newVal);
1451 }
1452 }
1453}
1454function triggerRef(ref) {
1455 triggerRefValue(ref, ref.value );
1456}
1457function unref(ref) {
1458 return isRef(ref) ? ref.value : ref;
1459}
1460const shallowUnwrapHandlers = {
1461 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1462 set: (target, key, value, receiver) => {
1463 const oldValue = target[key];
1464 if (isRef(oldValue) && !isRef(value)) {
1465 oldValue.value = value;
1466 return true;
1467 }
1468 else {
1469 return Reflect.set(target, key, value, receiver);
1470 }
1471 }
1472};
1473function proxyRefs(objectWithRefs) {
1474 return isReactive(objectWithRefs)
1475 ? objectWithRefs
1476 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1477}
1478class CustomRefImpl {
1479 constructor(factory) {
1480 this.dep = undefined;
1481 this.__v_isRef = true;
1482 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
1483 this._get = get;
1484 this._set = set;
1485 }
1486 get value() {
1487 return this._get();
1488 }
1489 set value(newVal) {
1490 this._set(newVal);
1491 }
1492}
1493function customRef(factory) {
1494 return new CustomRefImpl(factory);
1495}
1496function toRefs(object) {
1497 if (!isProxy(object)) {
1498 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1499 }
1500 const ret = isArray(object) ? new Array(object.length) : {};
1501 for (const key in object) {
1502 ret[key] = toRef(object, key);
1503 }
1504 return ret;
1505}
1506class ObjectRefImpl {
1507 constructor(_object, _key, _defaultValue) {
1508 this._object = _object;
1509 this._key = _key;
1510 this._defaultValue = _defaultValue;
1511 this.__v_isRef = true;
1512 }
1513 get value() {
1514 const val = this._object[this._key];
1515 return val === undefined ? this._defaultValue : val;
1516 }
1517 set value(newVal) {
1518 this._object[this._key] = newVal;
1519 }
1520}
1521function toRef(object, key, defaultValue) {
1522 const val = object[key];
1523 return isRef(val)
1524 ? val
1525 : new ObjectRefImpl(object, key, defaultValue);
1526}
1527
1528class ComputedRefImpl {
1529 constructor(getter, _setter, isReadonly, isSSR) {
1530 this._setter = _setter;
1531 this.dep = undefined;
1532 this.__v_isRef = true;
1533 this._dirty = true;
1534 this.effect = new ReactiveEffect(getter, () => {
1535 if (!this._dirty) {
1536 this._dirty = true;
1537 triggerRefValue(this);
1538 }
1539 });
1540 this.effect.computed = this;
1541 this.effect.active = this._cacheable = !isSSR;
1542 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1543 }
1544 get value() {
1545 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1546 const self = toRaw(this);
1547 trackRefValue(self);
1548 if (self._dirty || !self._cacheable) {
1549 self._dirty = false;
1550 self._value = self.effect.run();
1551 }
1552 return self._value;
1553 }
1554 set value(newValue) {
1555 this._setter(newValue);
1556 }
1557}
1558function computed(getterOrOptions, debugOptions, isSSR = false) {
1559 let getter;
1560 let setter;
1561 const onlyGetter = isFunction(getterOrOptions);
1562 if (onlyGetter) {
1563 getter = getterOrOptions;
1564 setter = () => {
1565 console.warn('Write operation failed: computed value is readonly');
1566 }
1567 ;
1568 }
1569 else {
1570 getter = getterOrOptions.get;
1571 setter = getterOrOptions.set;
1572 }
1573 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1574 if (debugOptions && !isSSR) {
1575 cRef.effect.onTrack = debugOptions.onTrack;
1576 cRef.effect.onTrigger = debugOptions.onTrigger;
1577 }
1578 return cRef;
1579}
1580
1581const stack = [];
1582function pushWarningContext(vnode) {
1583 stack.push(vnode);
1584}
1585function popWarningContext() {
1586 stack.pop();
1587}
1588function warn$1(msg, ...args) {
1589 // avoid props formatting or warn handler tracking deps that might be mutated
1590 // during patch, leading to infinite recursion.
1591 pauseTracking();
1592 const instance = stack.length ? stack[stack.length - 1].component : null;
1593 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1594 const trace = getComponentTrace();
1595 if (appWarnHandler) {
1596 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1597 msg + args.join(''),
1598 instance && instance.proxy,
1599 trace
1600 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1601 .join('\n'),
1602 trace
1603 ]);
1604 }
1605 else {
1606 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1607 /* istanbul ignore if */
1608 if (trace.length &&
1609 // avoid spamming console during tests
1610 !false) {
1611 warnArgs.push(`\n`, ...formatTrace(trace));
1612 }
1613 console.warn(...warnArgs);
1614 }
1615 resetTracking();
1616}
1617function getComponentTrace() {
1618 let currentVNode = stack[stack.length - 1];
1619 if (!currentVNode) {
1620 return [];
1621 }
1622 // we can't just use the stack because it will be incomplete during updates
1623 // that did not start from the root. Re-construct the parent chain using
1624 // instance parent pointers.
1625 const normalizedStack = [];
1626 while (currentVNode) {
1627 const last = normalizedStack[0];
1628 if (last && last.vnode === currentVNode) {
1629 last.recurseCount++;
1630 }
1631 else {
1632 normalizedStack.push({
1633 vnode: currentVNode,
1634 recurseCount: 0
1635 });
1636 }
1637 const parentInstance = currentVNode.component && currentVNode.component.parent;
1638 currentVNode = parentInstance && parentInstance.vnode;
1639 }
1640 return normalizedStack;
1641}
1642/* istanbul ignore next */
1643function formatTrace(trace) {
1644 const logs = [];
1645 trace.forEach((entry, i) => {
1646 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1647 });
1648 return logs;
1649}
1650function formatTraceEntry({ vnode, recurseCount }) {
1651 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1652 const isRoot = vnode.component ? vnode.component.parent == null : false;
1653 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1654 const close = `>` + postfix;
1655 return vnode.props
1656 ? [open, ...formatProps(vnode.props), close]
1657 : [open + close];
1658}
1659/* istanbul ignore next */
1660function formatProps(props) {
1661 const res = [];
1662 const keys = Object.keys(props);
1663 keys.slice(0, 3).forEach(key => {
1664 res.push(...formatProp(key, props[key]));
1665 });
1666 if (keys.length > 3) {
1667 res.push(` ...`);
1668 }
1669 return res;
1670}
1671/* istanbul ignore next */
1672function formatProp(key, value, raw) {
1673 if (isString(value)) {
1674 value = JSON.stringify(value);
1675 return raw ? value : [`${key}=${value}`];
1676 }
1677 else if (typeof value === 'number' ||
1678 typeof value === 'boolean' ||
1679 value == null) {
1680 return raw ? value : [`${key}=${value}`];
1681 }
1682 else if (isRef(value)) {
1683 value = formatProp(key, toRaw(value.value), true);
1684 return raw ? value : [`${key}=Ref<`, value, `>`];
1685 }
1686 else if (isFunction(value)) {
1687 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1688 }
1689 else {
1690 value = toRaw(value);
1691 return raw ? value : [`${key}=`, value];
1692 }
1693}
1694
1695const ErrorTypeStrings = {
1696 ["sp" /* SERVER_PREFETCH */]: 'serverPrefetch hook',
1697 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1698 ["c" /* CREATED */]: 'created hook',
1699 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1700 ["m" /* MOUNTED */]: 'mounted hook',
1701 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1702 ["u" /* UPDATED */]: 'updated',
1703 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1704 ["um" /* UNMOUNTED */]: 'unmounted hook',
1705 ["a" /* ACTIVATED */]: 'activated hook',
1706 ["da" /* DEACTIVATED */]: 'deactivated hook',
1707 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1708 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1709 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1710 [0 /* SETUP_FUNCTION */]: 'setup function',
1711 [1 /* RENDER_FUNCTION */]: 'render function',
1712 [2 /* WATCH_GETTER */]: 'watcher getter',
1713 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1714 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1715 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1716 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1717 [7 /* VNODE_HOOK */]: 'vnode hook',
1718 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1719 [9 /* TRANSITION_HOOK */]: 'transition hook',
1720 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1721 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1722 [12 /* FUNCTION_REF */]: 'ref function',
1723 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1724 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1725 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
1726};
1727function callWithErrorHandling(fn, instance, type, args) {
1728 let res;
1729 try {
1730 res = args ? fn(...args) : fn();
1731 }
1732 catch (err) {
1733 handleError(err, instance, type);
1734 }
1735 return res;
1736}
1737function callWithAsyncErrorHandling(fn, instance, type, args) {
1738 if (isFunction(fn)) {
1739 const res = callWithErrorHandling(fn, instance, type, args);
1740 if (res && isPromise(res)) {
1741 res.catch(err => {
1742 handleError(err, instance, type);
1743 });
1744 }
1745 return res;
1746 }
1747 const values = [];
1748 for (let i = 0; i < fn.length; i++) {
1749 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1750 }
1751 return values;
1752}
1753function handleError(err, instance, type, throwInDev = true) {
1754 const contextVNode = instance ? instance.vnode : null;
1755 if (instance) {
1756 let cur = instance.parent;
1757 // the exposed instance is the render proxy to keep it consistent with 2.x
1758 const exposedInstance = instance.proxy;
1759 // in production the hook receives only the error code
1760 const errorInfo = ErrorTypeStrings[type] ;
1761 while (cur) {
1762 const errorCapturedHooks = cur.ec;
1763 if (errorCapturedHooks) {
1764 for (let i = 0; i < errorCapturedHooks.length; i++) {
1765 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1766 return;
1767 }
1768 }
1769 }
1770 cur = cur.parent;
1771 }
1772 // app-level handling
1773 const appErrorHandler = instance.appContext.config.errorHandler;
1774 if (appErrorHandler) {
1775 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1776 return;
1777 }
1778 }
1779 logError(err, type, contextVNode, throwInDev);
1780}
1781function logError(err, type, contextVNode, throwInDev = true) {
1782 {
1783 const info = ErrorTypeStrings[type];
1784 if (contextVNode) {
1785 pushWarningContext(contextVNode);
1786 }
1787 warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1788 if (contextVNode) {
1789 popWarningContext();
1790 }
1791 // crash in dev by default so it's more noticeable
1792 if (throwInDev) {
1793 throw err;
1794 }
1795 else {
1796 console.error(err);
1797 }
1798 }
1799}
1800
1801let isFlushing = false;
1802let isFlushPending = false;
1803const queue = [];
1804let flushIndex = 0;
1805const pendingPreFlushCbs = [];
1806let activePreFlushCbs = null;
1807let preFlushIndex = 0;
1808const pendingPostFlushCbs = [];
1809let activePostFlushCbs = null;
1810let postFlushIndex = 0;
1811const resolvedPromise = /*#__PURE__*/ Promise.resolve();
1812let currentFlushPromise = null;
1813let currentPreFlushParentJob = null;
1814const RECURSION_LIMIT = 100;
1815function nextTick(fn) {
1816 const p = currentFlushPromise || resolvedPromise;
1817 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1818}
1819// #2768
1820// Use binary-search to find a suitable position in the queue,
1821// so that the queue maintains the increasing order of job's id,
1822// which can prevent the job from being skipped and also can avoid repeated patching.
1823function findInsertionIndex(id) {
1824 // the start index should be `flushIndex + 1`
1825 let start = flushIndex + 1;
1826 let end = queue.length;
1827 while (start < end) {
1828 const middle = (start + end) >>> 1;
1829 const middleJobId = getId(queue[middle]);
1830 middleJobId < id ? (start = middle + 1) : (end = middle);
1831 }
1832 return start;
1833}
1834function queueJob(job) {
1835 // the dedupe search uses the startIndex argument of Array.includes()
1836 // by default the search index includes the current job that is being run
1837 // so it cannot recursively trigger itself again.
1838 // if the job is a watch() callback, the search will start with a +1 index to
1839 // allow it recursively trigger itself - it is the user's responsibility to
1840 // ensure it doesn't end up in an infinite loop.
1841 if ((!queue.length ||
1842 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1843 job !== currentPreFlushParentJob) {
1844 if (job.id == null) {
1845 queue.push(job);
1846 }
1847 else {
1848 queue.splice(findInsertionIndex(job.id), 0, job);
1849 }
1850 queueFlush();
1851 }
1852}
1853function queueFlush() {
1854 if (!isFlushing && !isFlushPending) {
1855 isFlushPending = true;
1856 currentFlushPromise = resolvedPromise.then(flushJobs);
1857 }
1858}
1859function invalidateJob(job) {
1860 const i = queue.indexOf(job);
1861 if (i > flushIndex) {
1862 queue.splice(i, 1);
1863 }
1864}
1865function queueCb(cb, activeQueue, pendingQueue, index) {
1866 if (!isArray(cb)) {
1867 if (!activeQueue ||
1868 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1869 pendingQueue.push(cb);
1870 }
1871 }
1872 else {
1873 // if cb is an array, it is a component lifecycle hook which can only be
1874 // triggered by a job, which is already deduped in the main queue, so
1875 // we can skip duplicate check here to improve perf
1876 pendingQueue.push(...cb);
1877 }
1878 queueFlush();
1879}
1880function queuePreFlushCb(cb) {
1881 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1882}
1883function queuePostFlushCb(cb) {
1884 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1885}
1886function flushPreFlushCbs(seen, parentJob = null) {
1887 if (pendingPreFlushCbs.length) {
1888 currentPreFlushParentJob = parentJob;
1889 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1890 pendingPreFlushCbs.length = 0;
1891 {
1892 seen = seen || new Map();
1893 }
1894 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1895 if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) {
1896 continue;
1897 }
1898 activePreFlushCbs[preFlushIndex]();
1899 }
1900 activePreFlushCbs = null;
1901 preFlushIndex = 0;
1902 currentPreFlushParentJob = null;
1903 // recursively flush until it drains
1904 flushPreFlushCbs(seen, parentJob);
1905 }
1906}
1907function flushPostFlushCbs(seen) {
1908 // flush any pre cbs queued during the flush (e.g. pre watchers)
1909 flushPreFlushCbs();
1910 if (pendingPostFlushCbs.length) {
1911 const deduped = [...new Set(pendingPostFlushCbs)];
1912 pendingPostFlushCbs.length = 0;
1913 // #1947 already has active queue, nested flushPostFlushCbs call
1914 if (activePostFlushCbs) {
1915 activePostFlushCbs.push(...deduped);
1916 return;
1917 }
1918 activePostFlushCbs = deduped;
1919 {
1920 seen = seen || new Map();
1921 }
1922 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1923 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1924 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
1925 continue;
1926 }
1927 activePostFlushCbs[postFlushIndex]();
1928 }
1929 activePostFlushCbs = null;
1930 postFlushIndex = 0;
1931 }
1932}
1933const getId = (job) => job.id == null ? Infinity : job.id;
1934function flushJobs(seen) {
1935 isFlushPending = false;
1936 isFlushing = true;
1937 {
1938 seen = seen || new Map();
1939 }
1940 flushPreFlushCbs(seen);
1941 // Sort queue before flush.
1942 // This ensures that:
1943 // 1. Components are updated from parent to child. (because parent is always
1944 // created before the child so its render effect will have smaller
1945 // priority number)
1946 // 2. If a component is unmounted during a parent component's update,
1947 // its update can be skipped.
1948 queue.sort((a, b) => getId(a) - getId(b));
1949 // conditional usage of checkRecursiveUpdate must be determined out of
1950 // try ... catch block since Rollup by default de-optimizes treeshaking
1951 // inside try-catch. This can leave all warning code unshaked. Although
1952 // they would get eventually shaken by a minifier like terser, some minifiers
1953 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610)
1954 const check = (job) => checkRecursiveUpdates(seen, job)
1955 ;
1956 try {
1957 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1958 const job = queue[flushIndex];
1959 if (job && job.active !== false) {
1960 if (true && check(job)) {
1961 continue;
1962 }
1963 // console.log(`running:`, job.id)
1964 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1965 }
1966 }
1967 }
1968 finally {
1969 flushIndex = 0;
1970 queue.length = 0;
1971 flushPostFlushCbs(seen);
1972 isFlushing = false;
1973 currentFlushPromise = null;
1974 // some postFlushCb queued jobs!
1975 // keep flushing until it drains.
1976 if (queue.length ||
1977 pendingPreFlushCbs.length ||
1978 pendingPostFlushCbs.length) {
1979 flushJobs(seen);
1980 }
1981 }
1982}
1983function checkRecursiveUpdates(seen, fn) {
1984 if (!seen.has(fn)) {
1985 seen.set(fn, 1);
1986 }
1987 else {
1988 const count = seen.get(fn);
1989 if (count > RECURSION_LIMIT) {
1990 const instance = fn.ownerInstance;
1991 const componentName = instance && getComponentName(instance.type);
1992 warn$1(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
1993 `This means you have a reactive effect that is mutating its own ` +
1994 `dependencies and thus recursively triggering itself. Possible sources ` +
1995 `include component template, render function, updated hook or ` +
1996 `watcher source function.`);
1997 return true;
1998 }
1999 else {
2000 seen.set(fn, count + 1);
2001 }
2002 }
2003}
2004
2005/* eslint-disable no-restricted-globals */
2006let isHmrUpdating = false;
2007const hmrDirtyComponents = new Set();
2008// Expose the HMR runtime on the global object
2009// This makes it entirely tree-shakable without polluting the exports and makes
2010// it easier to be used in toolings like vue-loader
2011// Note: for a component to be eligible for HMR it also needs the __hmrId option
2012// to be set so that its instances can be registered / removed.
2013{
2014 getGlobalThis().__VUE_HMR_RUNTIME__ = {
2015 createRecord: tryWrap(createRecord),
2016 rerender: tryWrap(rerender),
2017 reload: tryWrap(reload)
2018 };
2019}
2020const map = new Map();
2021function registerHMR(instance) {
2022 const id = instance.type.__hmrId;
2023 let record = map.get(id);
2024 if (!record) {
2025 createRecord(id, instance.type);
2026 record = map.get(id);
2027 }
2028 record.instances.add(instance);
2029}
2030function unregisterHMR(instance) {
2031 map.get(instance.type.__hmrId).instances.delete(instance);
2032}
2033function createRecord(id, initialDef) {
2034 if (map.has(id)) {
2035 return false;
2036 }
2037 map.set(id, {
2038 initialDef: normalizeClassComponent(initialDef),
2039 instances: new Set()
2040 });
2041 return true;
2042}
2043function normalizeClassComponent(component) {
2044 return isClassComponent(component) ? component.__vccOpts : component;
2045}
2046function rerender(id, newRender) {
2047 const record = map.get(id);
2048 if (!record) {
2049 return;
2050 }
2051 // update initial record (for not-yet-rendered component)
2052 record.initialDef.render = newRender;
2053 [...record.instances].forEach(instance => {
2054 if (newRender) {
2055 instance.render = newRender;
2056 normalizeClassComponent(instance.type).render = newRender;
2057 }
2058 instance.renderCache = [];
2059 // this flag forces child components with slot content to update
2060 isHmrUpdating = true;
2061 instance.update();
2062 isHmrUpdating = false;
2063 });
2064}
2065function reload(id, newComp) {
2066 const record = map.get(id);
2067 if (!record)
2068 return;
2069 newComp = normalizeClassComponent(newComp);
2070 // update initial def (for not-yet-rendered components)
2071 updateComponentDef(record.initialDef, newComp);
2072 // create a snapshot which avoids the set being mutated during updates
2073 const instances = [...record.instances];
2074 for (const instance of instances) {
2075 const oldComp = normalizeClassComponent(instance.type);
2076 if (!hmrDirtyComponents.has(oldComp)) {
2077 // 1. Update existing comp definition to match new one
2078 if (oldComp !== record.initialDef) {
2079 updateComponentDef(oldComp, newComp);
2080 }
2081 // 2. mark definition dirty. This forces the renderer to replace the
2082 // component on patch.
2083 hmrDirtyComponents.add(oldComp);
2084 }
2085 // 3. invalidate options resolution cache
2086 instance.appContext.optionsCache.delete(instance.type);
2087 // 4. actually update
2088 if (instance.ceReload) {
2089 // custom element
2090 hmrDirtyComponents.add(oldComp);
2091 instance.ceReload(newComp.styles);
2092 hmrDirtyComponents.delete(oldComp);
2093 }
2094 else if (instance.parent) {
2095 // 4. Force the parent instance to re-render. This will cause all updated
2096 // components to be unmounted and re-mounted. Queue the update so that we
2097 // don't end up forcing the same parent to re-render multiple times.
2098 queueJob(instance.parent.update);
2099 // instance is the inner component of an async custom element
2100 // invoke to reset styles
2101 if (instance.parent.type.__asyncLoader &&
2102 instance.parent.ceReload) {
2103 instance.parent.ceReload(newComp.styles);
2104 }
2105 }
2106 else if (instance.appContext.reload) {
2107 // root instance mounted via createApp() has a reload method
2108 instance.appContext.reload();
2109 }
2110 else if (typeof window !== 'undefined') {
2111 // root instance inside tree created via raw render(). Force reload.
2112 window.location.reload();
2113 }
2114 else {
2115 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
2116 }
2117 }
2118 // 5. make sure to cleanup dirty hmr components after update
2119 queuePostFlushCb(() => {
2120 for (const instance of instances) {
2121 hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
2122 }
2123 });
2124}
2125function updateComponentDef(oldComp, newComp) {
2126 extend(oldComp, newComp);
2127 for (const key in oldComp) {
2128 if (key !== '__file' && !(key in newComp)) {
2129 delete oldComp[key];
2130 }
2131 }
2132}
2133function tryWrap(fn) {
2134 return (id, arg) => {
2135 try {
2136 return fn(id, arg);
2137 }
2138 catch (e) {
2139 console.error(e);
2140 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
2141 `Full reload required.`);
2142 }
2143 };
2144}
2145
2146let devtools;
2147let buffer = [];
2148let devtoolsNotInstalled = false;
2149function emit(event, ...args) {
2150 if (devtools) {
2151 devtools.emit(event, ...args);
2152 }
2153 else if (!devtoolsNotInstalled) {
2154 buffer.push({ event, args });
2155 }
2156}
2157function setDevtoolsHook(hook, target) {
2158 var _a, _b;
2159 devtools = hook;
2160 if (devtools) {
2161 devtools.enabled = true;
2162 buffer.forEach(({ event, args }) => devtools.emit(event, ...args));
2163 buffer = [];
2164 }
2165 else if (
2166 // handle late devtools injection - only do this if we are in an actual
2167 // browser environment to avoid the timer handle stalling test runner exit
2168 // (#4815)
2169 typeof window !== 'undefined' &&
2170 // some envs mock window but not fully
2171 window.HTMLElement &&
2172 // also exclude jsdom
2173 !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
2174 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
2175 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
2176 replay.push((newHook) => {
2177 setDevtoolsHook(newHook, target);
2178 });
2179 // clear buffer after 3s - the user probably doesn't have devtools installed
2180 // at all, and keeping the buffer will cause memory leaks (#4738)
2181 setTimeout(() => {
2182 if (!devtools) {
2183 target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
2184 devtoolsNotInstalled = true;
2185 buffer = [];
2186 }
2187 }, 3000);
2188 }
2189 else {
2190 // non-browser env, assume not installed
2191 devtoolsNotInstalled = true;
2192 buffer = [];
2193 }
2194}
2195function devtoolsInitApp(app, version) {
2196 emit("app:init" /* APP_INIT */, app, version, {
2197 Fragment,
2198 Text,
2199 Comment,
2200 Static
2201 });
2202}
2203function devtoolsUnmountApp(app) {
2204 emit("app:unmount" /* APP_UNMOUNT */, app);
2205}
2206const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
2207const devtoolsComponentUpdated =
2208/*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
2209const devtoolsComponentRemoved =
2210/*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
2211function createDevtoolsComponentHook(hook) {
2212 return (component) => {
2213 emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
2214 };
2215}
2216const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
2217const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
2218function createDevtoolsPerformanceHook(hook) {
2219 return (component, type, time) => {
2220 emit(hook, component.appContext.app, component.uid, component, type, time);
2221 };
2222}
2223function devtoolsComponentEmit(component, event, params) {
2224 emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
2225}
2226
2227function emit$1(instance, event, ...rawArgs) {
2228 if (instance.isUnmounted)
2229 return;
2230 const props = instance.vnode.props || EMPTY_OBJ;
2231 {
2232 const { emitsOptions, propsOptions: [propsOptions] } = instance;
2233 if (emitsOptions) {
2234 if (!(event in emitsOptions) &&
2235 !(false )) {
2236 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
2237 warn$1(`Component emitted event "${event}" but it is neither declared in ` +
2238 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
2239 }
2240 }
2241 else {
2242 const validator = emitsOptions[event];
2243 if (isFunction(validator)) {
2244 const isValid = validator(...rawArgs);
2245 if (!isValid) {
2246 warn$1(`Invalid event arguments: event validation failed for event "${event}".`);
2247 }
2248 }
2249 }
2250 }
2251 }
2252 let args = rawArgs;
2253 const isModelListener = event.startsWith('update:');
2254 // for v-model update:xxx events, apply modifiers on args
2255 const modelArg = isModelListener && event.slice(7);
2256 if (modelArg && modelArg in props) {
2257 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
2258 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
2259 if (trim) {
2260 args = rawArgs.map(a => a.trim());
2261 }
2262 if (number) {
2263 args = rawArgs.map(toNumber);
2264 }
2265 }
2266 {
2267 devtoolsComponentEmit(instance, event, args);
2268 }
2269 {
2270 const lowerCaseEvent = event.toLowerCase();
2271 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
2272 warn$1(`Event "${lowerCaseEvent}" is emitted in component ` +
2273 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
2274 `Note that HTML attributes are case-insensitive and you cannot use ` +
2275 `v-on to listen to camelCase events when using in-DOM templates. ` +
2276 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
2277 }
2278 }
2279 let handlerName;
2280 let handler = props[(handlerName = toHandlerKey(event))] ||
2281 // also try camelCase event handler (#2249)
2282 props[(handlerName = toHandlerKey(camelize(event)))];
2283 // for v-model update:xxx events, also trigger kebab-case equivalent
2284 // for props passed via kebab-case
2285 if (!handler && isModelListener) {
2286 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
2287 }
2288 if (handler) {
2289 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2290 }
2291 const onceHandler = props[handlerName + `Once`];
2292 if (onceHandler) {
2293 if (!instance.emitted) {
2294 instance.emitted = {};
2295 }
2296 else if (instance.emitted[handlerName]) {
2297 return;
2298 }
2299 instance.emitted[handlerName] = true;
2300 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2301 }
2302}
2303function normalizeEmitsOptions(comp, appContext, asMixin = false) {
2304 const cache = appContext.emitsCache;
2305 const cached = cache.get(comp);
2306 if (cached !== undefined) {
2307 return cached;
2308 }
2309 const raw = comp.emits;
2310 let normalized = {};
2311 // apply mixin/extends props
2312 let hasExtends = false;
2313 if (!isFunction(comp)) {
2314 const extendEmits = (raw) => {
2315 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
2316 if (normalizedFromExtend) {
2317 hasExtends = true;
2318 extend(normalized, normalizedFromExtend);
2319 }
2320 };
2321 if (!asMixin && appContext.mixins.length) {
2322 appContext.mixins.forEach(extendEmits);
2323 }
2324 if (comp.extends) {
2325 extendEmits(comp.extends);
2326 }
2327 if (comp.mixins) {
2328 comp.mixins.forEach(extendEmits);
2329 }
2330 }
2331 if (!raw && !hasExtends) {
2332 cache.set(comp, null);
2333 return null;
2334 }
2335 if (isArray(raw)) {
2336 raw.forEach(key => (normalized[key] = null));
2337 }
2338 else {
2339 extend(normalized, raw);
2340 }
2341 cache.set(comp, normalized);
2342 return normalized;
2343}
2344// Check if an incoming prop key is a declared emit event listener.
2345// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
2346// both considered matched listeners.
2347function isEmitListener(options, key) {
2348 if (!options || !isOn(key)) {
2349 return false;
2350 }
2351 key = key.slice(2).replace(/Once$/, '');
2352 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
2353 hasOwn(options, hyphenate(key)) ||
2354 hasOwn(options, key));
2355}
2356
2357/**
2358 * mark the current rendering instance for asset resolution (e.g.
2359 * resolveComponent, resolveDirective) during render
2360 */
2361let currentRenderingInstance = null;
2362let currentScopeId = null;
2363/**
2364 * Note: rendering calls maybe nested. The function returns the parent rendering
2365 * instance if present, which should be restored after the render is done:
2366 *
2367 * ```js
2368 * const prev = setCurrentRenderingInstance(i)
2369 * // ...render
2370 * setCurrentRenderingInstance(prev)
2371 * ```
2372 */
2373function setCurrentRenderingInstance(instance) {
2374 const prev = currentRenderingInstance;
2375 currentRenderingInstance = instance;
2376 currentScopeId = (instance && instance.type.__scopeId) || null;
2377 return prev;
2378}
2379/**
2380 * Set scope id when creating hoisted vnodes.
2381 * @private compiler helper
2382 */
2383function pushScopeId(id) {
2384 currentScopeId = id;
2385}
2386/**
2387 * Technically we no longer need this after 3.0.8 but we need to keep the same
2388 * API for backwards compat w/ code generated by compilers.
2389 * @private
2390 */
2391function popScopeId() {
2392 currentScopeId = null;
2393}
2394/**
2395 * Only for backwards compat
2396 * @private
2397 */
2398const withScopeId = (_id) => withCtx;
2399/**
2400 * Wrap a slot function to memoize current rendering instance
2401 * @private compiler helper
2402 */
2403function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
2404) {
2405 if (!ctx)
2406 return fn;
2407 // already normalized
2408 if (fn._n) {
2409 return fn;
2410 }
2411 const renderFnWithContext = (...args) => {
2412 // If a user calls a compiled slot inside a template expression (#1745), it
2413 // can mess up block tracking, so by default we disable block tracking and
2414 // force bail out when invoking a compiled slot (indicated by the ._d flag).
2415 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
2416 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
2417 if (renderFnWithContext._d) {
2418 setBlockTracking(-1);
2419 }
2420 const prevInstance = setCurrentRenderingInstance(ctx);
2421 const res = fn(...args);
2422 setCurrentRenderingInstance(prevInstance);
2423 if (renderFnWithContext._d) {
2424 setBlockTracking(1);
2425 }
2426 {
2427 devtoolsComponentUpdated(ctx);
2428 }
2429 return res;
2430 };
2431 // mark normalized to avoid duplicated wrapping
2432 renderFnWithContext._n = true;
2433 // mark this as compiled by default
2434 // this is used in vnode.ts -> normalizeChildren() to set the slot
2435 // rendering flag.
2436 renderFnWithContext._c = true;
2437 // disable block tracking by default
2438 renderFnWithContext._d = true;
2439 return renderFnWithContext;
2440}
2441
2442/**
2443 * dev only flag to track whether $attrs was used during render.
2444 * If $attrs was used during render then the warning for failed attrs
2445 * fallthrough can be suppressed.
2446 */
2447let accessedAttrs = false;
2448function markAttrsAccessed() {
2449 accessedAttrs = true;
2450}
2451function renderComponentRoot(instance) {
2452 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
2453 let result;
2454 let fallthroughAttrs;
2455 const prev = setCurrentRenderingInstance(instance);
2456 {
2457 accessedAttrs = false;
2458 }
2459 try {
2460 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
2461 // withProxy is a proxy with a different `has` trap only for
2462 // runtime-compiled render functions using `with` block.
2463 const proxyToUse = withProxy || proxy;
2464 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2465 fallthroughAttrs = attrs;
2466 }
2467 else {
2468 // functional
2469 const render = Component;
2470 // in dev, mark attrs accessed if optional props (attrs === props)
2471 if (true && attrs === props) {
2472 markAttrsAccessed();
2473 }
2474 result = normalizeVNode(render.length > 1
2475 ? render(props, true
2476 ? {
2477 get attrs() {
2478 markAttrsAccessed();
2479 return attrs;
2480 },
2481 slots,
2482 emit
2483 }
2484 : { attrs, slots, emit })
2485 : render(props, null /* we know it doesn't need it */));
2486 fallthroughAttrs = Component.props
2487 ? attrs
2488 : getFunctionalFallthrough(attrs);
2489 }
2490 }
2491 catch (err) {
2492 blockStack.length = 0;
2493 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2494 result = createVNode(Comment);
2495 }
2496 // attr merging
2497 // in dev mode, comments are preserved, and it's possible for a template
2498 // to have comments along side the root element which makes it a fragment
2499 let root = result;
2500 let setRoot = undefined;
2501 if (result.patchFlag > 0 &&
2502 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
2503 [root, setRoot] = getChildRoot(result);
2504 }
2505 if (fallthroughAttrs && inheritAttrs !== false) {
2506 const keys = Object.keys(fallthroughAttrs);
2507 const { shapeFlag } = root;
2508 if (keys.length) {
2509 if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) {
2510 if (propsOptions && keys.some(isModelListener)) {
2511 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2512 // prop, it indicates this component expects to handle v-model and
2513 // it should not fallthrough.
2514 // related: #1543, #1643, #1989
2515 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2516 }
2517 root = cloneVNode(root, fallthroughAttrs);
2518 }
2519 else if (!accessedAttrs && root.type !== Comment) {
2520 const allAttrs = Object.keys(attrs);
2521 const eventAttrs = [];
2522 const extraAttrs = [];
2523 for (let i = 0, l = allAttrs.length; i < l; i++) {
2524 const key = allAttrs[i];
2525 if (isOn(key)) {
2526 // ignore v-model handlers when they fail to fallthrough
2527 if (!isModelListener(key)) {
2528 // remove `on`, lowercase first letter to reflect event casing
2529 // accurately
2530 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2531 }
2532 }
2533 else {
2534 extraAttrs.push(key);
2535 }
2536 }
2537 if (extraAttrs.length) {
2538 warn$1(`Extraneous non-props attributes (` +
2539 `${extraAttrs.join(', ')}) ` +
2540 `were passed to component but could not be automatically inherited ` +
2541 `because component renders fragment or text root nodes.`);
2542 }
2543 if (eventAttrs.length) {
2544 warn$1(`Extraneous non-emits event listeners (` +
2545 `${eventAttrs.join(', ')}) ` +
2546 `were passed to component but could not be automatically inherited ` +
2547 `because component renders fragment or text root nodes. ` +
2548 `If the listener is intended to be a component custom event listener only, ` +
2549 `declare it using the "emits" option.`);
2550 }
2551 }
2552 }
2553 }
2554 // inherit directives
2555 if (vnode.dirs) {
2556 if (!isElementRoot(root)) {
2557 warn$1(`Runtime directive used on component with non-element root node. ` +
2558 `The directives will not function as intended.`);
2559 }
2560 // clone before mutating since the root may be a hoisted vnode
2561 root = cloneVNode(root);
2562 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2563 }
2564 // inherit transition data
2565 if (vnode.transition) {
2566 if (!isElementRoot(root)) {
2567 warn$1(`Component inside <Transition> renders non-element root node ` +
2568 `that cannot be animated.`);
2569 }
2570 root.transition = vnode.transition;
2571 }
2572 if (setRoot) {
2573 setRoot(root);
2574 }
2575 else {
2576 result = root;
2577 }
2578 setCurrentRenderingInstance(prev);
2579 return result;
2580}
2581/**
2582 * dev only
2583 * In dev mode, template root level comments are rendered, which turns the
2584 * template into a fragment root, but we need to locate the single element
2585 * root for attrs and scope id processing.
2586 */
2587const getChildRoot = (vnode) => {
2588 const rawChildren = vnode.children;
2589 const dynamicChildren = vnode.dynamicChildren;
2590 const childRoot = filterSingleRoot(rawChildren);
2591 if (!childRoot) {
2592 return [vnode, undefined];
2593 }
2594 const index = rawChildren.indexOf(childRoot);
2595 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2596 const setRoot = (updatedRoot) => {
2597 rawChildren[index] = updatedRoot;
2598 if (dynamicChildren) {
2599 if (dynamicIndex > -1) {
2600 dynamicChildren[dynamicIndex] = updatedRoot;
2601 }
2602 else if (updatedRoot.patchFlag > 0) {
2603 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2604 }
2605 }
2606 };
2607 return [normalizeVNode(childRoot), setRoot];
2608};
2609function filterSingleRoot(children) {
2610 let singleRoot;
2611 for (let i = 0; i < children.length; i++) {
2612 const child = children[i];
2613 if (isVNode(child)) {
2614 // ignore user comment
2615 if (child.type !== Comment || child.children === 'v-if') {
2616 if (singleRoot) {
2617 // has more than 1 non-comment child, return now
2618 return;
2619 }
2620 else {
2621 singleRoot = child;
2622 }
2623 }
2624 }
2625 else {
2626 return;
2627 }
2628 }
2629 return singleRoot;
2630}
2631const getFunctionalFallthrough = (attrs) => {
2632 let res;
2633 for (const key in attrs) {
2634 if (key === 'class' || key === 'style' || isOn(key)) {
2635 (res || (res = {}))[key] = attrs[key];
2636 }
2637 }
2638 return res;
2639};
2640const filterModelListeners = (attrs, props) => {
2641 const res = {};
2642 for (const key in attrs) {
2643 if (!isModelListener(key) || !(key.slice(9) in props)) {
2644 res[key] = attrs[key];
2645 }
2646 }
2647 return res;
2648};
2649const isElementRoot = (vnode) => {
2650 return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) ||
2651 vnode.type === Comment // potential v-if branch switch
2652 );
2653};
2654function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2655 const { props: prevProps, children: prevChildren, component } = prevVNode;
2656 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2657 const emits = component.emitsOptions;
2658 // Parent component's render function was hot-updated. Since this may have
2659 // caused the child component's slots content to have changed, we need to
2660 // force the child to update as well.
2661 if ((prevChildren || nextChildren) && isHmrUpdating) {
2662 return true;
2663 }
2664 // force child update for runtime directive or transition on component vnode.
2665 if (nextVNode.dirs || nextVNode.transition) {
2666 return true;
2667 }
2668 if (optimized && patchFlag >= 0) {
2669 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2670 // slot content that references values that might have changed,
2671 // e.g. in a v-for
2672 return true;
2673 }
2674 if (patchFlag & 16 /* FULL_PROPS */) {
2675 if (!prevProps) {
2676 return !!nextProps;
2677 }
2678 // presence of this flag indicates props are always non-null
2679 return hasPropsChanged(prevProps, nextProps, emits);
2680 }
2681 else if (patchFlag & 8 /* PROPS */) {
2682 const dynamicProps = nextVNode.dynamicProps;
2683 for (let i = 0; i < dynamicProps.length; i++) {
2684 const key = dynamicProps[i];
2685 if (nextProps[key] !== prevProps[key] &&
2686 !isEmitListener(emits, key)) {
2687 return true;
2688 }
2689 }
2690 }
2691 }
2692 else {
2693 // this path is only taken by manually written render functions
2694 // so presence of any children leads to a forced update
2695 if (prevChildren || nextChildren) {
2696 if (!nextChildren || !nextChildren.$stable) {
2697 return true;
2698 }
2699 }
2700 if (prevProps === nextProps) {
2701 return false;
2702 }
2703 if (!prevProps) {
2704 return !!nextProps;
2705 }
2706 if (!nextProps) {
2707 return true;
2708 }
2709 return hasPropsChanged(prevProps, nextProps, emits);
2710 }
2711 return false;
2712}
2713function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2714 const nextKeys = Object.keys(nextProps);
2715 if (nextKeys.length !== Object.keys(prevProps).length) {
2716 return true;
2717 }
2718 for (let i = 0; i < nextKeys.length; i++) {
2719 const key = nextKeys[i];
2720 if (nextProps[key] !== prevProps[key] &&
2721 !isEmitListener(emitsOptions, key)) {
2722 return true;
2723 }
2724 }
2725 return false;
2726}
2727function updateHOCHostEl({ vnode, parent }, el // HostNode
2728) {
2729 while (parent && parent.subTree === vnode) {
2730 (vnode = parent.vnode).el = el;
2731 parent = parent.parent;
2732 }
2733}
2734
2735const isSuspense = (type) => type.__isSuspense;
2736// Suspense exposes a component-like API, and is treated like a component
2737// in the compiler, but internally it's a special built-in type that hooks
2738// directly into the renderer.
2739const SuspenseImpl = {
2740 name: 'Suspense',
2741 // In order to make Suspense tree-shakable, we need to avoid importing it
2742 // directly in the renderer. The renderer checks for the __isSuspense flag
2743 // on a vnode's type and calls the `process` method, passing in renderer
2744 // internals.
2745 __isSuspense: true,
2746 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2747 // platform-specific impl passed from renderer
2748 rendererInternals) {
2749 if (n1 == null) {
2750 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2751 }
2752 else {
2753 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2754 }
2755 },
2756 hydrate: hydrateSuspense,
2757 create: createSuspenseBoundary,
2758 normalize: normalizeSuspenseChildren
2759};
2760// Force-casted public typing for h and TSX props inference
2761const Suspense = (SuspenseImpl );
2762function triggerEvent(vnode, name) {
2763 const eventListener = vnode.props && vnode.props[name];
2764 if (isFunction(eventListener)) {
2765 eventListener();
2766 }
2767}
2768function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2769 const { p: patch, o: { createElement } } = rendererInternals;
2770 const hiddenContainer = createElement('div');
2771 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2772 // start mounting the content subtree in an off-dom container
2773 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2774 // now check if we have encountered any async deps
2775 if (suspense.deps > 0) {
2776 // has async
2777 // invoke @fallback event
2778 triggerEvent(vnode, 'onPending');
2779 triggerEvent(vnode, 'onFallback');
2780 // mount the fallback tree
2781 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2782 isSVG, slotScopeIds);
2783 setActiveBranch(suspense, vnode.ssFallback);
2784 }
2785 else {
2786 // Suspense has no async deps. Just resolve.
2787 suspense.resolve();
2788 }
2789}
2790function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2791 const suspense = (n2.suspense = n1.suspense);
2792 suspense.vnode = n2;
2793 n2.el = n1.el;
2794 const newBranch = n2.ssContent;
2795 const newFallback = n2.ssFallback;
2796 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2797 if (pendingBranch) {
2798 suspense.pendingBranch = newBranch;
2799 if (isSameVNodeType(newBranch, pendingBranch)) {
2800 // same root type but content may have changed.
2801 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2802 if (suspense.deps <= 0) {
2803 suspense.resolve();
2804 }
2805 else if (isInFallback) {
2806 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2807 isSVG, slotScopeIds, optimized);
2808 setActiveBranch(suspense, newFallback);
2809 }
2810 }
2811 else {
2812 // toggled before pending tree is resolved
2813 suspense.pendingId++;
2814 if (isHydrating) {
2815 // if toggled before hydration is finished, the current DOM tree is
2816 // no longer valid. set it as the active branch so it will be unmounted
2817 // when resolved
2818 suspense.isHydrating = false;
2819 suspense.activeBranch = pendingBranch;
2820 }
2821 else {
2822 unmount(pendingBranch, parentComponent, suspense);
2823 }
2824 // increment pending ID. this is used to invalidate async callbacks
2825 // reset suspense state
2826 suspense.deps = 0;
2827 // discard effects from pending branch
2828 suspense.effects.length = 0;
2829 // discard previous container
2830 suspense.hiddenContainer = createElement('div');
2831 if (isInFallback) {
2832 // already in fallback state
2833 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2834 if (suspense.deps <= 0) {
2835 suspense.resolve();
2836 }
2837 else {
2838 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2839 isSVG, slotScopeIds, optimized);
2840 setActiveBranch(suspense, newFallback);
2841 }
2842 }
2843 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2844 // toggled "back" to current active branch
2845 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2846 // force resolve
2847 suspense.resolve(true);
2848 }
2849 else {
2850 // switched to a 3rd branch
2851 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2852 if (suspense.deps <= 0) {
2853 suspense.resolve();
2854 }
2855 }
2856 }
2857 }
2858 else {
2859 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2860 // root did not change, just normal patch
2861 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2862 setActiveBranch(suspense, newBranch);
2863 }
2864 else {
2865 // root node toggled
2866 // invoke @pending event
2867 triggerEvent(n2, 'onPending');
2868 // mount pending branch in off-dom container
2869 suspense.pendingBranch = newBranch;
2870 suspense.pendingId++;
2871 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2872 if (suspense.deps <= 0) {
2873 // incoming branch has no async deps, resolve now.
2874 suspense.resolve();
2875 }
2876 else {
2877 const { timeout, pendingId } = suspense;
2878 if (timeout > 0) {
2879 setTimeout(() => {
2880 if (suspense.pendingId === pendingId) {
2881 suspense.fallback(newFallback);
2882 }
2883 }, timeout);
2884 }
2885 else if (timeout === 0) {
2886 suspense.fallback(newFallback);
2887 }
2888 }
2889 }
2890 }
2891}
2892let hasWarned = false;
2893function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2894 /* istanbul ignore if */
2895 if (!hasWarned) {
2896 hasWarned = true;
2897 // @ts-ignore `console.info` cannot be null error
2898 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2899 }
2900 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2901 const timeout = toNumber(vnode.props && vnode.props.timeout);
2902 const suspense = {
2903 vnode,
2904 parent,
2905 parentComponent,
2906 isSVG,
2907 container,
2908 hiddenContainer,
2909 anchor,
2910 deps: 0,
2911 pendingId: 0,
2912 timeout: typeof timeout === 'number' ? timeout : -1,
2913 activeBranch: null,
2914 pendingBranch: null,
2915 isInFallback: true,
2916 isHydrating,
2917 isUnmounted: false,
2918 effects: [],
2919 resolve(resume = false) {
2920 {
2921 if (!resume && !suspense.pendingBranch) {
2922 throw new Error(`suspense.resolve() is called without a pending branch.`);
2923 }
2924 if (suspense.isUnmounted) {
2925 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2926 }
2927 }
2928 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2929 if (suspense.isHydrating) {
2930 suspense.isHydrating = false;
2931 }
2932 else if (!resume) {
2933 const delayEnter = activeBranch &&
2934 pendingBranch.transition &&
2935 pendingBranch.transition.mode === 'out-in';
2936 if (delayEnter) {
2937 activeBranch.transition.afterLeave = () => {
2938 if (pendingId === suspense.pendingId) {
2939 move(pendingBranch, container, anchor, 0 /* ENTER */);
2940 }
2941 };
2942 }
2943 // this is initial anchor on mount
2944 let { anchor } = suspense;
2945 // unmount current active tree
2946 if (activeBranch) {
2947 // if the fallback tree was mounted, it may have been moved
2948 // as part of a parent suspense. get the latest anchor for insertion
2949 anchor = next(activeBranch);
2950 unmount(activeBranch, parentComponent, suspense, true);
2951 }
2952 if (!delayEnter) {
2953 // move content from off-dom container to actual container
2954 move(pendingBranch, container, anchor, 0 /* ENTER */);
2955 }
2956 }
2957 setActiveBranch(suspense, pendingBranch);
2958 suspense.pendingBranch = null;
2959 suspense.isInFallback = false;
2960 // flush buffered effects
2961 // check if there is a pending parent suspense
2962 let parent = suspense.parent;
2963 let hasUnresolvedAncestor = false;
2964 while (parent) {
2965 if (parent.pendingBranch) {
2966 // found a pending parent suspense, merge buffered post jobs
2967 // into that parent
2968 parent.effects.push(...effects);
2969 hasUnresolvedAncestor = true;
2970 break;
2971 }
2972 parent = parent.parent;
2973 }
2974 // no pending parent suspense, flush all jobs
2975 if (!hasUnresolvedAncestor) {
2976 queuePostFlushCb(effects);
2977 }
2978 suspense.effects = [];
2979 // invoke @resolve event
2980 triggerEvent(vnode, 'onResolve');
2981 },
2982 fallback(fallbackVNode) {
2983 if (!suspense.pendingBranch) {
2984 return;
2985 }
2986 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2987 // invoke @fallback event
2988 triggerEvent(vnode, 'onFallback');
2989 const anchor = next(activeBranch);
2990 const mountFallback = () => {
2991 if (!suspense.isInFallback) {
2992 return;
2993 }
2994 // mount the fallback tree
2995 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2996 isSVG, slotScopeIds, optimized);
2997 setActiveBranch(suspense, fallbackVNode);
2998 };
2999 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
3000 if (delayEnter) {
3001 activeBranch.transition.afterLeave = mountFallback;
3002 }
3003 suspense.isInFallback = true;
3004 // unmount current active branch
3005 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
3006 true // shouldRemove
3007 );
3008 if (!delayEnter) {
3009 mountFallback();
3010 }
3011 },
3012 move(container, anchor, type) {
3013 suspense.activeBranch &&
3014 move(suspense.activeBranch, container, anchor, type);
3015 suspense.container = container;
3016 },
3017 next() {
3018 return suspense.activeBranch && next(suspense.activeBranch);
3019 },
3020 registerDep(instance, setupRenderEffect) {
3021 const isInPendingSuspense = !!suspense.pendingBranch;
3022 if (isInPendingSuspense) {
3023 suspense.deps++;
3024 }
3025 const hydratedEl = instance.vnode.el;
3026 instance
3027 .asyncDep.catch(err => {
3028 handleError(err, instance, 0 /* SETUP_FUNCTION */);
3029 })
3030 .then(asyncSetupResult => {
3031 // retry when the setup() promise resolves.
3032 // component may have been unmounted before resolve.
3033 if (instance.isUnmounted ||
3034 suspense.isUnmounted ||
3035 suspense.pendingId !== instance.suspenseId) {
3036 return;
3037 }
3038 // retry from this component
3039 instance.asyncResolved = true;
3040 const { vnode } = instance;
3041 {
3042 pushWarningContext(vnode);
3043 }
3044 handleSetupResult(instance, asyncSetupResult, false);
3045 if (hydratedEl) {
3046 // vnode may have been replaced if an update happened before the
3047 // async dep is resolved.
3048 vnode.el = hydratedEl;
3049 }
3050 const placeholder = !hydratedEl && instance.subTree.el;
3051 setupRenderEffect(instance, vnode,
3052 // component may have been moved before resolve.
3053 // if this is not a hydration, instance.subTree will be the comment
3054 // placeholder.
3055 parentNode(hydratedEl || instance.subTree.el),
3056 // anchor will not be used if this is hydration, so only need to
3057 // consider the comment placeholder case.
3058 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
3059 if (placeholder) {
3060 remove(placeholder);
3061 }
3062 updateHOCHostEl(instance, vnode.el);
3063 {
3064 popWarningContext();
3065 }
3066 // only decrease deps count if suspense is not already resolved
3067 if (isInPendingSuspense && --suspense.deps === 0) {
3068 suspense.resolve();
3069 }
3070 });
3071 },
3072 unmount(parentSuspense, doRemove) {
3073 suspense.isUnmounted = true;
3074 if (suspense.activeBranch) {
3075 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
3076 }
3077 if (suspense.pendingBranch) {
3078 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
3079 }
3080 }
3081 };
3082 return suspense;
3083}
3084function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
3085 /* eslint-disable no-restricted-globals */
3086 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
3087 // there are two possible scenarios for server-rendered suspense:
3088 // - success: ssr content should be fully resolved
3089 // - failure: ssr content should be the fallback branch.
3090 // however, on the client we don't really know if it has failed or not
3091 // attempt to hydrate the DOM assuming it has succeeded, but we still
3092 // need to construct a suspense boundary first
3093 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
3094 if (suspense.deps === 0) {
3095 suspense.resolve();
3096 }
3097 return result;
3098 /* eslint-enable no-restricted-globals */
3099}
3100function normalizeSuspenseChildren(vnode) {
3101 const { shapeFlag, children } = vnode;
3102 const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
3103 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
3104 vnode.ssFallback = isSlotChildren
3105 ? normalizeSuspenseSlot(children.fallback)
3106 : createVNode(Comment);
3107}
3108function normalizeSuspenseSlot(s) {
3109 let block;
3110 if (isFunction(s)) {
3111 const trackBlock = isBlockTreeEnabled && s._c;
3112 if (trackBlock) {
3113 // disableTracking: false
3114 // allow block tracking for compiled slots
3115 // (see ./componentRenderContext.ts)
3116 s._d = false;
3117 openBlock();
3118 }
3119 s = s();
3120 if (trackBlock) {
3121 s._d = true;
3122 block = currentBlock;
3123 closeBlock();
3124 }
3125 }
3126 if (isArray(s)) {
3127 const singleChild = filterSingleRoot(s);
3128 if (!singleChild) {
3129 warn$1(`<Suspense> slots expect a single root node.`);
3130 }
3131 s = singleChild;
3132 }
3133 s = normalizeVNode(s);
3134 if (block && !s.dynamicChildren) {
3135 s.dynamicChildren = block.filter(c => c !== s);
3136 }
3137 return s;
3138}
3139function queueEffectWithSuspense(fn, suspense) {
3140 if (suspense && suspense.pendingBranch) {
3141 if (isArray(fn)) {
3142 suspense.effects.push(...fn);
3143 }
3144 else {
3145 suspense.effects.push(fn);
3146 }
3147 }
3148 else {
3149 queuePostFlushCb(fn);
3150 }
3151}
3152function setActiveBranch(suspense, branch) {
3153 suspense.activeBranch = branch;
3154 const { vnode, parentComponent } = suspense;
3155 const el = (vnode.el = branch.el);
3156 // in case suspense is the root node of a component,
3157 // recursively update the HOC el
3158 if (parentComponent && parentComponent.subTree === vnode) {
3159 parentComponent.vnode.el = el;
3160 updateHOCHostEl(parentComponent, el);
3161 }
3162}
3163
3164function provide(key, value) {
3165 if (!currentInstance) {
3166 {
3167 warn$1(`provide() can only be used inside setup().`);
3168 }
3169 }
3170 else {
3171 let provides = currentInstance.provides;
3172 // by default an instance inherits its parent's provides object
3173 // but when it needs to provide values of its own, it creates its
3174 // own provides object using parent provides object as prototype.
3175 // this way in `inject` we can simply look up injections from direct
3176 // parent and let the prototype chain do the work.
3177 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
3178 if (parentProvides === provides) {
3179 provides = currentInstance.provides = Object.create(parentProvides);
3180 }
3181 // TS doesn't allow symbol as index type
3182 provides[key] = value;
3183 }
3184}
3185function inject(key, defaultValue, treatDefaultAsFactory = false) {
3186 // fallback to `currentRenderingInstance` so that this can be called in
3187 // a functional component
3188 const instance = currentInstance || currentRenderingInstance;
3189 if (instance) {
3190 // #2400
3191 // to support `app.use` plugins,
3192 // fallback to appContext's `provides` if the instance is at root
3193 const provides = instance.parent == null
3194 ? instance.vnode.appContext && instance.vnode.appContext.provides
3195 : instance.parent.provides;
3196 if (provides && key in provides) {
3197 // TS doesn't allow symbol as index type
3198 return provides[key];
3199 }
3200 else if (arguments.length > 1) {
3201 return treatDefaultAsFactory && isFunction(defaultValue)
3202 ? defaultValue.call(instance.proxy)
3203 : defaultValue;
3204 }
3205 else {
3206 warn$1(`injection "${String(key)}" not found.`);
3207 }
3208 }
3209 else {
3210 warn$1(`inject() can only be used inside setup() or functional components.`);
3211 }
3212}
3213
3214// Simple effect.
3215function watchEffect(effect, options) {
3216 return doWatch(effect, null, options);
3217}
3218function watchPostEffect(effect, options) {
3219 return doWatch(effect, null, (Object.assign(Object.assign({}, options), { flush: 'post' }) ));
3220}
3221function watchSyncEffect(effect, options) {
3222 return doWatch(effect, null, (Object.assign(Object.assign({}, options), { flush: 'sync' }) ));
3223}
3224// initial value for watchers to trigger on undefined initial values
3225const INITIAL_WATCHER_VALUE = {};
3226// implementation
3227function watch(source, cb, options) {
3228 if (!isFunction(cb)) {
3229 warn$1(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3230 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3231 `supports \`watch(source, cb, options?) signature.`);
3232 }
3233 return doWatch(source, cb, options);
3234}
3235function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
3236 if (!cb) {
3237 if (immediate !== undefined) {
3238 warn$1(`watch() "immediate" option is only respected when using the ` +
3239 `watch(source, callback, options?) signature.`);
3240 }
3241 if (deep !== undefined) {
3242 warn$1(`watch() "deep" option is only respected when using the ` +
3243 `watch(source, callback, options?) signature.`);
3244 }
3245 }
3246 const warnInvalidSource = (s) => {
3247 warn$1(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3248 `a reactive object, or an array of these types.`);
3249 };
3250 const instance = currentInstance;
3251 let getter;
3252 let forceTrigger = false;
3253 let isMultiSource = false;
3254 if (isRef(source)) {
3255 getter = () => source.value;
3256 forceTrigger = isShallow(source);
3257 }
3258 else if (isReactive(source)) {
3259 getter = () => source;
3260 deep = true;
3261 }
3262 else if (isArray(source)) {
3263 isMultiSource = true;
3264 forceTrigger = source.some(s => isReactive(s) || isShallow(s));
3265 getter = () => source.map(s => {
3266 if (isRef(s)) {
3267 return s.value;
3268 }
3269 else if (isReactive(s)) {
3270 return traverse(s);
3271 }
3272 else if (isFunction(s)) {
3273 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
3274 }
3275 else {
3276 warnInvalidSource(s);
3277 }
3278 });
3279 }
3280 else if (isFunction(source)) {
3281 if (cb) {
3282 // getter with cb
3283 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
3284 }
3285 else {
3286 // no cb -> simple effect
3287 getter = () => {
3288 if (instance && instance.isUnmounted) {
3289 return;
3290 }
3291 if (cleanup) {
3292 cleanup();
3293 }
3294 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onCleanup]);
3295 };
3296 }
3297 }
3298 else {
3299 getter = NOOP;
3300 warnInvalidSource(source);
3301 }
3302 if (cb && deep) {
3303 const baseGetter = getter;
3304 getter = () => traverse(baseGetter());
3305 }
3306 let cleanup;
3307 let onCleanup = (fn) => {
3308 cleanup = effect.onStop = () => {
3309 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3310 };
3311 };
3312 let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;
3313 const job = () => {
3314 if (!effect.active) {
3315 return;
3316 }
3317 if (cb) {
3318 // watch(source, cb)
3319 const newValue = effect.run();
3320 if (deep ||
3321 forceTrigger ||
3322 (isMultiSource
3323 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
3324 : hasChanged(newValue, oldValue)) ||
3325 (false )) {
3326 // cleanup before running cb again
3327 if (cleanup) {
3328 cleanup();
3329 }
3330 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3331 newValue,
3332 // pass undefined as the old value when it's changed for the first time
3333 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3334 onCleanup
3335 ]);
3336 oldValue = newValue;
3337 }
3338 }
3339 else {
3340 // watchEffect
3341 effect.run();
3342 }
3343 };
3344 // important: mark the job as a watcher callback so that scheduler knows
3345 // it is allowed to self-trigger (#1727)
3346 job.allowRecurse = !!cb;
3347 let scheduler;
3348 if (flush === 'sync') {
3349 scheduler = job; // the scheduler function gets called directly
3350 }
3351 else if (flush === 'post') {
3352 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3353 }
3354 else {
3355 // default: 'pre'
3356 scheduler = () => queuePreFlushCb(job);
3357 }
3358 const effect = new ReactiveEffect(getter, scheduler);
3359 {
3360 effect.onTrack = onTrack;
3361 effect.onTrigger = onTrigger;
3362 }
3363 // initial run
3364 if (cb) {
3365 if (immediate) {
3366 job();
3367 }
3368 else {
3369 oldValue = effect.run();
3370 }
3371 }
3372 else if (flush === 'post') {
3373 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
3374 }
3375 else {
3376 effect.run();
3377 }
3378 return () => {
3379 effect.stop();
3380 if (instance && instance.scope) {
3381 remove(instance.scope.effects, effect);
3382 }
3383 };
3384}
3385// this.$watch
3386function instanceWatch(source, value, options) {
3387 const publicThis = this.proxy;
3388 const getter = isString(source)
3389 ? source.includes('.')
3390 ? createPathGetter(publicThis, source)
3391 : () => publicThis[source]
3392 : source.bind(publicThis, publicThis);
3393 let cb;
3394 if (isFunction(value)) {
3395 cb = value;
3396 }
3397 else {
3398 cb = value.handler;
3399 options = value;
3400 }
3401 const cur = currentInstance;
3402 setCurrentInstance(this);
3403 const res = doWatch(getter, cb.bind(publicThis), options);
3404 if (cur) {
3405 setCurrentInstance(cur);
3406 }
3407 else {
3408 unsetCurrentInstance();
3409 }
3410 return res;
3411}
3412function createPathGetter(ctx, path) {
3413 const segments = path.split('.');
3414 return () => {
3415 let cur = ctx;
3416 for (let i = 0; i < segments.length && cur; i++) {
3417 cur = cur[segments[i]];
3418 }
3419 return cur;
3420 };
3421}
3422function traverse(value, seen) {
3423 if (!isObject(value) || value["__v_skip" /* SKIP */]) {
3424 return value;
3425 }
3426 seen = seen || new Set();
3427 if (seen.has(value)) {
3428 return value;
3429 }
3430 seen.add(value);
3431 if (isRef(value)) {
3432 traverse(value.value, seen);
3433 }
3434 else if (isArray(value)) {
3435 for (let i = 0; i < value.length; i++) {
3436 traverse(value[i], seen);
3437 }
3438 }
3439 else if (isSet(value) || isMap(value)) {
3440 value.forEach((v) => {
3441 traverse(v, seen);
3442 });
3443 }
3444 else if (isPlainObject(value)) {
3445 for (const key in value) {
3446 traverse(value[key], seen);
3447 }
3448 }
3449 return value;
3450}
3451
3452function useTransitionState() {
3453 const state = {
3454 isMounted: false,
3455 isLeaving: false,
3456 isUnmounting: false,
3457 leavingVNodes: new Map()
3458 };
3459 onMounted(() => {
3460 state.isMounted = true;
3461 });
3462 onBeforeUnmount(() => {
3463 state.isUnmounting = true;
3464 });
3465 return state;
3466}
3467const TransitionHookValidator = [Function, Array];
3468const BaseTransitionImpl = {
3469 name: `BaseTransition`,
3470 props: {
3471 mode: String,
3472 appear: Boolean,
3473 persisted: Boolean,
3474 // enter
3475 onBeforeEnter: TransitionHookValidator,
3476 onEnter: TransitionHookValidator,
3477 onAfterEnter: TransitionHookValidator,
3478 onEnterCancelled: TransitionHookValidator,
3479 // leave
3480 onBeforeLeave: TransitionHookValidator,
3481 onLeave: TransitionHookValidator,
3482 onAfterLeave: TransitionHookValidator,
3483 onLeaveCancelled: TransitionHookValidator,
3484 // appear
3485 onBeforeAppear: TransitionHookValidator,
3486 onAppear: TransitionHookValidator,
3487 onAfterAppear: TransitionHookValidator,
3488 onAppearCancelled: TransitionHookValidator
3489 },
3490 setup(props, { slots }) {
3491 const instance = getCurrentInstance();
3492 const state = useTransitionState();
3493 let prevTransitionKey;
3494 return () => {
3495 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3496 if (!children || !children.length) {
3497 return;
3498 }
3499 let child = children[0];
3500 if (children.length > 1) {
3501 let hasFound = false;
3502 // locate first non-comment child
3503 for (const c of children) {
3504 if (c.type !== Comment) {
3505 if (hasFound) {
3506 // warn more than one non-comment child
3507 warn$1('<transition> can only be used on a single element or component. ' +
3508 'Use <transition-group> for lists.');
3509 break;
3510 }
3511 child = c;
3512 hasFound = true;
3513 }
3514 }
3515 }
3516 // there's no need to track reactivity for these props so use the raw
3517 // props for a bit better perf
3518 const rawProps = toRaw(props);
3519 const { mode } = rawProps;
3520 // check mode
3521 if (mode &&
3522 mode !== 'in-out' &&
3523 mode !== 'out-in' &&
3524 mode !== 'default') {
3525 warn$1(`invalid <transition> mode: ${mode}`);
3526 }
3527 if (state.isLeaving) {
3528 return emptyPlaceholder(child);
3529 }
3530 // in the case of <transition><keep-alive/></transition>, we need to
3531 // compare the type of the kept-alive children.
3532 const innerChild = getKeepAliveChild(child);
3533 if (!innerChild) {
3534 return emptyPlaceholder(child);
3535 }
3536 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3537 setTransitionHooks(innerChild, enterHooks);
3538 const oldChild = instance.subTree;
3539 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3540 let transitionKeyChanged = false;
3541 const { getTransitionKey } = innerChild.type;
3542 if (getTransitionKey) {
3543 const key = getTransitionKey();
3544 if (prevTransitionKey === undefined) {
3545 prevTransitionKey = key;
3546 }
3547 else if (key !== prevTransitionKey) {
3548 prevTransitionKey = key;
3549 transitionKeyChanged = true;
3550 }
3551 }
3552 // handle mode
3553 if (oldInnerChild &&
3554 oldInnerChild.type !== Comment &&
3555 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3556 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3557 // update old tree's hooks in case of dynamic transition
3558 setTransitionHooks(oldInnerChild, leavingHooks);
3559 // switching between different views
3560 if (mode === 'out-in') {
3561 state.isLeaving = true;
3562 // return placeholder node and queue update when leave finishes
3563 leavingHooks.afterLeave = () => {
3564 state.isLeaving = false;
3565 instance.update();
3566 };
3567 return emptyPlaceholder(child);
3568 }
3569 else if (mode === 'in-out' && innerChild.type !== Comment) {
3570 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3571 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3572 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3573 // early removal callback
3574 el._leaveCb = () => {
3575 earlyRemove();
3576 el._leaveCb = undefined;
3577 delete enterHooks.delayedLeave;
3578 };
3579 enterHooks.delayedLeave = delayedLeave;
3580 };
3581 }
3582 }
3583 return child;
3584 };
3585 }
3586};
3587// export the public type for h/tsx inference
3588// also to avoid inline import() in generated d.ts files
3589const BaseTransition = BaseTransitionImpl;
3590function getLeavingNodesForType(state, vnode) {
3591 const { leavingVNodes } = state;
3592 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3593 if (!leavingVNodesCache) {
3594 leavingVNodesCache = Object.create(null);
3595 leavingVNodes.set(vnode.type, leavingVNodesCache);
3596 }
3597 return leavingVNodesCache;
3598}
3599// The transition hooks are attached to the vnode as vnode.transition
3600// and will be called at appropriate timing in the renderer.
3601function resolveTransitionHooks(vnode, props, state, instance) {
3602 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3603 const key = String(vnode.key);
3604 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3605 const callHook = (hook, args) => {
3606 hook &&
3607 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3608 };
3609 const callAsyncHook = (hook, args) => {
3610 const done = args[1];
3611 callHook(hook, args);
3612 if (isArray(hook)) {
3613 if (hook.every(hook => hook.length <= 1))
3614 done();
3615 }
3616 else if (hook.length <= 1) {
3617 done();
3618 }
3619 };
3620 const hooks = {
3621 mode,
3622 persisted,
3623 beforeEnter(el) {
3624 let hook = onBeforeEnter;
3625 if (!state.isMounted) {
3626 if (appear) {
3627 hook = onBeforeAppear || onBeforeEnter;
3628 }
3629 else {
3630 return;
3631 }
3632 }
3633 // for same element (v-show)
3634 if (el._leaveCb) {
3635 el._leaveCb(true /* cancelled */);
3636 }
3637 // for toggled element with same key (v-if)
3638 const leavingVNode = leavingVNodesCache[key];
3639 if (leavingVNode &&
3640 isSameVNodeType(vnode, leavingVNode) &&
3641 leavingVNode.el._leaveCb) {
3642 // force early removal (not cancelled)
3643 leavingVNode.el._leaveCb();
3644 }
3645 callHook(hook, [el]);
3646 },
3647 enter(el) {
3648 let hook = onEnter;
3649 let afterHook = onAfterEnter;
3650 let cancelHook = onEnterCancelled;
3651 if (!state.isMounted) {
3652 if (appear) {
3653 hook = onAppear || onEnter;
3654 afterHook = onAfterAppear || onAfterEnter;
3655 cancelHook = onAppearCancelled || onEnterCancelled;
3656 }
3657 else {
3658 return;
3659 }
3660 }
3661 let called = false;
3662 const done = (el._enterCb = (cancelled) => {
3663 if (called)
3664 return;
3665 called = true;
3666 if (cancelled) {
3667 callHook(cancelHook, [el]);
3668 }
3669 else {
3670 callHook(afterHook, [el]);
3671 }
3672 if (hooks.delayedLeave) {
3673 hooks.delayedLeave();
3674 }
3675 el._enterCb = undefined;
3676 });
3677 if (hook) {
3678 callAsyncHook(hook, [el, done]);
3679 }
3680 else {
3681 done();
3682 }
3683 },
3684 leave(el, remove) {
3685 const key = String(vnode.key);
3686 if (el._enterCb) {
3687 el._enterCb(true /* cancelled */);
3688 }
3689 if (state.isUnmounting) {
3690 return remove();
3691 }
3692 callHook(onBeforeLeave, [el]);
3693 let called = false;
3694 const done = (el._leaveCb = (cancelled) => {
3695 if (called)
3696 return;
3697 called = true;
3698 remove();
3699 if (cancelled) {
3700 callHook(onLeaveCancelled, [el]);
3701 }
3702 else {
3703 callHook(onAfterLeave, [el]);
3704 }
3705 el._leaveCb = undefined;
3706 if (leavingVNodesCache[key] === vnode) {
3707 delete leavingVNodesCache[key];
3708 }
3709 });
3710 leavingVNodesCache[key] = vnode;
3711 if (onLeave) {
3712 callAsyncHook(onLeave, [el, done]);
3713 }
3714 else {
3715 done();
3716 }
3717 },
3718 clone(vnode) {
3719 return resolveTransitionHooks(vnode, props, state, instance);
3720 }
3721 };
3722 return hooks;
3723}
3724// the placeholder really only handles one special case: KeepAlive
3725// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3726// placeholder with empty content to avoid the KeepAlive instance from being
3727// unmounted.
3728function emptyPlaceholder(vnode) {
3729 if (isKeepAlive(vnode)) {
3730 vnode = cloneVNode(vnode);
3731 vnode.children = null;
3732 return vnode;
3733 }
3734}
3735function getKeepAliveChild(vnode) {
3736 return isKeepAlive(vnode)
3737 ? vnode.children
3738 ? vnode.children[0]
3739 : undefined
3740 : vnode;
3741}
3742function setTransitionHooks(vnode, hooks) {
3743 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3744 setTransitionHooks(vnode.component.subTree, hooks);
3745 }
3746 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3747 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3748 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3749 }
3750 else {
3751 vnode.transition = hooks;
3752 }
3753}
3754function getTransitionRawChildren(children, keepComment = false, parentKey) {
3755 let ret = [];
3756 let keyedFragmentCount = 0;
3757 for (let i = 0; i < children.length; i++) {
3758 let child = children[i];
3759 // #5360 inherit parent key in case of <template v-for>
3760 const key = parentKey == null
3761 ? child.key
3762 : String(parentKey) + String(child.key != null ? child.key : i);
3763 // handle fragment children case, e.g. v-for
3764 if (child.type === Fragment) {
3765 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3766 keyedFragmentCount++;
3767 ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key));
3768 }
3769 // comment placeholders should be skipped, e.g. v-if
3770 else if (keepComment || child.type !== Comment) {
3771 ret.push(key != null ? cloneVNode(child, { key }) : child);
3772 }
3773 }
3774 // #1126 if a transition children list contains multiple sub fragments, these
3775 // fragments will be merged into a flat children array. Since each v-for
3776 // fragment may contain different static bindings inside, we need to de-op
3777 // these children to force full diffs to ensure correct behavior.
3778 if (keyedFragmentCount > 1) {
3779 for (let i = 0; i < ret.length; i++) {
3780 ret[i].patchFlag = -2 /* BAIL */;
3781 }
3782 }
3783 return ret;
3784}
3785
3786// implementation, close to no-op
3787function defineComponent(options) {
3788 return isFunction(options) ? { setup: options, name: options.name } : options;
3789}
3790
3791const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
3792function defineAsyncComponent(source) {
3793 if (isFunction(source)) {
3794 source = { loader: source };
3795 }
3796 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
3797 suspensible = true, onError: userOnError } = source;
3798 let pendingRequest = null;
3799 let resolvedComp;
3800 let retries = 0;
3801 const retry = () => {
3802 retries++;
3803 pendingRequest = null;
3804 return load();
3805 };
3806 const load = () => {
3807 let thisRequest;
3808 return (pendingRequest ||
3809 (thisRequest = pendingRequest =
3810 loader()
3811 .catch(err => {
3812 err = err instanceof Error ? err : new Error(String(err));
3813 if (userOnError) {
3814 return new Promise((resolve, reject) => {
3815 const userRetry = () => resolve(retry());
3816 const userFail = () => reject(err);
3817 userOnError(err, userRetry, userFail, retries + 1);
3818 });
3819 }
3820 else {
3821 throw err;
3822 }
3823 })
3824 .then((comp) => {
3825 if (thisRequest !== pendingRequest && pendingRequest) {
3826 return pendingRequest;
3827 }
3828 if (!comp) {
3829 warn$1(`Async component loader resolved to undefined. ` +
3830 `If you are using retry(), make sure to return its return value.`);
3831 }
3832 // interop module default
3833 if (comp &&
3834 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3835 comp = comp.default;
3836 }
3837 if (comp && !isObject(comp) && !isFunction(comp)) {
3838 throw new Error(`Invalid async component load result: ${comp}`);
3839 }
3840 resolvedComp = comp;
3841 return comp;
3842 })));
3843 };
3844 return defineComponent({
3845 name: 'AsyncComponentWrapper',
3846 __asyncLoader: load,
3847 get __asyncResolved() {
3848 return resolvedComp;
3849 },
3850 setup() {
3851 const instance = currentInstance;
3852 // already resolved
3853 if (resolvedComp) {
3854 return () => createInnerComp(resolvedComp, instance);
3855 }
3856 const onError = (err) => {
3857 pendingRequest = null;
3858 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3859 };
3860 // suspense-controlled or SSR.
3861 if ((suspensible && instance.suspense) ||
3862 (false )) {
3863 return load()
3864 .then(comp => {
3865 return () => createInnerComp(comp, instance);
3866 })
3867 .catch(err => {
3868 onError(err);
3869 return () => errorComponent
3870 ? createVNode(errorComponent, {
3871 error: err
3872 })
3873 : null;
3874 });
3875 }
3876 const loaded = ref(false);
3877 const error = ref();
3878 const delayed = ref(!!delay);
3879 if (delay) {
3880 setTimeout(() => {
3881 delayed.value = false;
3882 }, delay);
3883 }
3884 if (timeout != null) {
3885 setTimeout(() => {
3886 if (!loaded.value && !error.value) {
3887 const err = new Error(`Async component timed out after ${timeout}ms.`);
3888 onError(err);
3889 error.value = err;
3890 }
3891 }, timeout);
3892 }
3893 load()
3894 .then(() => {
3895 loaded.value = true;
3896 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3897 // parent is keep-alive, force update so the loaded component's
3898 // name is taken into account
3899 queueJob(instance.parent.update);
3900 }
3901 })
3902 .catch(err => {
3903 onError(err);
3904 error.value = err;
3905 });
3906 return () => {
3907 if (loaded.value && resolvedComp) {
3908 return createInnerComp(resolvedComp, instance);
3909 }
3910 else if (error.value && errorComponent) {
3911 return createVNode(errorComponent, {
3912 error: error.value
3913 });
3914 }
3915 else if (loadingComponent && !delayed.value) {
3916 return createVNode(loadingComponent);
3917 }
3918 };
3919 }
3920 });
3921}
3922function createInnerComp(comp, { vnode: { ref, props, children, shapeFlag }, parent }) {
3923 const vnode = createVNode(comp, props, children);
3924 // ensure inner component inherits the async wrapper's ref owner
3925 vnode.ref = ref;
3926 return vnode;
3927}
3928
3929const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3930const KeepAliveImpl = {
3931 name: `KeepAlive`,
3932 // Marker for special handling inside the renderer. We are not using a ===
3933 // check directly on KeepAlive in the renderer, because importing it directly
3934 // would prevent it from being tree-shaken.
3935 __isKeepAlive: true,
3936 props: {
3937 include: [String, RegExp, Array],
3938 exclude: [String, RegExp, Array],
3939 max: [String, Number]
3940 },
3941 setup(props, { slots }) {
3942 const instance = getCurrentInstance();
3943 // KeepAlive communicates with the instantiated renderer via the
3944 // ctx where the renderer passes in its internals,
3945 // and the KeepAlive instance exposes activate/deactivate implementations.
3946 // The whole point of this is to avoid importing KeepAlive directly in the
3947 // renderer to facilitate tree-shaking.
3948 const sharedContext = instance.ctx;
3949 const cache = new Map();
3950 const keys = new Set();
3951 let current = null;
3952 {
3953 instance.__v_cache = cache;
3954 }
3955 const parentSuspense = instance.suspense;
3956 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3957 const storageContainer = createElement('div');
3958 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3959 const instance = vnode.component;
3960 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3961 // in case props have changed
3962 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3963 queuePostRenderEffect(() => {
3964 instance.isDeactivated = false;
3965 if (instance.a) {
3966 invokeArrayFns(instance.a);
3967 }
3968 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3969 if (vnodeHook) {
3970 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3971 }
3972 }, parentSuspense);
3973 {
3974 // Update components tree
3975 devtoolsComponentAdded(instance);
3976 }
3977 };
3978 sharedContext.deactivate = (vnode) => {
3979 const instance = vnode.component;
3980 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3981 queuePostRenderEffect(() => {
3982 if (instance.da) {
3983 invokeArrayFns(instance.da);
3984 }
3985 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3986 if (vnodeHook) {
3987 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3988 }
3989 instance.isDeactivated = true;
3990 }, parentSuspense);
3991 {
3992 // Update components tree
3993 devtoolsComponentAdded(instance);
3994 }
3995 };
3996 function unmount(vnode) {
3997 // reset the shapeFlag so it can be properly unmounted
3998 resetShapeFlag(vnode);
3999 _unmount(vnode, instance, parentSuspense, true);
4000 }
4001 function pruneCache(filter) {
4002 cache.forEach((vnode, key) => {
4003 const name = getComponentName(vnode.type);
4004 if (name && (!filter || !filter(name))) {
4005 pruneCacheEntry(key);
4006 }
4007 });
4008 }
4009 function pruneCacheEntry(key) {
4010 const cached = cache.get(key);
4011 if (!current || cached.type !== current.type) {
4012 unmount(cached);
4013 }
4014 else if (current) {
4015 // current active instance should no longer be kept-alive.
4016 // we can't unmount it now but it might be later, so reset its flag now.
4017 resetShapeFlag(current);
4018 }
4019 cache.delete(key);
4020 keys.delete(key);
4021 }
4022 // prune cache on include/exclude prop change
4023 watch(() => [props.include, props.exclude], ([include, exclude]) => {
4024 include && pruneCache(name => matches(include, name));
4025 exclude && pruneCache(name => !matches(exclude, name));
4026 },
4027 // prune post-render after `current` has been updated
4028 { flush: 'post', deep: true });
4029 // cache sub tree after render
4030 let pendingCacheKey = null;
4031 const cacheSubtree = () => {
4032 // fix #1621, the pendingCacheKey could be 0
4033 if (pendingCacheKey != null) {
4034 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
4035 }
4036 };
4037 onMounted(cacheSubtree);
4038 onUpdated(cacheSubtree);
4039 onBeforeUnmount(() => {
4040 cache.forEach(cached => {
4041 const { subTree, suspense } = instance;
4042 const vnode = getInnerChild(subTree);
4043 if (cached.type === vnode.type) {
4044 // current instance will be unmounted as part of keep-alive's unmount
4045 resetShapeFlag(vnode);
4046 // but invoke its deactivated hook here
4047 const da = vnode.component.da;
4048 da && queuePostRenderEffect(da, suspense);
4049 return;
4050 }
4051 unmount(cached);
4052 });
4053 });
4054 return () => {
4055 pendingCacheKey = null;
4056 if (!slots.default) {
4057 return null;
4058 }
4059 const children = slots.default();
4060 const rawVNode = children[0];
4061 if (children.length > 1) {
4062 {
4063 warn$1(`KeepAlive should contain exactly one component child.`);
4064 }
4065 current = null;
4066 return children;
4067 }
4068 else if (!isVNode(rawVNode) ||
4069 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
4070 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
4071 current = null;
4072 return rawVNode;
4073 }
4074 let vnode = getInnerChild(rawVNode);
4075 const comp = vnode.type;
4076 // for async components, name check should be based in its loaded
4077 // inner component if available
4078 const name = getComponentName(isAsyncWrapper(vnode)
4079 ? vnode.type.__asyncResolved || {}
4080 : comp);
4081 const { include, exclude, max } = props;
4082 if ((include && (!name || !matches(include, name))) ||
4083 (exclude && name && matches(exclude, name))) {
4084 current = vnode;
4085 return rawVNode;
4086 }
4087 const key = vnode.key == null ? comp : vnode.key;
4088 const cachedVNode = cache.get(key);
4089 // clone vnode if it's reused because we are going to mutate it
4090 if (vnode.el) {
4091 vnode = cloneVNode(vnode);
4092 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
4093 rawVNode.ssContent = vnode;
4094 }
4095 }
4096 // #1513 it's possible for the returned vnode to be cloned due to attr
4097 // fallthrough or scopeId, so the vnode here may not be the final vnode
4098 // that is mounted. Instead of caching it directly, we store the pending
4099 // key and cache `instance.subTree` (the normalized vnode) in
4100 // beforeMount/beforeUpdate hooks.
4101 pendingCacheKey = key;
4102 if (cachedVNode) {
4103 // copy over mounted state
4104 vnode.el = cachedVNode.el;
4105 vnode.component = cachedVNode.component;
4106 if (vnode.transition) {
4107 // recursively update transition hooks on subTree
4108 setTransitionHooks(vnode, vnode.transition);
4109 }
4110 // avoid vnode being mounted as fresh
4111 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
4112 // make this key the freshest
4113 keys.delete(key);
4114 keys.add(key);
4115 }
4116 else {
4117 keys.add(key);
4118 // prune oldest entry
4119 if (max && keys.size > parseInt(max, 10)) {
4120 pruneCacheEntry(keys.values().next().value);
4121 }
4122 }
4123 // avoid vnode being unmounted
4124 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4125 current = vnode;
4126 return isSuspense(rawVNode.type) ? rawVNode : vnode;
4127 };
4128 }
4129};
4130// export the public type for h/tsx inference
4131// also to avoid inline import() in generated d.ts files
4132const KeepAlive = KeepAliveImpl;
4133function matches(pattern, name) {
4134 if (isArray(pattern)) {
4135 return pattern.some((p) => matches(p, name));
4136 }
4137 else if (isString(pattern)) {
4138 return pattern.split(',').includes(name);
4139 }
4140 else if (pattern.test) {
4141 return pattern.test(name);
4142 }
4143 /* istanbul ignore next */
4144 return false;
4145}
4146function onActivated(hook, target) {
4147 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
4148}
4149function onDeactivated(hook, target) {
4150 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
4151}
4152function registerKeepAliveHook(hook, type, target = currentInstance) {
4153 // cache the deactivate branch check wrapper for injected hooks so the same
4154 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
4155 // deactivation check".
4156 const wrappedHook = hook.__wdc ||
4157 (hook.__wdc = () => {
4158 // only fire the hook if the target instance is NOT in a deactivated branch.
4159 let current = target;
4160 while (current) {
4161 if (current.isDeactivated) {
4162 return;
4163 }
4164 current = current.parent;
4165 }
4166 return hook();
4167 });
4168 injectHook(type, wrappedHook, target);
4169 // In addition to registering it on the target instance, we walk up the parent
4170 // chain and register it on all ancestor instances that are keep-alive roots.
4171 // This avoids the need to walk the entire component tree when invoking these
4172 // hooks, and more importantly, avoids the need to track child components in
4173 // arrays.
4174 if (target) {
4175 let current = target.parent;
4176 while (current && current.parent) {
4177 if (isKeepAlive(current.parent.vnode)) {
4178 injectToKeepAliveRoot(wrappedHook, type, target, current);
4179 }
4180 current = current.parent;
4181 }
4182 }
4183}
4184function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
4185 // injectHook wraps the original for error handling, so make sure to remove
4186 // the wrapped version.
4187 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4188 onUnmounted(() => {
4189 remove(keepAliveRoot[type], injected);
4190 }, target);
4191}
4192function resetShapeFlag(vnode) {
4193 let shapeFlag = vnode.shapeFlag;
4194 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
4195 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4196 }
4197 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
4198 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
4199 }
4200 vnode.shapeFlag = shapeFlag;
4201}
4202function getInnerChild(vnode) {
4203 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
4204}
4205
4206function injectHook(type, hook, target = currentInstance, prepend = false) {
4207 if (target) {
4208 const hooks = target[type] || (target[type] = []);
4209 // cache the error handling wrapper for injected hooks so the same hook
4210 // can be properly deduped by the scheduler. "__weh" stands for "with error
4211 // handling".
4212 const wrappedHook = hook.__weh ||
4213 (hook.__weh = (...args) => {
4214 if (target.isUnmounted) {
4215 return;
4216 }
4217 // disable tracking inside all lifecycle hooks
4218 // since they can potentially be called inside effects.
4219 pauseTracking();
4220 // Set currentInstance during hook invocation.
4221 // This assumes the hook does not synchronously trigger other hooks, which
4222 // can only be false when the user does something really funky.
4223 setCurrentInstance(target);
4224 const res = callWithAsyncErrorHandling(hook, target, type, args);
4225 unsetCurrentInstance();
4226 resetTracking();
4227 return res;
4228 });
4229 if (prepend) {
4230 hooks.unshift(wrappedHook);
4231 }
4232 else {
4233 hooks.push(wrappedHook);
4234 }
4235 return wrappedHook;
4236 }
4237 else {
4238 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
4239 warn$1(`${apiName} is called when there is no active component instance to be ` +
4240 `associated with. ` +
4241 `Lifecycle injection APIs can only be used during execution of setup().` +
4242 (` If you are using async setup(), make sure to register lifecycle ` +
4243 `hooks before the first await statement.`
4244 ));
4245 }
4246}
4247const createHook = (lifecycle) => (hook, target = currentInstance) =>
4248// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
4249(!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
4250 injectHook(lifecycle, hook, target);
4251const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
4252const onMounted = createHook("m" /* MOUNTED */);
4253const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
4254const onUpdated = createHook("u" /* UPDATED */);
4255const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
4256const onUnmounted = createHook("um" /* UNMOUNTED */);
4257const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
4258const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
4259const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
4260function onErrorCaptured(hook, target = currentInstance) {
4261 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
4262}
4263
4264/**
4265Runtime helper for applying directives to a vnode. Example usage:
4266
4267const comp = resolveComponent('comp')
4268const foo = resolveDirective('foo')
4269const bar = resolveDirective('bar')
4270
4271return withDirectives(h(comp), [
4272 [foo, this.x],
4273 [bar, this.y]
4274])
4275*/
4276function validateDirectiveName(name) {
4277 if (isBuiltInDirective(name)) {
4278 warn$1('Do not use built-in directive ids as custom directive id: ' + name);
4279 }
4280}
4281/**
4282 * Adds directives to a VNode.
4283 */
4284function withDirectives(vnode, directives) {
4285 const internalInstance = currentRenderingInstance;
4286 if (internalInstance === null) {
4287 warn$1(`withDirectives can only be used inside render functions.`);
4288 return vnode;
4289 }
4290 const instance = getExposeProxy(internalInstance) ||
4291 internalInstance.proxy;
4292 const bindings = vnode.dirs || (vnode.dirs = []);
4293 for (let i = 0; i < directives.length; i++) {
4294 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4295 if (isFunction(dir)) {
4296 dir = {
4297 mounted: dir,
4298 updated: dir
4299 };
4300 }
4301 if (dir.deep) {
4302 traverse(value);
4303 }
4304 bindings.push({
4305 dir,
4306 instance,
4307 value,
4308 oldValue: void 0,
4309 arg,
4310 modifiers
4311 });
4312 }
4313 return vnode;
4314}
4315function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4316 const bindings = vnode.dirs;
4317 const oldBindings = prevVNode && prevVNode.dirs;
4318 for (let i = 0; i < bindings.length; i++) {
4319 const binding = bindings[i];
4320 if (oldBindings) {
4321 binding.oldValue = oldBindings[i].value;
4322 }
4323 let hook = binding.dir[name];
4324 if (hook) {
4325 // disable tracking inside all lifecycle hooks
4326 // since they can potentially be called inside effects.
4327 pauseTracking();
4328 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4329 vnode.el,
4330 binding,
4331 vnode,
4332 prevVNode
4333 ]);
4334 resetTracking();
4335 }
4336 }
4337}
4338
4339const COMPONENTS = 'components';
4340const DIRECTIVES = 'directives';
4341/**
4342 * @private
4343 */
4344function resolveComponent(name, maybeSelfReference) {
4345 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
4346}
4347const NULL_DYNAMIC_COMPONENT = Symbol();
4348/**
4349 * @private
4350 */
4351function resolveDynamicComponent(component) {
4352 if (isString(component)) {
4353 return resolveAsset(COMPONENTS, component, false) || component;
4354 }
4355 else {
4356 // invalid types will fallthrough to createVNode and raise warning
4357 return (component || NULL_DYNAMIC_COMPONENT);
4358 }
4359}
4360/**
4361 * @private
4362 */
4363function resolveDirective(name) {
4364 return resolveAsset(DIRECTIVES, name);
4365}
4366// implementation
4367function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
4368 const instance = currentRenderingInstance || currentInstance;
4369 if (instance) {
4370 const Component = instance.type;
4371 // explicit self name has highest priority
4372 if (type === COMPONENTS) {
4373 const selfName = getComponentName(Component, false /* do not include inferred name to avoid breaking existing code */);
4374 if (selfName &&
4375 (selfName === name ||
4376 selfName === camelize(name) ||
4377 selfName === capitalize(camelize(name)))) {
4378 return Component;
4379 }
4380 }
4381 const res =
4382 // local registration
4383 // check instance[type] first which is resolved for options API
4384 resolve(instance[type] || Component[type], name) ||
4385 // global registration
4386 resolve(instance.appContext[type], name);
4387 if (!res && maybeSelfReference) {
4388 // fallback to implicit self-reference
4389 return Component;
4390 }
4391 if (warnMissing && !res) {
4392 const extra = type === COMPONENTS
4393 ? `\nIf this is a native custom element, make sure to exclude it from ` +
4394 `component resolution via compilerOptions.isCustomElement.`
4395 : ``;
4396 warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
4397 }
4398 return res;
4399 }
4400 else {
4401 warn$1(`resolve${capitalize(type.slice(0, -1))} ` +
4402 `can only be used in render() or setup().`);
4403 }
4404}
4405function resolve(registry, name) {
4406 return (registry &&
4407 (registry[name] ||
4408 registry[camelize(name)] ||
4409 registry[capitalize(camelize(name))]));
4410}
4411
4412/**
4413 * Actual implementation
4414 */
4415function renderList(source, renderItem, cache, index) {
4416 let ret;
4417 const cached = (cache && cache[index]);
4418 if (isArray(source) || isString(source)) {
4419 ret = new Array(source.length);
4420 for (let i = 0, l = source.length; i < l; i++) {
4421 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
4422 }
4423 }
4424 else if (typeof source === 'number') {
4425 if (!Number.isInteger(source)) {
4426 warn$1(`The v-for range expect an integer value but got ${source}.`);
4427 }
4428 ret = new Array(source);
4429 for (let i = 0; i < source; i++) {
4430 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
4431 }
4432 }
4433 else if (isObject(source)) {
4434 if (source[Symbol.iterator]) {
4435 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
4436 }
4437 else {
4438 const keys = Object.keys(source);
4439 ret = new Array(keys.length);
4440 for (let i = 0, l = keys.length; i < l; i++) {
4441 const key = keys[i];
4442 ret[i] = renderItem(source[key], key, i, cached && cached[i]);
4443 }
4444 }
4445 }
4446 else {
4447 ret = [];
4448 }
4449 if (cache) {
4450 cache[index] = ret;
4451 }
4452 return ret;
4453}
4454
4455/**
4456 * Compiler runtime helper for creating dynamic slots object
4457 * @private
4458 */
4459function createSlots(slots, dynamicSlots) {
4460 for (let i = 0; i < dynamicSlots.length; i++) {
4461 const slot = dynamicSlots[i];
4462 // array of dynamic slot generated by <template v-for="..." #[...]>
4463 if (isArray(slot)) {
4464 for (let j = 0; j < slot.length; j++) {
4465 slots[slot[j].name] = slot[j].fn;
4466 }
4467 }
4468 else if (slot) {
4469 // conditional single slot generated by <template v-if="..." #foo>
4470 slots[slot.name] = slot.fn;
4471 }
4472 }
4473 return slots;
4474}
4475
4476/**
4477 * Compiler runtime helper for rendering `<slot/>`
4478 * @private
4479 */
4480function renderSlot(slots, name, props = {},
4481// this is not a user-facing function, so the fallback is always generated by
4482// the compiler and guaranteed to be a function returning an array
4483fallback, noSlotted) {
4484 if (currentRenderingInstance.isCE ||
4485 (currentRenderingInstance.parent &&
4486 isAsyncWrapper(currentRenderingInstance.parent) &&
4487 currentRenderingInstance.parent.isCE)) {
4488 return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback());
4489 }
4490 let slot = slots[name];
4491 if (slot && slot.length > 1) {
4492 warn$1(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
4493 `function. You need to mark this component with $dynamic-slots in the ` +
4494 `parent template.`);
4495 slot = () => [];
4496 }
4497 // a compiled slot disables block tracking by default to avoid manual
4498 // invocation interfering with template-based block tracking, but in
4499 // `renderSlot` we can be sure that it's template-based so we can force
4500 // enable it.
4501 if (slot && slot._c) {
4502 slot._d = false;
4503 }
4504 openBlock();
4505 const validSlotContent = slot && ensureValidVNode(slot(props));
4506 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
4507 ? 64 /* STABLE_FRAGMENT */
4508 : -2 /* BAIL */);
4509 if (!noSlotted && rendered.scopeId) {
4510 rendered.slotScopeIds = [rendered.scopeId + '-s'];
4511 }
4512 if (slot && slot._c) {
4513 slot._d = true;
4514 }
4515 return rendered;
4516}
4517function ensureValidVNode(vnodes) {
4518 return vnodes.some(child => {
4519 if (!isVNode(child))
4520 return true;
4521 if (child.type === Comment)
4522 return false;
4523 if (child.type === Fragment &&
4524 !ensureValidVNode(child.children))
4525 return false;
4526 return true;
4527 })
4528 ? vnodes
4529 : null;
4530}
4531
4532/**
4533 * For prefixing keys in v-on="obj" with "on"
4534 * @private
4535 */
4536function toHandlers(obj) {
4537 const ret = {};
4538 if (!isObject(obj)) {
4539 warn$1(`v-on with no argument expects an object value.`);
4540 return ret;
4541 }
4542 for (const key in obj) {
4543 ret[toHandlerKey(key)] = obj[key];
4544 }
4545 return ret;
4546}
4547
4548/**
4549 * #2437 In Vue 3, functional components do not have a public instance proxy but
4550 * they exist in the internal parent chain. For code that relies on traversing
4551 * public $parent chains, skip functional ones and go to the parent instead.
4552 */
4553const getPublicInstance = (i) => {
4554 if (!i)
4555 return null;
4556 if (isStatefulComponent(i))
4557 return getExposeProxy(i) || i.proxy;
4558 return getPublicInstance(i.parent);
4559};
4560const publicPropertiesMap =
4561// Move PURE marker to new line to workaround compiler discarding it
4562// due to type annotation
4563/*#__PURE__*/ extend(Object.create(null), {
4564 $: i => i,
4565 $el: i => i.vnode.el,
4566 $data: i => i.data,
4567 $props: i => (shallowReadonly(i.props) ),
4568 $attrs: i => (shallowReadonly(i.attrs) ),
4569 $slots: i => (shallowReadonly(i.slots) ),
4570 $refs: i => (shallowReadonly(i.refs) ),
4571 $parent: i => getPublicInstance(i.parent),
4572 $root: i => getPublicInstance(i.root),
4573 $emit: i => i.emit,
4574 $options: i => (resolveMergedOptions(i) ),
4575 $forceUpdate: i => i.f || (i.f = () => queueJob(i.update)),
4576 $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)),
4577 $watch: i => (instanceWatch.bind(i) )
4578});
4579const isReservedPrefix = (key) => key === '_' || key === '$';
4580const PublicInstanceProxyHandlers = {
4581 get({ _: instance }, key) {
4582 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
4583 // for internal formatters to know that this is a Vue instance
4584 if (key === '__isVue') {
4585 return true;
4586 }
4587 // prioritize <script setup> bindings during dev.
4588 // this allows even properties that start with _ or $ to be used - so that
4589 // it aligns with the production behavior where the render fn is inlined and
4590 // indeed has access to all declared variables.
4591 if (setupState !== EMPTY_OBJ &&
4592 setupState.__isScriptSetup &&
4593 hasOwn(setupState, key)) {
4594 return setupState[key];
4595 }
4596 // data / props / ctx
4597 // This getter gets called for every property access on the render context
4598 // during render and is a major hotspot. The most expensive part of this
4599 // is the multiple hasOwn() calls. It's much faster to do a simple property
4600 // access on a plain object, so we use an accessCache object (with null
4601 // prototype) to memoize what access type a key corresponds to.
4602 let normalizedProps;
4603 if (key[0] !== '$') {
4604 const n = accessCache[key];
4605 if (n !== undefined) {
4606 switch (n) {
4607 case 1 /* SETUP */:
4608 return setupState[key];
4609 case 2 /* DATA */:
4610 return data[key];
4611 case 4 /* CONTEXT */:
4612 return ctx[key];
4613 case 3 /* PROPS */:
4614 return props[key];
4615 // default: just fallthrough
4616 }
4617 }
4618 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
4619 accessCache[key] = 1 /* SETUP */;
4620 return setupState[key];
4621 }
4622 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4623 accessCache[key] = 2 /* DATA */;
4624 return data[key];
4625 }
4626 else if (
4627 // only cache other properties when instance has declared (thus stable)
4628 // props
4629 (normalizedProps = instance.propsOptions[0]) &&
4630 hasOwn(normalizedProps, key)) {
4631 accessCache[key] = 3 /* PROPS */;
4632 return props[key];
4633 }
4634 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4635 accessCache[key] = 4 /* CONTEXT */;
4636 return ctx[key];
4637 }
4638 else if (shouldCacheAccess) {
4639 accessCache[key] = 0 /* OTHER */;
4640 }
4641 }
4642 const publicGetter = publicPropertiesMap[key];
4643 let cssModule, globalProperties;
4644 // public $xxx properties
4645 if (publicGetter) {
4646 if (key === '$attrs') {
4647 track(instance, "get" /* GET */, key);
4648 markAttrsAccessed();
4649 }
4650 return publicGetter(instance);
4651 }
4652 else if (
4653 // css module (injected by vue-loader)
4654 (cssModule = type.__cssModules) &&
4655 (cssModule = cssModule[key])) {
4656 return cssModule;
4657 }
4658 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4659 // user may set custom properties to `this` that start with `$`
4660 accessCache[key] = 4 /* CONTEXT */;
4661 return ctx[key];
4662 }
4663 else if (
4664 // global properties
4665 ((globalProperties = appContext.config.globalProperties),
4666 hasOwn(globalProperties, key))) {
4667 {
4668 return globalProperties[key];
4669 }
4670 }
4671 else if (currentRenderingInstance &&
4672 (!isString(key) ||
4673 // #1091 avoid internal isRef/isVNode checks on component instance leading
4674 // to infinite warning loop
4675 key.indexOf('__v') !== 0)) {
4676 if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {
4677 warn$1(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
4678 `character ("$" or "_") and is not proxied on the render context.`);
4679 }
4680 else if (instance === currentRenderingInstance) {
4681 warn$1(`Property ${JSON.stringify(key)} was accessed during render ` +
4682 `but is not defined on instance.`);
4683 }
4684 }
4685 },
4686 set({ _: instance }, key, value) {
4687 const { data, setupState, ctx } = instance;
4688 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
4689 setupState[key] = value;
4690 return true;
4691 }
4692 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4693 data[key] = value;
4694 return true;
4695 }
4696 else if (hasOwn(instance.props, key)) {
4697 warn$1(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
4698 return false;
4699 }
4700 if (key[0] === '$' && key.slice(1) in instance) {
4701 warn$1(`Attempting to mutate public property "${key}". ` +
4702 `Properties starting with $ are reserved and readonly.`, instance);
4703 return false;
4704 }
4705 else {
4706 if (key in instance.appContext.config.globalProperties) {
4707 Object.defineProperty(ctx, key, {
4708 enumerable: true,
4709 configurable: true,
4710 value
4711 });
4712 }
4713 else {
4714 ctx[key] = value;
4715 }
4716 }
4717 return true;
4718 },
4719 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
4720 let normalizedProps;
4721 return (!!accessCache[key] ||
4722 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
4723 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
4724 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
4725 hasOwn(ctx, key) ||
4726 hasOwn(publicPropertiesMap, key) ||
4727 hasOwn(appContext.config.globalProperties, key));
4728 },
4729 defineProperty(target, key, descriptor) {
4730 if (descriptor.get != null) {
4731 // invalidate key cache of a getter based property #5417
4732 target._.accessCache[key] = 0;
4733 }
4734 else if (hasOwn(descriptor, 'value')) {
4735 this.set(target, key, descriptor.value, null);
4736 }
4737 return Reflect.defineProperty(target, key, descriptor);
4738 }
4739};
4740{
4741 PublicInstanceProxyHandlers.ownKeys = (target) => {
4742 warn$1(`Avoid app logic that relies on enumerating keys on a component instance. ` +
4743 `The keys will be empty in production mode to avoid performance overhead.`);
4744 return Reflect.ownKeys(target);
4745 };
4746}
4747const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, {
4748 get(target, key) {
4749 // fast path for unscopables when using `with` block
4750 if (key === Symbol.unscopables) {
4751 return;
4752 }
4753 return PublicInstanceProxyHandlers.get(target, key, target);
4754 },
4755 has(_, key) {
4756 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
4757 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
4758 warn$1(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
4759 }
4760 return has;
4761 }
4762});
4763// dev only
4764// In dev mode, the proxy target exposes the same properties as seen on `this`
4765// for easier console inspection. In prod mode it will be an empty object so
4766// these properties definitions can be skipped.
4767function createDevRenderContext(instance) {
4768 const target = {};
4769 // expose internal instance for proxy handlers
4770 Object.defineProperty(target, `_`, {
4771 configurable: true,
4772 enumerable: false,
4773 get: () => instance
4774 });
4775 // expose public properties
4776 Object.keys(publicPropertiesMap).forEach(key => {
4777 Object.defineProperty(target, key, {
4778 configurable: true,
4779 enumerable: false,
4780 get: () => publicPropertiesMap[key](instance),
4781 // intercepted by the proxy so no need for implementation,
4782 // but needed to prevent set errors
4783 set: NOOP
4784 });
4785 });
4786 return target;
4787}
4788// dev only
4789function exposePropsOnRenderContext(instance) {
4790 const { ctx, propsOptions: [propsOptions] } = instance;
4791 if (propsOptions) {
4792 Object.keys(propsOptions).forEach(key => {
4793 Object.defineProperty(ctx, key, {
4794 enumerable: true,
4795 configurable: true,
4796 get: () => instance.props[key],
4797 set: NOOP
4798 });
4799 });
4800 }
4801}
4802// dev only
4803function exposeSetupStateOnRenderContext(instance) {
4804 const { ctx, setupState } = instance;
4805 Object.keys(toRaw(setupState)).forEach(key => {
4806 if (!setupState.__isScriptSetup) {
4807 if (isReservedPrefix(key[0])) {
4808 warn$1(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
4809 `which are reserved prefixes for Vue internals.`);
4810 return;
4811 }
4812 Object.defineProperty(ctx, key, {
4813 enumerable: true,
4814 configurable: true,
4815 get: () => setupState[key],
4816 set: NOOP
4817 });
4818 }
4819 });
4820}
4821
4822function createDuplicateChecker() {
4823 const cache = Object.create(null);
4824 return (type, key) => {
4825 if (cache[key]) {
4826 warn$1(`${type} property "${key}" is already defined in ${cache[key]}.`);
4827 }
4828 else {
4829 cache[key] = type;
4830 }
4831 };
4832}
4833let shouldCacheAccess = true;
4834function applyOptions(instance) {
4835 const options = resolveMergedOptions(instance);
4836 const publicThis = instance.proxy;
4837 const ctx = instance.ctx;
4838 // do not cache property access on public proxy during state initialization
4839 shouldCacheAccess = false;
4840 // call beforeCreate first before accessing other options since
4841 // the hook may mutate resolved options (#2791)
4842 if (options.beforeCreate) {
4843 callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
4844 }
4845 const {
4846 // state
4847 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
4848 // lifecycle
4849 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
4850 // public API
4851 expose, inheritAttrs,
4852 // assets
4853 components, directives, filters } = options;
4854 const checkDuplicateProperties = createDuplicateChecker() ;
4855 {
4856 const [propsOptions] = instance.propsOptions;
4857 if (propsOptions) {
4858 for (const key in propsOptions) {
4859 checkDuplicateProperties("Props" /* PROPS */, key);
4860 }
4861 }
4862 }
4863 // options initialization order (to be consistent with Vue 2):
4864 // - props (already done outside of this function)
4865 // - inject
4866 // - methods
4867 // - data (deferred since it relies on `this` access)
4868 // - computed
4869 // - watch (deferred since it relies on `this` access)
4870 if (injectOptions) {
4871 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
4872 }
4873 if (methods) {
4874 for (const key in methods) {
4875 const methodHandler = methods[key];
4876 if (isFunction(methodHandler)) {
4877 // In dev mode, we use the `createRenderContext` function to define
4878 // methods to the proxy target, and those are read-only but
4879 // reconfigurable, so it needs to be redefined here
4880 {
4881 Object.defineProperty(ctx, key, {
4882 value: methodHandler.bind(publicThis),
4883 configurable: true,
4884 enumerable: true,
4885 writable: true
4886 });
4887 }
4888 {
4889 checkDuplicateProperties("Methods" /* METHODS */, key);
4890 }
4891 }
4892 else {
4893 warn$1(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
4894 `Did you reference the function correctly?`);
4895 }
4896 }
4897 }
4898 if (dataOptions) {
4899 if (!isFunction(dataOptions)) {
4900 warn$1(`The data option must be a function. ` +
4901 `Plain object usage is no longer supported.`);
4902 }
4903 const data = dataOptions.call(publicThis, publicThis);
4904 if (isPromise(data)) {
4905 warn$1(`data() returned a Promise - note data() cannot be async; If you ` +
4906 `intend to perform data fetching before component renders, use ` +
4907 `async setup() + <Suspense>.`);
4908 }
4909 if (!isObject(data)) {
4910 warn$1(`data() should return an object.`);
4911 }
4912 else {
4913 instance.data = reactive(data);
4914 {
4915 for (const key in data) {
4916 checkDuplicateProperties("Data" /* DATA */, key);
4917 // expose data on ctx during dev
4918 if (!isReservedPrefix(key[0])) {
4919 Object.defineProperty(ctx, key, {
4920 configurable: true,
4921 enumerable: true,
4922 get: () => data[key],
4923 set: NOOP
4924 });
4925 }
4926 }
4927 }
4928 }
4929 }
4930 // state initialization complete at this point - start caching access
4931 shouldCacheAccess = true;
4932 if (computedOptions) {
4933 for (const key in computedOptions) {
4934 const opt = computedOptions[key];
4935 const get = isFunction(opt)
4936 ? opt.bind(publicThis, publicThis)
4937 : isFunction(opt.get)
4938 ? opt.get.bind(publicThis, publicThis)
4939 : NOOP;
4940 if (get === NOOP) {
4941 warn$1(`Computed property "${key}" has no getter.`);
4942 }
4943 const set = !isFunction(opt) && isFunction(opt.set)
4944 ? opt.set.bind(publicThis)
4945 : () => {
4946 warn$1(`Write operation failed: computed property "${key}" is readonly.`);
4947 }
4948 ;
4949 const c = computed$1({
4950 get,
4951 set
4952 });
4953 Object.defineProperty(ctx, key, {
4954 enumerable: true,
4955 configurable: true,
4956 get: () => c.value,
4957 set: v => (c.value = v)
4958 });
4959 {
4960 checkDuplicateProperties("Computed" /* COMPUTED */, key);
4961 }
4962 }
4963 }
4964 if (watchOptions) {
4965 for (const key in watchOptions) {
4966 createWatcher(watchOptions[key], ctx, publicThis, key);
4967 }
4968 }
4969 if (provideOptions) {
4970 const provides = isFunction(provideOptions)
4971 ? provideOptions.call(publicThis)
4972 : provideOptions;
4973 Reflect.ownKeys(provides).forEach(key => {
4974 provide(key, provides[key]);
4975 });
4976 }
4977 if (created) {
4978 callHook(created, instance, "c" /* CREATED */);
4979 }
4980 function registerLifecycleHook(register, hook) {
4981 if (isArray(hook)) {
4982 hook.forEach(_hook => register(_hook.bind(publicThis)));
4983 }
4984 else if (hook) {
4985 register(hook.bind(publicThis));
4986 }
4987 }
4988 registerLifecycleHook(onBeforeMount, beforeMount);
4989 registerLifecycleHook(onMounted, mounted);
4990 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
4991 registerLifecycleHook(onUpdated, updated);
4992 registerLifecycleHook(onActivated, activated);
4993 registerLifecycleHook(onDeactivated, deactivated);
4994 registerLifecycleHook(onErrorCaptured, errorCaptured);
4995 registerLifecycleHook(onRenderTracked, renderTracked);
4996 registerLifecycleHook(onRenderTriggered, renderTriggered);
4997 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
4998 registerLifecycleHook(onUnmounted, unmounted);
4999 registerLifecycleHook(onServerPrefetch, serverPrefetch);
5000 if (isArray(expose)) {
5001 if (expose.length) {
5002 const exposed = instance.exposed || (instance.exposed = {});
5003 expose.forEach(key => {
5004 Object.defineProperty(exposed, key, {
5005 get: () => publicThis[key],
5006 set: val => (publicThis[key] = val)
5007 });
5008 });
5009 }
5010 else if (!instance.exposed) {
5011 instance.exposed = {};
5012 }
5013 }
5014 // options that are handled when creating the instance but also need to be
5015 // applied from mixins
5016 if (render && instance.render === NOOP) {
5017 instance.render = render;
5018 }
5019 if (inheritAttrs != null) {
5020 instance.inheritAttrs = inheritAttrs;
5021 }
5022 // asset options.
5023 if (components)
5024 instance.components = components;
5025 if (directives)
5026 instance.directives = directives;
5027}
5028function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
5029 if (isArray(injectOptions)) {
5030 injectOptions = normalizeInject(injectOptions);
5031 }
5032 for (const key in injectOptions) {
5033 const opt = injectOptions[key];
5034 let injected;
5035 if (isObject(opt)) {
5036 if ('default' in opt) {
5037 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
5038 }
5039 else {
5040 injected = inject(opt.from || key);
5041 }
5042 }
5043 else {
5044 injected = inject(opt);
5045 }
5046 if (isRef(injected)) {
5047 // TODO remove the check in 3.3
5048 if (unwrapRef) {
5049 Object.defineProperty(ctx, key, {
5050 enumerable: true,
5051 configurable: true,
5052 get: () => injected.value,
5053 set: v => (injected.value = v)
5054 });
5055 }
5056 else {
5057 {
5058 warn$1(`injected property "${key}" is a ref and will be auto-unwrapped ` +
5059 `and no longer needs \`.value\` in the next minor release. ` +
5060 `To opt-in to the new behavior now, ` +
5061 `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
5062 `temporary and will not be needed in the future.)`);
5063 }
5064 ctx[key] = injected;
5065 }
5066 }
5067 else {
5068 ctx[key] = injected;
5069 }
5070 {
5071 checkDuplicateProperties("Inject" /* INJECT */, key);
5072 }
5073 }
5074}
5075function callHook(hook, instance, type) {
5076 callWithAsyncErrorHandling(isArray(hook)
5077 ? hook.map(h => h.bind(instance.proxy))
5078 : hook.bind(instance.proxy), instance, type);
5079}
5080function createWatcher(raw, ctx, publicThis, key) {
5081 const getter = key.includes('.')
5082 ? createPathGetter(publicThis, key)
5083 : () => publicThis[key];
5084 if (isString(raw)) {
5085 const handler = ctx[raw];
5086 if (isFunction(handler)) {
5087 watch(getter, handler);
5088 }
5089 else {
5090 warn$1(`Invalid watch handler specified by key "${raw}"`, handler);
5091 }
5092 }
5093 else if (isFunction(raw)) {
5094 watch(getter, raw.bind(publicThis));
5095 }
5096 else if (isObject(raw)) {
5097 if (isArray(raw)) {
5098 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
5099 }
5100 else {
5101 const handler = isFunction(raw.handler)
5102 ? raw.handler.bind(publicThis)
5103 : ctx[raw.handler];
5104 if (isFunction(handler)) {
5105 watch(getter, handler, raw);
5106 }
5107 else {
5108 warn$1(`Invalid watch handler specified by key "${raw.handler}"`, handler);
5109 }
5110 }
5111 }
5112 else {
5113 warn$1(`Invalid watch option: "${key}"`, raw);
5114 }
5115}
5116/**
5117 * Resolve merged options and cache it on the component.
5118 * This is done only once per-component since the merging does not involve
5119 * instances.
5120 */
5121function resolveMergedOptions(instance) {
5122 const base = instance.type;
5123 const { mixins, extends: extendsOptions } = base;
5124 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
5125 const cached = cache.get(base);
5126 let resolved;
5127 if (cached) {
5128 resolved = cached;
5129 }
5130 else if (!globalMixins.length && !mixins && !extendsOptions) {
5131 {
5132 resolved = base;
5133 }
5134 }
5135 else {
5136 resolved = {};
5137 if (globalMixins.length) {
5138 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
5139 }
5140 mergeOptions(resolved, base, optionMergeStrategies);
5141 }
5142 cache.set(base, resolved);
5143 return resolved;
5144}
5145function mergeOptions(to, from, strats, asMixin = false) {
5146 const { mixins, extends: extendsOptions } = from;
5147 if (extendsOptions) {
5148 mergeOptions(to, extendsOptions, strats, true);
5149 }
5150 if (mixins) {
5151 mixins.forEach((m) => mergeOptions(to, m, strats, true));
5152 }
5153 for (const key in from) {
5154 if (asMixin && key === 'expose') {
5155 warn$1(`"expose" option is ignored when declared in mixins or extends. ` +
5156 `It should only be declared in the base component itself.`);
5157 }
5158 else {
5159 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
5160 to[key] = strat ? strat(to[key], from[key]) : from[key];
5161 }
5162 }
5163 return to;
5164}
5165const internalOptionMergeStrats = {
5166 data: mergeDataFn,
5167 props: mergeObjectOptions,
5168 emits: mergeObjectOptions,
5169 // objects
5170 methods: mergeObjectOptions,
5171 computed: mergeObjectOptions,
5172 // lifecycle
5173 beforeCreate: mergeAsArray,
5174 created: mergeAsArray,
5175 beforeMount: mergeAsArray,
5176 mounted: mergeAsArray,
5177 beforeUpdate: mergeAsArray,
5178 updated: mergeAsArray,
5179 beforeDestroy: mergeAsArray,
5180 beforeUnmount: mergeAsArray,
5181 destroyed: mergeAsArray,
5182 unmounted: mergeAsArray,
5183 activated: mergeAsArray,
5184 deactivated: mergeAsArray,
5185 errorCaptured: mergeAsArray,
5186 serverPrefetch: mergeAsArray,
5187 // assets
5188 components: mergeObjectOptions,
5189 directives: mergeObjectOptions,
5190 // watch
5191 watch: mergeWatchOptions,
5192 // provide / inject
5193 provide: mergeDataFn,
5194 inject: mergeInject
5195};
5196function mergeDataFn(to, from) {
5197 if (!from) {
5198 return to;
5199 }
5200 if (!to) {
5201 return from;
5202 }
5203 return function mergedDataFn() {
5204 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
5205 };
5206}
5207function mergeInject(to, from) {
5208 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
5209}
5210function normalizeInject(raw) {
5211 if (isArray(raw)) {
5212 const res = {};
5213 for (let i = 0; i < raw.length; i++) {
5214 res[raw[i]] = raw[i];
5215 }
5216 return res;
5217 }
5218 return raw;
5219}
5220function mergeAsArray(to, from) {
5221 return to ? [...new Set([].concat(to, from))] : from;
5222}
5223function mergeObjectOptions(to, from) {
5224 return to ? extend(extend(Object.create(null), to), from) : from;
5225}
5226function mergeWatchOptions(to, from) {
5227 if (!to)
5228 return from;
5229 if (!from)
5230 return to;
5231 const merged = extend(Object.create(null), to);
5232 for (const key in from) {
5233 merged[key] = mergeAsArray(to[key], from[key]);
5234 }
5235 return merged;
5236}
5237
5238function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
5239isSSR = false) {
5240 const props = {};
5241 const attrs = {};
5242 def(attrs, InternalObjectKey, 1);
5243 instance.propsDefaults = Object.create(null);
5244 setFullProps(instance, rawProps, props, attrs);
5245 // ensure all declared prop keys are present
5246 for (const key in instance.propsOptions[0]) {
5247 if (!(key in props)) {
5248 props[key] = undefined;
5249 }
5250 }
5251 // validation
5252 {
5253 validateProps(rawProps || {}, props, instance);
5254 }
5255 if (isStateful) {
5256 // stateful
5257 instance.props = isSSR ? props : shallowReactive(props);
5258 }
5259 else {
5260 if (!instance.type.props) {
5261 // functional w/ optional props, props === attrs
5262 instance.props = attrs;
5263 }
5264 else {
5265 // functional w/ declared props
5266 instance.props = props;
5267 }
5268 }
5269 instance.attrs = attrs;
5270}
5271function updateProps(instance, rawProps, rawPrevProps, optimized) {
5272 const { props, attrs, vnode: { patchFlag } } = instance;
5273 const rawCurrentProps = toRaw(props);
5274 const [options] = instance.propsOptions;
5275 let hasAttrsChanged = false;
5276 if (
5277 // always force full diff in dev
5278 // - #1942 if hmr is enabled with sfc component
5279 // - vite#872 non-sfc component used by sfc component
5280 !((instance.type.__hmrId ||
5281 (instance.parent && instance.parent.type.__hmrId))) &&
5282 (optimized || patchFlag > 0) &&
5283 !(patchFlag & 16 /* FULL_PROPS */)) {
5284 if (patchFlag & 8 /* PROPS */) {
5285 // Compiler-generated props & no keys change, just set the updated
5286 // the props.
5287 const propsToUpdate = instance.vnode.dynamicProps;
5288 for (let i = 0; i < propsToUpdate.length; i++) {
5289 let key = propsToUpdate[i];
5290 // skip if the prop key is a declared emit event listener
5291 if (isEmitListener(instance.emitsOptions, key)) {
5292 continue;
5293 }
5294 // PROPS flag guarantees rawProps to be non-null
5295 const value = rawProps[key];
5296 if (options) {
5297 // attr / props separation was done on init and will be consistent
5298 // in this code path, so just check if attrs have it.
5299 if (hasOwn(attrs, key)) {
5300 if (value !== attrs[key]) {
5301 attrs[key] = value;
5302 hasAttrsChanged = true;
5303 }
5304 }
5305 else {
5306 const camelizedKey = camelize(key);
5307 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
5308 }
5309 }
5310 else {
5311 if (value !== attrs[key]) {
5312 attrs[key] = value;
5313 hasAttrsChanged = true;
5314 }
5315 }
5316 }
5317 }
5318 }
5319 else {
5320 // full props update.
5321 if (setFullProps(instance, rawProps, props, attrs)) {
5322 hasAttrsChanged = true;
5323 }
5324 // in case of dynamic props, check if we need to delete keys from
5325 // the props object
5326 let kebabKey;
5327 for (const key in rawCurrentProps) {
5328 if (!rawProps ||
5329 // for camelCase
5330 (!hasOwn(rawProps, key) &&
5331 // it's possible the original props was passed in as kebab-case
5332 // and converted to camelCase (#955)
5333 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
5334 if (options) {
5335 if (rawPrevProps &&
5336 // for camelCase
5337 (rawPrevProps[key] !== undefined ||
5338 // for kebab-case
5339 rawPrevProps[kebabKey] !== undefined)) {
5340 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
5341 }
5342 }
5343 else {
5344 delete props[key];
5345 }
5346 }
5347 }
5348 // in the case of functional component w/o props declaration, props and
5349 // attrs point to the same object so it should already have been updated.
5350 if (attrs !== rawCurrentProps) {
5351 for (const key in attrs) {
5352 if (!rawProps ||
5353 (!hasOwn(rawProps, key) &&
5354 (!false ))) {
5355 delete attrs[key];
5356 hasAttrsChanged = true;
5357 }
5358 }
5359 }
5360 }
5361 // trigger updates for $attrs in case it's used in component slots
5362 if (hasAttrsChanged) {
5363 trigger(instance, "set" /* SET */, '$attrs');
5364 }
5365 {
5366 validateProps(rawProps || {}, props, instance);
5367 }
5368}
5369function setFullProps(instance, rawProps, props, attrs) {
5370 const [options, needCastKeys] = instance.propsOptions;
5371 let hasAttrsChanged = false;
5372 let rawCastValues;
5373 if (rawProps) {
5374 for (let key in rawProps) {
5375 // key, ref are reserved and never passed down
5376 if (isReservedProp(key)) {
5377 continue;
5378 }
5379 const value = rawProps[key];
5380 // prop option names are camelized during normalization, so to support
5381 // kebab -> camel conversion here we need to camelize the key.
5382 let camelKey;
5383 if (options && hasOwn(options, (camelKey = camelize(key)))) {
5384 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
5385 props[camelKey] = value;
5386 }
5387 else {
5388 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
5389 }
5390 }
5391 else if (!isEmitListener(instance.emitsOptions, key)) {
5392 if (!(key in attrs) || value !== attrs[key]) {
5393 attrs[key] = value;
5394 hasAttrsChanged = true;
5395 }
5396 }
5397 }
5398 }
5399 if (needCastKeys) {
5400 const rawCurrentProps = toRaw(props);
5401 const castValues = rawCastValues || EMPTY_OBJ;
5402 for (let i = 0; i < needCastKeys.length; i++) {
5403 const key = needCastKeys[i];
5404 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
5405 }
5406 }
5407 return hasAttrsChanged;
5408}
5409function resolvePropValue(options, props, key, value, instance, isAbsent) {
5410 const opt = options[key];
5411 if (opt != null) {
5412 const hasDefault = hasOwn(opt, 'default');
5413 // default values
5414 if (hasDefault && value === undefined) {
5415 const defaultValue = opt.default;
5416 if (opt.type !== Function && isFunction(defaultValue)) {
5417 const { propsDefaults } = instance;
5418 if (key in propsDefaults) {
5419 value = propsDefaults[key];
5420 }
5421 else {
5422 setCurrentInstance(instance);
5423 value = propsDefaults[key] = defaultValue.call(null, props);
5424 unsetCurrentInstance();
5425 }
5426 }
5427 else {
5428 value = defaultValue;
5429 }
5430 }
5431 // boolean casting
5432 if (opt[0 /* shouldCast */]) {
5433 if (isAbsent && !hasDefault) {
5434 value = false;
5435 }
5436 else if (opt[1 /* shouldCastTrue */] &&
5437 (value === '' || value === hyphenate(key))) {
5438 value = true;
5439 }
5440 }
5441 }
5442 return value;
5443}
5444function normalizePropsOptions(comp, appContext, asMixin = false) {
5445 const cache = appContext.propsCache;
5446 const cached = cache.get(comp);
5447 if (cached) {
5448 return cached;
5449 }
5450 const raw = comp.props;
5451 const normalized = {};
5452 const needCastKeys = [];
5453 // apply mixin/extends props
5454 let hasExtends = false;
5455 if (!isFunction(comp)) {
5456 const extendProps = (raw) => {
5457 hasExtends = true;
5458 const [props, keys] = normalizePropsOptions(raw, appContext, true);
5459 extend(normalized, props);
5460 if (keys)
5461 needCastKeys.push(...keys);
5462 };
5463 if (!asMixin && appContext.mixins.length) {
5464 appContext.mixins.forEach(extendProps);
5465 }
5466 if (comp.extends) {
5467 extendProps(comp.extends);
5468 }
5469 if (comp.mixins) {
5470 comp.mixins.forEach(extendProps);
5471 }
5472 }
5473 if (!raw && !hasExtends) {
5474 cache.set(comp, EMPTY_ARR);
5475 return EMPTY_ARR;
5476 }
5477 if (isArray(raw)) {
5478 for (let i = 0; i < raw.length; i++) {
5479 if (!isString(raw[i])) {
5480 warn$1(`props must be strings when using array syntax.`, raw[i]);
5481 }
5482 const normalizedKey = camelize(raw[i]);
5483 if (validatePropName(normalizedKey)) {
5484 normalized[normalizedKey] = EMPTY_OBJ;
5485 }
5486 }
5487 }
5488 else if (raw) {
5489 if (!isObject(raw)) {
5490 warn$1(`invalid props options`, raw);
5491 }
5492 for (const key in raw) {
5493 const normalizedKey = camelize(key);
5494 if (validatePropName(normalizedKey)) {
5495 const opt = raw[key];
5496 const prop = (normalized[normalizedKey] =
5497 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
5498 if (prop) {
5499 const booleanIndex = getTypeIndex(Boolean, prop.type);
5500 const stringIndex = getTypeIndex(String, prop.type);
5501 prop[0 /* shouldCast */] = booleanIndex > -1;
5502 prop[1 /* shouldCastTrue */] =
5503 stringIndex < 0 || booleanIndex < stringIndex;
5504 // if the prop needs boolean casting or default value
5505 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
5506 needCastKeys.push(normalizedKey);
5507 }
5508 }
5509 }
5510 }
5511 }
5512 const res = [normalized, needCastKeys];
5513 cache.set(comp, res);
5514 return res;
5515}
5516function validatePropName(key) {
5517 if (key[0] !== '$') {
5518 return true;
5519 }
5520 else {
5521 warn$1(`Invalid prop name: "${key}" is a reserved property.`);
5522 }
5523 return false;
5524}
5525// use function string name to check type constructors
5526// so that it works across vms / iframes.
5527function getType(ctor) {
5528 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
5529 return match ? match[1] : ctor === null ? 'null' : '';
5530}
5531function isSameType(a, b) {
5532 return getType(a) === getType(b);
5533}
5534function getTypeIndex(type, expectedTypes) {
5535 if (isArray(expectedTypes)) {
5536 return expectedTypes.findIndex(t => isSameType(t, type));
5537 }
5538 else if (isFunction(expectedTypes)) {
5539 return isSameType(expectedTypes, type) ? 0 : -1;
5540 }
5541 return -1;
5542}
5543/**
5544 * dev only
5545 */
5546function validateProps(rawProps, props, instance) {
5547 const resolvedValues = toRaw(props);
5548 const options = instance.propsOptions[0];
5549 for (const key in options) {
5550 let opt = options[key];
5551 if (opt == null)
5552 continue;
5553 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
5554 }
5555}
5556/**
5557 * dev only
5558 */
5559function validateProp(name, value, prop, isAbsent) {
5560 const { type, required, validator } = prop;
5561 // required!
5562 if (required && isAbsent) {
5563 warn$1('Missing required prop: "' + name + '"');
5564 return;
5565 }
5566 // missing but optional
5567 if (value == null && !prop.required) {
5568 return;
5569 }
5570 // type check
5571 if (type != null && type !== true) {
5572 let isValid = false;
5573 const types = isArray(type) ? type : [type];
5574 const expectedTypes = [];
5575 // value is valid as long as one of the specified types match
5576 for (let i = 0; i < types.length && !isValid; i++) {
5577 const { valid, expectedType } = assertType(value, types[i]);
5578 expectedTypes.push(expectedType || '');
5579 isValid = valid;
5580 }
5581 if (!isValid) {
5582 warn$1(getInvalidTypeMessage(name, value, expectedTypes));
5583 return;
5584 }
5585 }
5586 // custom validator
5587 if (validator && !validator(value)) {
5588 warn$1('Invalid prop: custom validator check failed for prop "' + name + '".');
5589 }
5590}
5591const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
5592/**
5593 * dev only
5594 */
5595function assertType(value, type) {
5596 let valid;
5597 const expectedType = getType(type);
5598 if (isSimpleType(expectedType)) {
5599 const t = typeof value;
5600 valid = t === expectedType.toLowerCase();
5601 // for primitive wrapper objects
5602 if (!valid && t === 'object') {
5603 valid = value instanceof type;
5604 }
5605 }
5606 else if (expectedType === 'Object') {
5607 valid = isObject(value);
5608 }
5609 else if (expectedType === 'Array') {
5610 valid = isArray(value);
5611 }
5612 else if (expectedType === 'null') {
5613 valid = value === null;
5614 }
5615 else {
5616 valid = value instanceof type;
5617 }
5618 return {
5619 valid,
5620 expectedType
5621 };
5622}
5623/**
5624 * dev only
5625 */
5626function getInvalidTypeMessage(name, value, expectedTypes) {
5627 let message = `Invalid prop: type check failed for prop "${name}".` +
5628 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
5629 const expectedType = expectedTypes[0];
5630 const receivedType = toRawType(value);
5631 const expectedValue = styleValue(value, expectedType);
5632 const receivedValue = styleValue(value, receivedType);
5633 // check if we need to specify expected value
5634 if (expectedTypes.length === 1 &&
5635 isExplicable(expectedType) &&
5636 !isBoolean(expectedType, receivedType)) {
5637 message += ` with value ${expectedValue}`;
5638 }
5639 message += `, got ${receivedType} `;
5640 // check if we need to specify received value
5641 if (isExplicable(receivedType)) {
5642 message += `with value ${receivedValue}.`;
5643 }
5644 return message;
5645}
5646/**
5647 * dev only
5648 */
5649function styleValue(value, type) {
5650 if (type === 'String') {
5651 return `"${value}"`;
5652 }
5653 else if (type === 'Number') {
5654 return `${Number(value)}`;
5655 }
5656 else {
5657 return `${value}`;
5658 }
5659}
5660/**
5661 * dev only
5662 */
5663function isExplicable(type) {
5664 const explicitTypes = ['string', 'number', 'boolean'];
5665 return explicitTypes.some(elem => type.toLowerCase() === elem);
5666}
5667/**
5668 * dev only
5669 */
5670function isBoolean(...args) {
5671 return args.some(elem => elem.toLowerCase() === 'boolean');
5672}
5673
5674const isInternalKey = (key) => key[0] === '_' || key === '$stable';
5675const normalizeSlotValue = (value) => isArray(value)
5676 ? value.map(normalizeVNode)
5677 : [normalizeVNode(value)];
5678const normalizeSlot = (key, rawSlot, ctx) => {
5679 if (rawSlot._n) {
5680 // already normalized - #5353
5681 return rawSlot;
5682 }
5683 const normalized = withCtx((...args) => {
5684 if (currentInstance) {
5685 warn$1(`Slot "${key}" invoked outside of the render function: ` +
5686 `this will not track dependencies used in the slot. ` +
5687 `Invoke the slot function inside the render function instead.`);
5688 }
5689 return normalizeSlotValue(rawSlot(...args));
5690 }, ctx);
5691 normalized._c = false;
5692 return normalized;
5693};
5694const normalizeObjectSlots = (rawSlots, slots, instance) => {
5695 const ctx = rawSlots._ctx;
5696 for (const key in rawSlots) {
5697 if (isInternalKey(key))
5698 continue;
5699 const value = rawSlots[key];
5700 if (isFunction(value)) {
5701 slots[key] = normalizeSlot(key, value, ctx);
5702 }
5703 else if (value != null) {
5704 {
5705 warn$1(`Non-function value encountered for slot "${key}". ` +
5706 `Prefer function slots for better performance.`);
5707 }
5708 const normalized = normalizeSlotValue(value);
5709 slots[key] = () => normalized;
5710 }
5711 }
5712};
5713const normalizeVNodeSlots = (instance, children) => {
5714 if (!isKeepAlive(instance.vnode) &&
5715 !(false )) {
5716 warn$1(`Non-function value encountered for default slot. ` +
5717 `Prefer function slots for better performance.`);
5718 }
5719 const normalized = normalizeSlotValue(children);
5720 instance.slots.default = () => normalized;
5721};
5722const initSlots = (instance, children) => {
5723 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5724 const type = children._;
5725 if (type) {
5726 // users can get the shallow readonly version of the slots object through `this.$slots`,
5727 // we should avoid the proxy object polluting the slots of the internal instance
5728 instance.slots = toRaw(children);
5729 // make compiler marker non-enumerable
5730 def(children, '_', type);
5731 }
5732 else {
5733 normalizeObjectSlots(children, (instance.slots = {}));
5734 }
5735 }
5736 else {
5737 instance.slots = {};
5738 if (children) {
5739 normalizeVNodeSlots(instance, children);
5740 }
5741 }
5742 def(instance.slots, InternalObjectKey, 1);
5743};
5744const updateSlots = (instance, children, optimized) => {
5745 const { vnode, slots } = instance;
5746 let needDeletionCheck = true;
5747 let deletionComparisonTarget = EMPTY_OBJ;
5748 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5749 const type = children._;
5750 if (type) {
5751 // compiled slots.
5752 if (isHmrUpdating) {
5753 // Parent was HMR updated so slot content may have changed.
5754 // force update slots and mark instance for hmr as well
5755 extend(slots, children);
5756 }
5757 else if (optimized && type === 1 /* STABLE */) {
5758 // compiled AND stable.
5759 // no need to update, and skip stale slots removal.
5760 needDeletionCheck = false;
5761 }
5762 else {
5763 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
5764 // normalization.
5765 extend(slots, children);
5766 // #2893
5767 // when rendering the optimized slots by manually written render function,
5768 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
5769 // i.e. let the `renderSlot` create the bailed Fragment
5770 if (!optimized && type === 1 /* STABLE */) {
5771 delete slots._;
5772 }
5773 }
5774 }
5775 else {
5776 needDeletionCheck = !children.$stable;
5777 normalizeObjectSlots(children, slots);
5778 }
5779 deletionComparisonTarget = children;
5780 }
5781 else if (children) {
5782 // non slot object children (direct value) passed to a component
5783 normalizeVNodeSlots(instance, children);
5784 deletionComparisonTarget = { default: 1 };
5785 }
5786 // delete stale slots
5787 if (needDeletionCheck) {
5788 for (const key in slots) {
5789 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
5790 delete slots[key];
5791 }
5792 }
5793 }
5794};
5795
5796function createAppContext() {
5797 return {
5798 app: null,
5799 config: {
5800 isNativeTag: NO,
5801 performance: false,
5802 globalProperties: {},
5803 optionMergeStrategies: {},
5804 errorHandler: undefined,
5805 warnHandler: undefined,
5806 compilerOptions: {}
5807 },
5808 mixins: [],
5809 components: {},
5810 directives: {},
5811 provides: Object.create(null),
5812 optionsCache: new WeakMap(),
5813 propsCache: new WeakMap(),
5814 emitsCache: new WeakMap()
5815 };
5816}
5817let uid = 0;
5818function createAppAPI(render, hydrate) {
5819 return function createApp(rootComponent, rootProps = null) {
5820 if (!isFunction(rootComponent)) {
5821 rootComponent = Object.assign({}, rootComponent);
5822 }
5823 if (rootProps != null && !isObject(rootProps)) {
5824 warn$1(`root props passed to app.mount() must be an object.`);
5825 rootProps = null;
5826 }
5827 const context = createAppContext();
5828 const installedPlugins = new Set();
5829 let isMounted = false;
5830 const app = (context.app = {
5831 _uid: uid++,
5832 _component: rootComponent,
5833 _props: rootProps,
5834 _container: null,
5835 _context: context,
5836 _instance: null,
5837 version,
5838 get config() {
5839 return context.config;
5840 },
5841 set config(v) {
5842 {
5843 warn$1(`app.config cannot be replaced. Modify individual options instead.`);
5844 }
5845 },
5846 use(plugin, ...options) {
5847 if (installedPlugins.has(plugin)) {
5848 warn$1(`Plugin has already been applied to target app.`);
5849 }
5850 else if (plugin && isFunction(plugin.install)) {
5851 installedPlugins.add(plugin);
5852 plugin.install(app, ...options);
5853 }
5854 else if (isFunction(plugin)) {
5855 installedPlugins.add(plugin);
5856 plugin(app, ...options);
5857 }
5858 else {
5859 warn$1(`A plugin must either be a function or an object with an "install" ` +
5860 `function.`);
5861 }
5862 return app;
5863 },
5864 mixin(mixin) {
5865 {
5866 if (!context.mixins.includes(mixin)) {
5867 context.mixins.push(mixin);
5868 }
5869 else {
5870 warn$1('Mixin has already been applied to target app' +
5871 (mixin.name ? `: ${mixin.name}` : ''));
5872 }
5873 }
5874 return app;
5875 },
5876 component(name, component) {
5877 {
5878 validateComponentName(name, context.config);
5879 }
5880 if (!component) {
5881 return context.components[name];
5882 }
5883 if (context.components[name]) {
5884 warn$1(`Component "${name}" has already been registered in target app.`);
5885 }
5886 context.components[name] = component;
5887 return app;
5888 },
5889 directive(name, directive) {
5890 {
5891 validateDirectiveName(name);
5892 }
5893 if (!directive) {
5894 return context.directives[name];
5895 }
5896 if (context.directives[name]) {
5897 warn$1(`Directive "${name}" has already been registered in target app.`);
5898 }
5899 context.directives[name] = directive;
5900 return app;
5901 },
5902 mount(rootContainer, isHydrate, isSVG) {
5903 if (!isMounted) {
5904 // #5571
5905 if (rootContainer.__vue_app__) {
5906 warn$1(`There is already an app instance mounted on the host container.\n` +
5907 ` If you want to mount another app on the same host container,` +
5908 ` you need to unmount the previous app by calling \`app.unmount()\` first.`);
5909 }
5910 const vnode = createVNode(rootComponent, rootProps);
5911 // store app context on the root VNode.
5912 // this will be set on the root instance on initial mount.
5913 vnode.appContext = context;
5914 // HMR root reload
5915 {
5916 context.reload = () => {
5917 render(cloneVNode(vnode), rootContainer, isSVG);
5918 };
5919 }
5920 if (isHydrate && hydrate) {
5921 hydrate(vnode, rootContainer);
5922 }
5923 else {
5924 render(vnode, rootContainer, isSVG);
5925 }
5926 isMounted = true;
5927 app._container = rootContainer;
5928 rootContainer.__vue_app__ = app;
5929 {
5930 app._instance = vnode.component;
5931 devtoolsInitApp(app, version);
5932 }
5933 return getExposeProxy(vnode.component) || vnode.component.proxy;
5934 }
5935 else {
5936 warn$1(`App has already been mounted.\n` +
5937 `If you want to remount the same app, move your app creation logic ` +
5938 `into a factory function and create fresh app instances for each ` +
5939 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
5940 }
5941 },
5942 unmount() {
5943 if (isMounted) {
5944 render(null, app._container);
5945 {
5946 app._instance = null;
5947 devtoolsUnmountApp(app);
5948 }
5949 delete app._container.__vue_app__;
5950 }
5951 else {
5952 warn$1(`Cannot unmount an app that is not mounted.`);
5953 }
5954 },
5955 provide(key, value) {
5956 if (key in context.provides) {
5957 warn$1(`App already provides property with key "${String(key)}". ` +
5958 `It will be overwritten with the new value.`);
5959 }
5960 context.provides[key] = value;
5961 return app;
5962 }
5963 });
5964 return app;
5965 };
5966}
5967
5968/**
5969 * Function for handling a template ref
5970 */
5971function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
5972 if (isArray(rawRef)) {
5973 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
5974 return;
5975 }
5976 if (isAsyncWrapper(vnode) && !isUnmount) {
5977 // when mounting async components, nothing needs to be done,
5978 // because the template ref is forwarded to inner component
5979 return;
5980 }
5981 const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
5982 ? getExposeProxy(vnode.component) || vnode.component.proxy
5983 : vnode.el;
5984 const value = isUnmount ? null : refValue;
5985 const { i: owner, r: ref } = rawRef;
5986 if (!owner) {
5987 warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
5988 `A vnode with ref must be created inside the render function.`);
5989 return;
5990 }
5991 const oldRef = oldRawRef && oldRawRef.r;
5992 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
5993 const setupState = owner.setupState;
5994 // dynamic ref changed. unset old ref
5995 if (oldRef != null && oldRef !== ref) {
5996 if (isString(oldRef)) {
5997 refs[oldRef] = null;
5998 if (hasOwn(setupState, oldRef)) {
5999 setupState[oldRef] = null;
6000 }
6001 }
6002 else if (isRef(oldRef)) {
6003 oldRef.value = null;
6004 }
6005 }
6006 if (isFunction(ref)) {
6007 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6008 }
6009 else {
6010 const _isString = isString(ref);
6011 const _isRef = isRef(ref);
6012 if (_isString || _isRef) {
6013 const doSet = () => {
6014 if (rawRef.f) {
6015 const existing = _isString ? refs[ref] : ref.value;
6016 if (isUnmount) {
6017 isArray(existing) && remove(existing, refValue);
6018 }
6019 else {
6020 if (!isArray(existing)) {
6021 if (_isString) {
6022 refs[ref] = [refValue];
6023 if (hasOwn(setupState, ref)) {
6024 setupState[ref] = refs[ref];
6025 }
6026 }
6027 else {
6028 ref.value = [refValue];
6029 if (rawRef.k)
6030 refs[rawRef.k] = ref.value;
6031 }
6032 }
6033 else if (!existing.includes(refValue)) {
6034 existing.push(refValue);
6035 }
6036 }
6037 }
6038 else if (_isString) {
6039 refs[ref] = value;
6040 if (hasOwn(setupState, ref)) {
6041 setupState[ref] = value;
6042 }
6043 }
6044 else if (_isRef) {
6045 ref.value = value;
6046 if (rawRef.k)
6047 refs[rawRef.k] = value;
6048 }
6049 else {
6050 warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6051 }
6052 };
6053 if (value) {
6054 doSet.id = -1;
6055 queuePostRenderEffect(doSet, parentSuspense);
6056 }
6057 else {
6058 doSet();
6059 }
6060 }
6061 else {
6062 warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6063 }
6064 }
6065}
6066
6067let hasMismatch = false;
6068const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
6069const isComment = (node) => node.nodeType === 8 /* COMMENT */;
6070// Note: hydration is DOM-specific
6071// But we have to place it in core due to tight coupling with core - splitting
6072// it out creates a ton of unnecessary complexity.
6073// Hydration also depends on some renderer internal logic which needs to be
6074// passed in via arguments.
6075function createHydrationFunctions(rendererInternals) {
6076 const { mt: mountComponent, p: patch, o: { patchProp, createText, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
6077 const hydrate = (vnode, container) => {
6078 if (!container.hasChildNodes()) {
6079 warn$1(`Attempting to hydrate existing markup but container is empty. ` +
6080 `Performing full mount instead.`);
6081 patch(null, vnode, container);
6082 flushPostFlushCbs();
6083 container._vnode = vnode;
6084 return;
6085 }
6086 hasMismatch = false;
6087 hydrateNode(container.firstChild, vnode, null, null, null);
6088 flushPostFlushCbs();
6089 container._vnode = vnode;
6090 if (hasMismatch && !false) {
6091 // this error should show up in production
6092 console.error(`Hydration completed but contains mismatches.`);
6093 }
6094 };
6095 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
6096 const isFragmentStart = isComment(node) && node.data === '[';
6097 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
6098 const { type, ref, shapeFlag, patchFlag } = vnode;
6099 const domType = node.nodeType;
6100 vnode.el = node;
6101 if (patchFlag === -2 /* BAIL */) {
6102 optimized = false;
6103 vnode.dynamicChildren = null;
6104 }
6105 let nextNode = null;
6106 switch (type) {
6107 case Text:
6108 if (domType !== 3 /* TEXT */) {
6109 // #5728 empty text node inside a slot can cause hydration failure
6110 // because the server rendered HTML won't contain a text node
6111 if (vnode.children === '') {
6112 insert((vnode.el = createText('')), parentNode(node), node);
6113 nextNode = node;
6114 }
6115 else {
6116 nextNode = onMismatch();
6117 }
6118 }
6119 else {
6120 if (node.data !== vnode.children) {
6121 hasMismatch = true;
6122 warn$1(`Hydration text mismatch:` +
6123 `\n- Client: ${JSON.stringify(node.data)}` +
6124 `\n- Server: ${JSON.stringify(vnode.children)}`);
6125 node.data = vnode.children;
6126 }
6127 nextNode = nextSibling(node);
6128 }
6129 break;
6130 case Comment:
6131 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
6132 nextNode = onMismatch();
6133 }
6134 else {
6135 nextNode = nextSibling(node);
6136 }
6137 break;
6138 case Static:
6139 if (domType !== 1 /* ELEMENT */ && domType !== 3 /* TEXT */) {
6140 nextNode = onMismatch();
6141 }
6142 else {
6143 // determine anchor, adopt content
6144 nextNode = node;
6145 // if the static vnode has its content stripped during build,
6146 // adopt it from the server-rendered HTML.
6147 const needToAdoptContent = !vnode.children.length;
6148 for (let i = 0; i < vnode.staticCount; i++) {
6149 if (needToAdoptContent)
6150 vnode.children +=
6151 nextNode.nodeType === 1 /* ELEMENT */
6152 ? nextNode.outerHTML
6153 : nextNode.data;
6154 if (i === vnode.staticCount - 1) {
6155 vnode.anchor = nextNode;
6156 }
6157 nextNode = nextSibling(nextNode);
6158 }
6159 return nextNode;
6160 }
6161 break;
6162 case Fragment:
6163 if (!isFragmentStart) {
6164 nextNode = onMismatch();
6165 }
6166 else {
6167 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6168 }
6169 break;
6170 default:
6171 if (shapeFlag & 1 /* ELEMENT */) {
6172 if (domType !== 1 /* ELEMENT */ ||
6173 vnode.type.toLowerCase() !==
6174 node.tagName.toLowerCase()) {
6175 nextNode = onMismatch();
6176 }
6177 else {
6178 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6179 }
6180 }
6181 else if (shapeFlag & 6 /* COMPONENT */) {
6182 // when setting up the render effect, if the initial vnode already
6183 // has .el set, the component will perform hydration instead of mount
6184 // on its sub-tree.
6185 vnode.slotScopeIds = slotScopeIds;
6186 const container = parentNode(node);
6187 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
6188 // component may be async, so in the case of fragments we cannot rely
6189 // on component's rendered output to determine the end of the fragment
6190 // instead, we do a lookahead to find the end anchor node.
6191 nextNode = isFragmentStart
6192 ? locateClosingAsyncAnchor(node)
6193 : nextSibling(node);
6194 // #4293 teleport as component root
6195 if (nextNode &&
6196 isComment(nextNode) &&
6197 nextNode.data === 'teleport end') {
6198 nextNode = nextSibling(nextNode);
6199 }
6200 // #3787
6201 // if component is async, it may get moved / unmounted before its
6202 // inner component is loaded, so we need to give it a placeholder
6203 // vnode that matches its adopted DOM.
6204 if (isAsyncWrapper(vnode)) {
6205 let subTree;
6206 if (isFragmentStart) {
6207 subTree = createVNode(Fragment);
6208 subTree.anchor = nextNode
6209 ? nextNode.previousSibling
6210 : container.lastChild;
6211 }
6212 else {
6213 subTree =
6214 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
6215 }
6216 subTree.el = node;
6217 vnode.component.subTree = subTree;
6218 }
6219 }
6220 else if (shapeFlag & 64 /* TELEPORT */) {
6221 if (domType !== 8 /* COMMENT */) {
6222 nextNode = onMismatch();
6223 }
6224 else {
6225 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
6226 }
6227 }
6228 else if (shapeFlag & 128 /* SUSPENSE */) {
6229 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
6230 }
6231 else {
6232 warn$1('Invalid HostVNode type:', type, `(${typeof type})`);
6233 }
6234 }
6235 if (ref != null) {
6236 setRef(ref, null, parentSuspense, vnode);
6237 }
6238 return nextNode;
6239 };
6240 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6241 optimized = optimized || !!vnode.dynamicChildren;
6242 const { type, props, patchFlag, shapeFlag, dirs } = vnode;
6243 // #4006 for form elements with non-string v-model value bindings
6244 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
6245 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
6246 // skip props & children if this is hoisted static nodes
6247 // #5405 in dev, always hydrate children for HMR
6248 {
6249 if (dirs) {
6250 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6251 }
6252 // props
6253 if (props) {
6254 if (forcePatchValue ||
6255 !optimized ||
6256 patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) {
6257 for (const key in props) {
6258 if ((forcePatchValue && key.endsWith('value')) ||
6259 (isOn(key) && !isReservedProp(key))) {
6260 patchProp(el, key, null, props[key], false, undefined, parentComponent);
6261 }
6262 }
6263 }
6264 else if (props.onClick) {
6265 // Fast path for click listeners (which is most often) to avoid
6266 // iterating through props.
6267 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent);
6268 }
6269 }
6270 // vnode / directive hooks
6271 let vnodeHooks;
6272 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
6273 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6274 }
6275 if (dirs) {
6276 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6277 }
6278 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
6279 queueEffectWithSuspense(() => {
6280 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6281 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6282 }, parentSuspense);
6283 }
6284 // children
6285 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
6286 // skip if element has innerHTML / textContent
6287 !(props && (props.innerHTML || props.textContent))) {
6288 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
6289 let hasWarned = false;
6290 while (next) {
6291 hasMismatch = true;
6292 if (!hasWarned) {
6293 warn$1(`Hydration children mismatch in <${vnode.type}>: ` +
6294 `server rendered element contains more child nodes than client vdom.`);
6295 hasWarned = true;
6296 }
6297 // The SSRed DOM contains more nodes than it should. Remove them.
6298 const cur = next;
6299 next = next.nextSibling;
6300 remove(cur);
6301 }
6302 }
6303 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6304 if (el.textContent !== vnode.children) {
6305 hasMismatch = true;
6306 warn$1(`Hydration text content mismatch in <${vnode.type}>:\n` +
6307 `- Client: ${el.textContent}\n` +
6308 `- Server: ${vnode.children}`);
6309 el.textContent = vnode.children;
6310 }
6311 }
6312 }
6313 return el.nextSibling;
6314 };
6315 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6316 optimized = optimized || !!parentVNode.dynamicChildren;
6317 const children = parentVNode.children;
6318 const l = children.length;
6319 let hasWarned = false;
6320 for (let i = 0; i < l; i++) {
6321 const vnode = optimized
6322 ? children[i]
6323 : (children[i] = normalizeVNode(children[i]));
6324 if (node) {
6325 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6326 }
6327 else if (vnode.type === Text && !vnode.children) {
6328 continue;
6329 }
6330 else {
6331 hasMismatch = true;
6332 if (!hasWarned) {
6333 warn$1(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
6334 `server rendered element contains fewer child nodes than client vdom.`);
6335 hasWarned = true;
6336 }
6337 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
6338 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6339 }
6340 }
6341 return node;
6342 };
6343 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6344 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
6345 if (fragmentSlotScopeIds) {
6346 slotScopeIds = slotScopeIds
6347 ? slotScopeIds.concat(fragmentSlotScopeIds)
6348 : fragmentSlotScopeIds;
6349 }
6350 const container = parentNode(node);
6351 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
6352 if (next && isComment(next) && next.data === ']') {
6353 return nextSibling((vnode.anchor = next));
6354 }
6355 else {
6356 // fragment didn't hydrate successfully, since we didn't get a end anchor
6357 // back. This should have led to node/children mismatch warnings.
6358 hasMismatch = true;
6359 // since the anchor is missing, we need to create one and insert it
6360 insert((vnode.anchor = createComment(`]`)), container, next);
6361 return next;
6362 }
6363 };
6364 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
6365 hasMismatch = true;
6366 warn$1(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
6367 ? `(text)`
6368 : isComment(node) && node.data === '['
6369 ? `(start of fragment)`
6370 : ``);
6371 vnode.el = null;
6372 if (isFragment) {
6373 // remove excessive fragment nodes
6374 const end = locateClosingAsyncAnchor(node);
6375 while (true) {
6376 const next = nextSibling(node);
6377 if (next && next !== end) {
6378 remove(next);
6379 }
6380 else {
6381 break;
6382 }
6383 }
6384 }
6385 const next = nextSibling(node);
6386 const container = parentNode(node);
6387 remove(node);
6388 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6389 return next;
6390 };
6391 const locateClosingAsyncAnchor = (node) => {
6392 let match = 0;
6393 while (node) {
6394 node = nextSibling(node);
6395 if (node && isComment(node)) {
6396 if (node.data === '[')
6397 match++;
6398 if (node.data === ']') {
6399 if (match === 0) {
6400 return nextSibling(node);
6401 }
6402 else {
6403 match--;
6404 }
6405 }
6406 }
6407 }
6408 return node;
6409 };
6410 return [hydrate, hydrateNode];
6411}
6412
6413/* eslint-disable no-restricted-globals */
6414let supported;
6415let perf;
6416function startMeasure(instance, type) {
6417 if (instance.appContext.config.performance && isSupported()) {
6418 perf.mark(`vue-${type}-${instance.uid}`);
6419 }
6420 {
6421 devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now());
6422 }
6423}
6424function endMeasure(instance, type) {
6425 if (instance.appContext.config.performance && isSupported()) {
6426 const startTag = `vue-${type}-${instance.uid}`;
6427 const endTag = startTag + `:end`;
6428 perf.mark(endTag);
6429 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
6430 perf.clearMarks(startTag);
6431 perf.clearMarks(endTag);
6432 }
6433 {
6434 devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now());
6435 }
6436}
6437function isSupported() {
6438 if (supported !== undefined) {
6439 return supported;
6440 }
6441 if (typeof window !== 'undefined' && window.performance) {
6442 supported = true;
6443 perf = window.performance;
6444 }
6445 else {
6446 supported = false;
6447 }
6448 return supported;
6449}
6450
6451const queuePostRenderEffect = queueEffectWithSuspense
6452 ;
6453/**
6454 * The createRenderer function accepts two generic arguments:
6455 * HostNode and HostElement, corresponding to Node and Element types in the
6456 * host environment. For example, for runtime-dom, HostNode would be the DOM
6457 * `Node` interface and HostElement would be the DOM `Element` interface.
6458 *
6459 * Custom renderers can pass in the platform specific types like this:
6460 *
6461 * ``` js
6462 * const { render, createApp } = createRenderer<Node, Element>({
6463 * patchProp,
6464 * ...nodeOps
6465 * })
6466 * ```
6467 */
6468function createRenderer(options) {
6469 return baseCreateRenderer(options);
6470}
6471// Separate API for creating hydration-enabled renderer.
6472// Hydration logic is only used when calling this function, making it
6473// tree-shakable.
6474function createHydrationRenderer(options) {
6475 return baseCreateRenderer(options, createHydrationFunctions);
6476}
6477// implementation
6478function baseCreateRenderer(options, createHydrationFns) {
6479 const target = getGlobalThis();
6480 target.__VUE__ = true;
6481 {
6482 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
6483 }
6484 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
6485 // Note: functions inside this closure should use `const xxx = () => {}`
6486 // style in order to prevent being inlined by minifiers.
6487 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
6488 if (n1 === n2) {
6489 return;
6490 }
6491 // patching & not same type, unmount old tree
6492 if (n1 && !isSameVNodeType(n1, n2)) {
6493 anchor = getNextHostNode(n1);
6494 unmount(n1, parentComponent, parentSuspense, true);
6495 n1 = null;
6496 }
6497 if (n2.patchFlag === -2 /* BAIL */) {
6498 optimized = false;
6499 n2.dynamicChildren = null;
6500 }
6501 const { type, ref, shapeFlag } = n2;
6502 switch (type) {
6503 case Text:
6504 processText(n1, n2, container, anchor);
6505 break;
6506 case Comment:
6507 processCommentNode(n1, n2, container, anchor);
6508 break;
6509 case Static:
6510 if (n1 == null) {
6511 mountStaticNode(n2, container, anchor, isSVG);
6512 }
6513 else {
6514 patchStaticNode(n1, n2, container, isSVG);
6515 }
6516 break;
6517 case Fragment:
6518 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6519 break;
6520 default:
6521 if (shapeFlag & 1 /* ELEMENT */) {
6522 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6523 }
6524 else if (shapeFlag & 6 /* COMPONENT */) {
6525 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6526 }
6527 else if (shapeFlag & 64 /* TELEPORT */) {
6528 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6529 }
6530 else if (shapeFlag & 128 /* SUSPENSE */) {
6531 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6532 }
6533 else {
6534 warn$1('Invalid VNode type:', type, `(${typeof type})`);
6535 }
6536 }
6537 // set ref
6538 if (ref != null && parentComponent) {
6539 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
6540 }
6541 };
6542 const processText = (n1, n2, container, anchor) => {
6543 if (n1 == null) {
6544 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
6545 }
6546 else {
6547 const el = (n2.el = n1.el);
6548 if (n2.children !== n1.children) {
6549 hostSetText(el, n2.children);
6550 }
6551 }
6552 };
6553 const processCommentNode = (n1, n2, container, anchor) => {
6554 if (n1 == null) {
6555 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
6556 }
6557 else {
6558 // there's no support for dynamic comments
6559 n2.el = n1.el;
6560 }
6561 };
6562 const mountStaticNode = (n2, container, anchor, isSVG) => {
6563 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG, n2.el, n2.anchor);
6564 };
6565 /**
6566 * Dev / HMR only
6567 */
6568 const patchStaticNode = (n1, n2, container, isSVG) => {
6569 // static nodes are only patched during dev for HMR
6570 if (n2.children !== n1.children) {
6571 const anchor = hostNextSibling(n1.anchor);
6572 // remove existing
6573 removeStaticNode(n1);
6574 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
6575 }
6576 else {
6577 n2.el = n1.el;
6578 n2.anchor = n1.anchor;
6579 }
6580 };
6581 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
6582 let next;
6583 while (el && el !== anchor) {
6584 next = hostNextSibling(el);
6585 hostInsert(el, container, nextSibling);
6586 el = next;
6587 }
6588 hostInsert(anchor, container, nextSibling);
6589 };
6590 const removeStaticNode = ({ el, anchor }) => {
6591 let next;
6592 while (el && el !== anchor) {
6593 next = hostNextSibling(el);
6594 hostRemove(el);
6595 el = next;
6596 }
6597 hostRemove(anchor);
6598 };
6599 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6600 isSVG = isSVG || n2.type === 'svg';
6601 if (n1 == null) {
6602 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6603 }
6604 else {
6605 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6606 }
6607 };
6608 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6609 let el;
6610 let vnodeHook;
6611 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
6612 {
6613 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6614 // mount children first, since some props may rely on child content
6615 // being already rendered, e.g. `<select value>`
6616 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6617 hostSetElementText(el, vnode.children);
6618 }
6619 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6620 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6621 }
6622 if (dirs) {
6623 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6624 }
6625 // props
6626 if (props) {
6627 for (const key in props) {
6628 if (key !== 'value' && !isReservedProp(key)) {
6629 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6630 }
6631 }
6632 /**
6633 * Special case for setting value on DOM elements:
6634 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6635 * - it needs to be forced (#1471)
6636 * #2353 proposes adding another renderer option to configure this, but
6637 * the properties affects are so finite it is worth special casing it
6638 * here to reduce the complexity. (Special casing it also should not
6639 * affect non-DOM renderers)
6640 */
6641 if ('value' in props) {
6642 hostPatchProp(el, 'value', null, props.value);
6643 }
6644 if ((vnodeHook = props.onVnodeBeforeMount)) {
6645 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6646 }
6647 }
6648 // scopeId
6649 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6650 }
6651 {
6652 Object.defineProperty(el, '__vnode', {
6653 value: vnode,
6654 enumerable: false
6655 });
6656 Object.defineProperty(el, '__vueParentComponent', {
6657 value: parentComponent,
6658 enumerable: false
6659 });
6660 }
6661 if (dirs) {
6662 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6663 }
6664 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
6665 // #1689 For inside suspense + suspense resolved case, just call it
6666 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
6667 transition &&
6668 !transition.persisted;
6669 if (needCallTransitionHooks) {
6670 transition.beforeEnter(el);
6671 }
6672 hostInsert(el, container, anchor);
6673 if ((vnodeHook = props && props.onVnodeMounted) ||
6674 needCallTransitionHooks ||
6675 dirs) {
6676 queuePostRenderEffect(() => {
6677 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6678 needCallTransitionHooks && transition.enter(el);
6679 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6680 }, parentSuspense);
6681 }
6682 };
6683 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
6684 if (scopeId) {
6685 hostSetScopeId(el, scopeId);
6686 }
6687 if (slotScopeIds) {
6688 for (let i = 0; i < slotScopeIds.length; i++) {
6689 hostSetScopeId(el, slotScopeIds[i]);
6690 }
6691 }
6692 if (parentComponent) {
6693 let subTree = parentComponent.subTree;
6694 if (subTree.patchFlag > 0 &&
6695 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
6696 subTree =
6697 filterSingleRoot(subTree.children) || subTree;
6698 }
6699 if (vnode === subTree) {
6700 const parentVNode = parentComponent.vnode;
6701 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
6702 }
6703 }
6704 };
6705 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
6706 for (let i = start; i < children.length; i++) {
6707 const child = (children[i] = optimized
6708 ? cloneIfMounted(children[i])
6709 : normalizeVNode(children[i]));
6710 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6711 }
6712 };
6713 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6714 const el = (n2.el = n1.el);
6715 let { patchFlag, dynamicChildren, dirs } = n2;
6716 // #1426 take the old vnode's patch flag into account since user may clone a
6717 // compiler-generated vnode, which de-opts to FULL_PROPS
6718 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
6719 const oldProps = n1.props || EMPTY_OBJ;
6720 const newProps = n2.props || EMPTY_OBJ;
6721 let vnodeHook;
6722 // disable recurse in beforeUpdate hooks
6723 parentComponent && toggleRecurse(parentComponent, false);
6724 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6725 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6726 }
6727 if (dirs) {
6728 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6729 }
6730 parentComponent && toggleRecurse(parentComponent, true);
6731 if (isHmrUpdating) {
6732 // HMR updated, force full diff
6733 patchFlag = 0;
6734 optimized = false;
6735 dynamicChildren = null;
6736 }
6737 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
6738 if (dynamicChildren) {
6739 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
6740 if (parentComponent && parentComponent.type.__hmrId) {
6741 traverseStaticChildren(n1, n2);
6742 }
6743 }
6744 else if (!optimized) {
6745 // full diff
6746 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
6747 }
6748 if (patchFlag > 0) {
6749 // the presence of a patchFlag means this element's render code was
6750 // generated by the compiler and can take the fast path.
6751 // in this path old node and new node are guaranteed to have the same shape
6752 // (i.e. at the exact same position in the source template)
6753 if (patchFlag & 16 /* FULL_PROPS */) {
6754 // element props contain dynamic keys, full diff needed
6755 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6756 }
6757 else {
6758 // class
6759 // this flag is matched when the element has dynamic class bindings.
6760 if (patchFlag & 2 /* CLASS */) {
6761 if (oldProps.class !== newProps.class) {
6762 hostPatchProp(el, 'class', null, newProps.class, isSVG);
6763 }
6764 }
6765 // style
6766 // this flag is matched when the element has dynamic style bindings
6767 if (patchFlag & 4 /* STYLE */) {
6768 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
6769 }
6770 // props
6771 // This flag is matched when the element has dynamic prop/attr bindings
6772 // other than class and style. The keys of dynamic prop/attrs are saved for
6773 // faster iteration.
6774 // Note dynamic keys like :[foo]="bar" will cause this optimization to
6775 // bail out and go through a full diff because we need to unset the old key
6776 if (patchFlag & 8 /* PROPS */) {
6777 // if the flag is present then dynamicProps must be non-null
6778 const propsToUpdate = n2.dynamicProps;
6779 for (let i = 0; i < propsToUpdate.length; i++) {
6780 const key = propsToUpdate[i];
6781 const prev = oldProps[key];
6782 const next = newProps[key];
6783 // #1471 force patch value
6784 if (next !== prev || key === 'value') {
6785 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
6786 }
6787 }
6788 }
6789 }
6790 // text
6791 // This flag is matched when the element has only dynamic text children.
6792 if (patchFlag & 1 /* TEXT */) {
6793 if (n1.children !== n2.children) {
6794 hostSetElementText(el, n2.children);
6795 }
6796 }
6797 }
6798 else if (!optimized && dynamicChildren == null) {
6799 // unoptimized, full diff
6800 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6801 }
6802 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
6803 queuePostRenderEffect(() => {
6804 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6805 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
6806 }, parentSuspense);
6807 }
6808 };
6809 // The fast path for blocks.
6810 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
6811 for (let i = 0; i < newChildren.length; i++) {
6812 const oldVNode = oldChildren[i];
6813 const newVNode = newChildren[i];
6814 // Determine the container (parent element) for the patch.
6815 const container =
6816 // oldVNode may be an errored async setup() component inside Suspense
6817 // which will not have a mounted element
6818 oldVNode.el &&
6819 // - In the case of a Fragment, we need to provide the actual parent
6820 // of the Fragment itself so it can move its children.
6821 (oldVNode.type === Fragment ||
6822 // - In the case of different nodes, there is going to be a replacement
6823 // which also requires the correct parent container
6824 !isSameVNodeType(oldVNode, newVNode) ||
6825 // - In the case of a component, it could contain anything.
6826 oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */))
6827 ? hostParentNode(oldVNode.el)
6828 : // In other cases, the parent container is not actually used so we
6829 // just pass the block element here to avoid a DOM parentNode call.
6830 fallbackContainer;
6831 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
6832 }
6833 };
6834 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
6835 if (oldProps !== newProps) {
6836 for (const key in newProps) {
6837 // empty string is not valid prop
6838 if (isReservedProp(key))
6839 continue;
6840 const next = newProps[key];
6841 const prev = oldProps[key];
6842 // defer patching value
6843 if (next !== prev && key !== 'value') {
6844 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6845 }
6846 }
6847 if (oldProps !== EMPTY_OBJ) {
6848 for (const key in oldProps) {
6849 if (!isReservedProp(key) && !(key in newProps)) {
6850 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6851 }
6852 }
6853 }
6854 if ('value' in newProps) {
6855 hostPatchProp(el, 'value', oldProps.value, newProps.value);
6856 }
6857 }
6858 };
6859 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6860 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
6861 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
6862 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
6863 if (// #5523 dev root fragment may inherit directives
6864 (isHmrUpdating || patchFlag & 2048 /* DEV_ROOT_FRAGMENT */)) {
6865 // HMR updated / Dev root fragment (w/ comments), force full diff
6866 patchFlag = 0;
6867 optimized = false;
6868 dynamicChildren = null;
6869 }
6870 // check if this is a slot fragment with :slotted scope ids
6871 if (fragmentSlotScopeIds) {
6872 slotScopeIds = slotScopeIds
6873 ? slotScopeIds.concat(fragmentSlotScopeIds)
6874 : fragmentSlotScopeIds;
6875 }
6876 if (n1 == null) {
6877 hostInsert(fragmentStartAnchor, container, anchor);
6878 hostInsert(fragmentEndAnchor, container, anchor);
6879 // a fragment can only have array children
6880 // since they are either generated by the compiler, or implicitly created
6881 // from arrays.
6882 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6883 }
6884 else {
6885 if (patchFlag > 0 &&
6886 patchFlag & 64 /* STABLE_FRAGMENT */ &&
6887 dynamicChildren &&
6888 // #2715 the previous fragment could've been a BAILed one as a result
6889 // of renderSlot() with no valid children
6890 n1.dynamicChildren) {
6891 // a stable fragment (template root or <template v-for>) doesn't need to
6892 // patch children order, but it may contain dynamicChildren.
6893 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
6894 if (parentComponent && parentComponent.type.__hmrId) {
6895 traverseStaticChildren(n1, n2);
6896 }
6897 else if (
6898 // #2080 if the stable fragment has a key, it's a <template v-for> that may
6899 // get moved around. Make sure all root level vnodes inherit el.
6900 // #2134 or if it's a component root, it may also get moved around
6901 // as the component is being moved.
6902 n2.key != null ||
6903 (parentComponent && n2 === parentComponent.subTree)) {
6904 traverseStaticChildren(n1, n2, true /* shallow */);
6905 }
6906 }
6907 else {
6908 // keyed / unkeyed, or manual fragments.
6909 // for keyed & unkeyed, since they are compiler generated from v-for,
6910 // each child is guaranteed to be a block so the fragment will never
6911 // have dynamicChildren.
6912 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6913 }
6914 }
6915 };
6916 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6917 n2.slotScopeIds = slotScopeIds;
6918 if (n1 == null) {
6919 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
6920 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
6921 }
6922 else {
6923 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
6924 }
6925 }
6926 else {
6927 updateComponent(n1, n2, optimized);
6928 }
6929 };
6930 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
6931 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
6932 if (instance.type.__hmrId) {
6933 registerHMR(instance);
6934 }
6935 {
6936 pushWarningContext(initialVNode);
6937 startMeasure(instance, `mount`);
6938 }
6939 // inject renderer internals for keepAlive
6940 if (isKeepAlive(initialVNode)) {
6941 instance.ctx.renderer = internals;
6942 }
6943 // resolve props and slots for setup context
6944 {
6945 {
6946 startMeasure(instance, `init`);
6947 }
6948 setupComponent(instance);
6949 {
6950 endMeasure(instance, `init`);
6951 }
6952 }
6953 // setup() is async. This component relies on async logic to be resolved
6954 // before proceeding
6955 if (instance.asyncDep) {
6956 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
6957 // Give it a placeholder if this is not hydration
6958 // TODO handle self-defined fallback
6959 if (!initialVNode.el) {
6960 const placeholder = (instance.subTree = createVNode(Comment));
6961 processCommentNode(null, placeholder, container, anchor);
6962 }
6963 return;
6964 }
6965 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
6966 {
6967 popWarningContext();
6968 endMeasure(instance, `mount`);
6969 }
6970 };
6971 const updateComponent = (n1, n2, optimized) => {
6972 const instance = (n2.component = n1.component);
6973 if (shouldUpdateComponent(n1, n2, optimized)) {
6974 if (instance.asyncDep &&
6975 !instance.asyncResolved) {
6976 // async & still pending - just update props and slots
6977 // since the component's reactive effect for render isn't set-up yet
6978 {
6979 pushWarningContext(n2);
6980 }
6981 updateComponentPreRender(instance, n2, optimized);
6982 {
6983 popWarningContext();
6984 }
6985 return;
6986 }
6987 else {
6988 // normal update
6989 instance.next = n2;
6990 // in case the child component is also queued, remove it to avoid
6991 // double updating the same child component in the same flush.
6992 invalidateJob(instance.update);
6993 // instance.update is the reactive effect.
6994 instance.update();
6995 }
6996 }
6997 else {
6998 // no update needed. just copy over properties
6999 n2.el = n1.el;
7000 instance.vnode = n2;
7001 }
7002 };
7003 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
7004 const componentUpdateFn = () => {
7005 if (!instance.isMounted) {
7006 let vnodeHook;
7007 const { el, props } = initialVNode;
7008 const { bm, m, parent } = instance;
7009 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
7010 toggleRecurse(instance, false);
7011 // beforeMount hook
7012 if (bm) {
7013 invokeArrayFns(bm);
7014 }
7015 // onVnodeBeforeMount
7016 if (!isAsyncWrapperVNode &&
7017 (vnodeHook = props && props.onVnodeBeforeMount)) {
7018 invokeVNodeHook(vnodeHook, parent, initialVNode);
7019 }
7020 toggleRecurse(instance, true);
7021 if (el && hydrateNode) {
7022 // vnode has adopted host node - perform hydration instead of mount.
7023 const hydrateSubTree = () => {
7024 {
7025 startMeasure(instance, `render`);
7026 }
7027 instance.subTree = renderComponentRoot(instance);
7028 {
7029 endMeasure(instance, `render`);
7030 }
7031 {
7032 startMeasure(instance, `hydrate`);
7033 }
7034 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
7035 {
7036 endMeasure(instance, `hydrate`);
7037 }
7038 };
7039 if (isAsyncWrapperVNode) {
7040 initialVNode.type.__asyncLoader().then(
7041 // note: we are moving the render call into an async callback,
7042 // which means it won't track dependencies - but it's ok because
7043 // a server-rendered async wrapper is already in resolved state
7044 // and it will never need to change.
7045 () => !instance.isUnmounted && hydrateSubTree());
7046 }
7047 else {
7048 hydrateSubTree();
7049 }
7050 }
7051 else {
7052 {
7053 startMeasure(instance, `render`);
7054 }
7055 const subTree = (instance.subTree = renderComponentRoot(instance));
7056 {
7057 endMeasure(instance, `render`);
7058 }
7059 {
7060 startMeasure(instance, `patch`);
7061 }
7062 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
7063 {
7064 endMeasure(instance, `patch`);
7065 }
7066 initialVNode.el = subTree.el;
7067 }
7068 // mounted hook
7069 if (m) {
7070 queuePostRenderEffect(m, parentSuspense);
7071 }
7072 // onVnodeMounted
7073 if (!isAsyncWrapperVNode &&
7074 (vnodeHook = props && props.onVnodeMounted)) {
7075 const scopedInitialVNode = initialVNode;
7076 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
7077 }
7078 // activated hook for keep-alive roots.
7079 // #1742 activated hook must be accessed after first render
7080 // since the hook may be injected by a child keep-alive
7081 if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */ ||
7082 (parent &&
7083 isAsyncWrapper(parent.vnode) &&
7084 parent.vnode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */)) {
7085 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
7086 }
7087 instance.isMounted = true;
7088 {
7089 devtoolsComponentAdded(instance);
7090 }
7091 // #2458: deference mount-only object parameters to prevent memleaks
7092 initialVNode = container = anchor = null;
7093 }
7094 else {
7095 // updateComponent
7096 // This is triggered by mutation of component's own state (next: null)
7097 // OR parent calling processComponent (next: VNode)
7098 let { next, bu, u, parent, vnode } = instance;
7099 let originNext = next;
7100 let vnodeHook;
7101 {
7102 pushWarningContext(next || instance.vnode);
7103 }
7104 // Disallow component effect recursion during pre-lifecycle hooks.
7105 toggleRecurse(instance, false);
7106 if (next) {
7107 next.el = vnode.el;
7108 updateComponentPreRender(instance, next, optimized);
7109 }
7110 else {
7111 next = vnode;
7112 }
7113 // beforeUpdate hook
7114 if (bu) {
7115 invokeArrayFns(bu);
7116 }
7117 // onVnodeBeforeUpdate
7118 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
7119 invokeVNodeHook(vnodeHook, parent, next, vnode);
7120 }
7121 toggleRecurse(instance, true);
7122 // render
7123 {
7124 startMeasure(instance, `render`);
7125 }
7126 const nextTree = renderComponentRoot(instance);
7127 {
7128 endMeasure(instance, `render`);
7129 }
7130 const prevTree = instance.subTree;
7131 instance.subTree = nextTree;
7132 {
7133 startMeasure(instance, `patch`);
7134 }
7135 patch(prevTree, nextTree,
7136 // parent may have changed if it's in a teleport
7137 hostParentNode(prevTree.el),
7138 // anchor may have changed if it's in a fragment
7139 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
7140 {
7141 endMeasure(instance, `patch`);
7142 }
7143 next.el = nextTree.el;
7144 if (originNext === null) {
7145 // self-triggered update. In case of HOC, update parent component
7146 // vnode el. HOC is indicated by parent instance's subTree pointing
7147 // to child component's vnode
7148 updateHOCHostEl(instance, nextTree.el);
7149 }
7150 // updated hook
7151 if (u) {
7152 queuePostRenderEffect(u, parentSuspense);
7153 }
7154 // onVnodeUpdated
7155 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
7156 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
7157 }
7158 {
7159 devtoolsComponentUpdated(instance);
7160 }
7161 {
7162 popWarningContext();
7163 }
7164 }
7165 };
7166 // create reactive effect for rendering
7167 const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(update), instance.scope // track it in component's effect scope
7168 ));
7169 const update = (instance.update = () => effect.run());
7170 update.id = instance.uid;
7171 // allowRecurse
7172 // #1801, #2043 component render effects should allow recursive updates
7173 toggleRecurse(instance, true);
7174 {
7175 effect.onTrack = instance.rtc
7176 ? e => invokeArrayFns(instance.rtc, e)
7177 : void 0;
7178 effect.onTrigger = instance.rtg
7179 ? e => invokeArrayFns(instance.rtg, e)
7180 : void 0;
7181 update.ownerInstance = instance;
7182 }
7183 update();
7184 };
7185 const updateComponentPreRender = (instance, nextVNode, optimized) => {
7186 nextVNode.component = instance;
7187 const prevProps = instance.vnode.props;
7188 instance.vnode = nextVNode;
7189 instance.next = null;
7190 updateProps(instance, nextVNode.props, prevProps, optimized);
7191 updateSlots(instance, nextVNode.children, optimized);
7192 pauseTracking();
7193 // props update may have triggered pre-flush watchers.
7194 // flush them before the render update.
7195 flushPreFlushCbs(undefined, instance.update);
7196 resetTracking();
7197 };
7198 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
7199 const c1 = n1 && n1.children;
7200 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
7201 const c2 = n2.children;
7202 const { patchFlag, shapeFlag } = n2;
7203 // fast path
7204 if (patchFlag > 0) {
7205 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
7206 // this could be either fully-keyed or mixed (some keyed some not)
7207 // presence of patchFlag means children are guaranteed to be arrays
7208 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7209 return;
7210 }
7211 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
7212 // unkeyed
7213 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7214 return;
7215 }
7216 }
7217 // children has 3 possibilities: text, array or no children.
7218 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
7219 // text children fast path
7220 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
7221 unmountChildren(c1, parentComponent, parentSuspense);
7222 }
7223 if (c2 !== c1) {
7224 hostSetElementText(container, c2);
7225 }
7226 }
7227 else {
7228 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
7229 // prev children was array
7230 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7231 // two arrays, cannot assume anything, do full diff
7232 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7233 }
7234 else {
7235 // no new children, just unmount old
7236 unmountChildren(c1, parentComponent, parentSuspense, true);
7237 }
7238 }
7239 else {
7240 // prev children was text OR null
7241 // new children is array OR null
7242 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
7243 hostSetElementText(container, '');
7244 }
7245 // mount new if array
7246 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7247 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7248 }
7249 }
7250 }
7251 };
7252 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7253 c1 = c1 || EMPTY_ARR;
7254 c2 = c2 || EMPTY_ARR;
7255 const oldLength = c1.length;
7256 const newLength = c2.length;
7257 const commonLength = Math.min(oldLength, newLength);
7258 let i;
7259 for (i = 0; i < commonLength; i++) {
7260 const nextChild = (c2[i] = optimized
7261 ? cloneIfMounted(c2[i])
7262 : normalizeVNode(c2[i]));
7263 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7264 }
7265 if (oldLength > newLength) {
7266 // remove old
7267 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
7268 }
7269 else {
7270 // mount new
7271 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
7272 }
7273 };
7274 // can be all-keyed or mixed
7275 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7276 let i = 0;
7277 const l2 = c2.length;
7278 let e1 = c1.length - 1; // prev ending index
7279 let e2 = l2 - 1; // next ending index
7280 // 1. sync from start
7281 // (a b) c
7282 // (a b) d e
7283 while (i <= e1 && i <= e2) {
7284 const n1 = c1[i];
7285 const n2 = (c2[i] = optimized
7286 ? cloneIfMounted(c2[i])
7287 : normalizeVNode(c2[i]));
7288 if (isSameVNodeType(n1, n2)) {
7289 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7290 }
7291 else {
7292 break;
7293 }
7294 i++;
7295 }
7296 // 2. sync from end
7297 // a (b c)
7298 // d e (b c)
7299 while (i <= e1 && i <= e2) {
7300 const n1 = c1[e1];
7301 const n2 = (c2[e2] = optimized
7302 ? cloneIfMounted(c2[e2])
7303 : normalizeVNode(c2[e2]));
7304 if (isSameVNodeType(n1, n2)) {
7305 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7306 }
7307 else {
7308 break;
7309 }
7310 e1--;
7311 e2--;
7312 }
7313 // 3. common sequence + mount
7314 // (a b)
7315 // (a b) c
7316 // i = 2, e1 = 1, e2 = 2
7317 // (a b)
7318 // c (a b)
7319 // i = 0, e1 = -1, e2 = 0
7320 if (i > e1) {
7321 if (i <= e2) {
7322 const nextPos = e2 + 1;
7323 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
7324 while (i <= e2) {
7325 patch(null, (c2[i] = optimized
7326 ? cloneIfMounted(c2[i])
7327 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7328 i++;
7329 }
7330 }
7331 }
7332 // 4. common sequence + unmount
7333 // (a b) c
7334 // (a b)
7335 // i = 2, e1 = 2, e2 = 1
7336 // a (b c)
7337 // (b c)
7338 // i = 0, e1 = 0, e2 = -1
7339 else if (i > e2) {
7340 while (i <= e1) {
7341 unmount(c1[i], parentComponent, parentSuspense, true);
7342 i++;
7343 }
7344 }
7345 // 5. unknown sequence
7346 // [i ... e1 + 1]: a b [c d e] f g
7347 // [i ... e2 + 1]: a b [e d c h] f g
7348 // i = 2, e1 = 4, e2 = 5
7349 else {
7350 const s1 = i; // prev starting index
7351 const s2 = i; // next starting index
7352 // 5.1 build key:index map for newChildren
7353 const keyToNewIndexMap = new Map();
7354 for (i = s2; i <= e2; i++) {
7355 const nextChild = (c2[i] = optimized
7356 ? cloneIfMounted(c2[i])
7357 : normalizeVNode(c2[i]));
7358 if (nextChild.key != null) {
7359 if (keyToNewIndexMap.has(nextChild.key)) {
7360 warn$1(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
7361 }
7362 keyToNewIndexMap.set(nextChild.key, i);
7363 }
7364 }
7365 // 5.2 loop through old children left to be patched and try to patch
7366 // matching nodes & remove nodes that are no longer present
7367 let j;
7368 let patched = 0;
7369 const toBePatched = e2 - s2 + 1;
7370 let moved = false;
7371 // used to track whether any node has moved
7372 let maxNewIndexSoFar = 0;
7373 // works as Map<newIndex, oldIndex>
7374 // Note that oldIndex is offset by +1
7375 // and oldIndex = 0 is a special value indicating the new node has
7376 // no corresponding old node.
7377 // used for determining longest stable subsequence
7378 const newIndexToOldIndexMap = new Array(toBePatched);
7379 for (i = 0; i < toBePatched; i++)
7380 newIndexToOldIndexMap[i] = 0;
7381 for (i = s1; i <= e1; i++) {
7382 const prevChild = c1[i];
7383 if (patched >= toBePatched) {
7384 // all new children have been patched so this can only be a removal
7385 unmount(prevChild, parentComponent, parentSuspense, true);
7386 continue;
7387 }
7388 let newIndex;
7389 if (prevChild.key != null) {
7390 newIndex = keyToNewIndexMap.get(prevChild.key);
7391 }
7392 else {
7393 // key-less node, try to locate a key-less node of the same type
7394 for (j = s2; j <= e2; j++) {
7395 if (newIndexToOldIndexMap[j - s2] === 0 &&
7396 isSameVNodeType(prevChild, c2[j])) {
7397 newIndex = j;
7398 break;
7399 }
7400 }
7401 }
7402 if (newIndex === undefined) {
7403 unmount(prevChild, parentComponent, parentSuspense, true);
7404 }
7405 else {
7406 newIndexToOldIndexMap[newIndex - s2] = i + 1;
7407 if (newIndex >= maxNewIndexSoFar) {
7408 maxNewIndexSoFar = newIndex;
7409 }
7410 else {
7411 moved = true;
7412 }
7413 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7414 patched++;
7415 }
7416 }
7417 // 5.3 move and mount
7418 // generate longest stable subsequence only when nodes have moved
7419 const increasingNewIndexSequence = moved
7420 ? getSequence(newIndexToOldIndexMap)
7421 : EMPTY_ARR;
7422 j = increasingNewIndexSequence.length - 1;
7423 // looping backwards so that we can use last patched node as anchor
7424 for (i = toBePatched - 1; i >= 0; i--) {
7425 const nextIndex = s2 + i;
7426 const nextChild = c2[nextIndex];
7427 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
7428 if (newIndexToOldIndexMap[i] === 0) {
7429 // mount new
7430 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7431 }
7432 else if (moved) {
7433 // move if:
7434 // There is no stable subsequence (e.g. a reverse)
7435 // OR current node is not among the stable sequence
7436 if (j < 0 || i !== increasingNewIndexSequence[j]) {
7437 move(nextChild, container, anchor, 2 /* REORDER */);
7438 }
7439 else {
7440 j--;
7441 }
7442 }
7443 }
7444 }
7445 };
7446 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
7447 const { el, type, transition, children, shapeFlag } = vnode;
7448 if (shapeFlag & 6 /* COMPONENT */) {
7449 move(vnode.component.subTree, container, anchor, moveType);
7450 return;
7451 }
7452 if (shapeFlag & 128 /* SUSPENSE */) {
7453 vnode.suspense.move(container, anchor, moveType);
7454 return;
7455 }
7456 if (shapeFlag & 64 /* TELEPORT */) {
7457 type.move(vnode, container, anchor, internals);
7458 return;
7459 }
7460 if (type === Fragment) {
7461 hostInsert(el, container, anchor);
7462 for (let i = 0; i < children.length; i++) {
7463 move(children[i], container, anchor, moveType);
7464 }
7465 hostInsert(vnode.anchor, container, anchor);
7466 return;
7467 }
7468 if (type === Static) {
7469 moveStaticNode(vnode, container, anchor);
7470 return;
7471 }
7472 // single nodes
7473 const needTransition = moveType !== 2 /* REORDER */ &&
7474 shapeFlag & 1 /* ELEMENT */ &&
7475 transition;
7476 if (needTransition) {
7477 if (moveType === 0 /* ENTER */) {
7478 transition.beforeEnter(el);
7479 hostInsert(el, container, anchor);
7480 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
7481 }
7482 else {
7483 const { leave, delayLeave, afterLeave } = transition;
7484 const remove = () => hostInsert(el, container, anchor);
7485 const performLeave = () => {
7486 leave(el, () => {
7487 remove();
7488 afterLeave && afterLeave();
7489 });
7490 };
7491 if (delayLeave) {
7492 delayLeave(el, remove, performLeave);
7493 }
7494 else {
7495 performLeave();
7496 }
7497 }
7498 }
7499 else {
7500 hostInsert(el, container, anchor);
7501 }
7502 };
7503 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
7504 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
7505 // unset ref
7506 if (ref != null) {
7507 setRef(ref, null, parentSuspense, vnode, true);
7508 }
7509 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
7510 parentComponent.ctx.deactivate(vnode);
7511 return;
7512 }
7513 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
7514 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
7515 let vnodeHook;
7516 if (shouldInvokeVnodeHook &&
7517 (vnodeHook = props && props.onVnodeBeforeUnmount)) {
7518 invokeVNodeHook(vnodeHook, parentComponent, vnode);
7519 }
7520 if (shapeFlag & 6 /* COMPONENT */) {
7521 unmountComponent(vnode.component, parentSuspense, doRemove);
7522 }
7523 else {
7524 if (shapeFlag & 128 /* SUSPENSE */) {
7525 vnode.suspense.unmount(parentSuspense, doRemove);
7526 return;
7527 }
7528 if (shouldInvokeDirs) {
7529 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
7530 }
7531 if (shapeFlag & 64 /* TELEPORT */) {
7532 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
7533 }
7534 else if (dynamicChildren &&
7535 // #1153: fast path should not be taken for non-stable (v-for) fragments
7536 (type !== Fragment ||
7537 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
7538 // fast path for block nodes: only need to unmount dynamic children.
7539 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
7540 }
7541 else if ((type === Fragment &&
7542 patchFlag &
7543 (128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) ||
7544 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
7545 unmountChildren(children, parentComponent, parentSuspense);
7546 }
7547 if (doRemove) {
7548 remove(vnode);
7549 }
7550 }
7551 if ((shouldInvokeVnodeHook &&
7552 (vnodeHook = props && props.onVnodeUnmounted)) ||
7553 shouldInvokeDirs) {
7554 queuePostRenderEffect(() => {
7555 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
7556 shouldInvokeDirs &&
7557 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
7558 }, parentSuspense);
7559 }
7560 };
7561 const remove = vnode => {
7562 const { type, el, anchor, transition } = vnode;
7563 if (type === Fragment) {
7564 if (vnode.patchFlag > 0 &&
7565 vnode.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */ &&
7566 transition &&
7567 !transition.persisted) {
7568 vnode.children.forEach(child => {
7569 if (child.type === Comment) {
7570 hostRemove(child.el);
7571 }
7572 else {
7573 remove(child);
7574 }
7575 });
7576 }
7577 else {
7578 removeFragment(el, anchor);
7579 }
7580 return;
7581 }
7582 if (type === Static) {
7583 removeStaticNode(vnode);
7584 return;
7585 }
7586 const performRemove = () => {
7587 hostRemove(el);
7588 if (transition && !transition.persisted && transition.afterLeave) {
7589 transition.afterLeave();
7590 }
7591 };
7592 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
7593 transition &&
7594 !transition.persisted) {
7595 const { leave, delayLeave } = transition;
7596 const performLeave = () => leave(el, performRemove);
7597 if (delayLeave) {
7598 delayLeave(vnode.el, performRemove, performLeave);
7599 }
7600 else {
7601 performLeave();
7602 }
7603 }
7604 else {
7605 performRemove();
7606 }
7607 };
7608 const removeFragment = (cur, end) => {
7609 // For fragments, directly remove all contained DOM nodes.
7610 // (fragment child nodes cannot have transition)
7611 let next;
7612 while (cur !== end) {
7613 next = hostNextSibling(cur);
7614 hostRemove(cur);
7615 cur = next;
7616 }
7617 hostRemove(end);
7618 };
7619 const unmountComponent = (instance, parentSuspense, doRemove) => {
7620 if (instance.type.__hmrId) {
7621 unregisterHMR(instance);
7622 }
7623 const { bum, scope, update, subTree, um } = instance;
7624 // beforeUnmount hook
7625 if (bum) {
7626 invokeArrayFns(bum);
7627 }
7628 // stop effects in component scope
7629 scope.stop();
7630 // update may be null if a component is unmounted before its async
7631 // setup has resolved.
7632 if (update) {
7633 // so that scheduler will no longer invoke it
7634 update.active = false;
7635 unmount(subTree, instance, parentSuspense, doRemove);
7636 }
7637 // unmounted hook
7638 if (um) {
7639 queuePostRenderEffect(um, parentSuspense);
7640 }
7641 queuePostRenderEffect(() => {
7642 instance.isUnmounted = true;
7643 }, parentSuspense);
7644 // A component with async dep inside a pending suspense is unmounted before
7645 // its async dep resolves. This should remove the dep from the suspense, and
7646 // cause the suspense to resolve immediately if that was the last dep.
7647 if (parentSuspense &&
7648 parentSuspense.pendingBranch &&
7649 !parentSuspense.isUnmounted &&
7650 instance.asyncDep &&
7651 !instance.asyncResolved &&
7652 instance.suspenseId === parentSuspense.pendingId) {
7653 parentSuspense.deps--;
7654 if (parentSuspense.deps === 0) {
7655 parentSuspense.resolve();
7656 }
7657 }
7658 {
7659 devtoolsComponentRemoved(instance);
7660 }
7661 };
7662 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
7663 for (let i = start; i < children.length; i++) {
7664 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
7665 }
7666 };
7667 const getNextHostNode = vnode => {
7668 if (vnode.shapeFlag & 6 /* COMPONENT */) {
7669 return getNextHostNode(vnode.component.subTree);
7670 }
7671 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
7672 return vnode.suspense.next();
7673 }
7674 return hostNextSibling((vnode.anchor || vnode.el));
7675 };
7676 const render = (vnode, container, isSVG) => {
7677 if (vnode == null) {
7678 if (container._vnode) {
7679 unmount(container._vnode, null, null, true);
7680 }
7681 }
7682 else {
7683 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
7684 }
7685 flushPostFlushCbs();
7686 container._vnode = vnode;
7687 };
7688 const internals = {
7689 p: patch,
7690 um: unmount,
7691 m: move,
7692 r: remove,
7693 mt: mountComponent,
7694 mc: mountChildren,
7695 pc: patchChildren,
7696 pbc: patchBlockChildren,
7697 n: getNextHostNode,
7698 o: options
7699 };
7700 let hydrate;
7701 let hydrateNode;
7702 if (createHydrationFns) {
7703 [hydrate, hydrateNode] = createHydrationFns(internals);
7704 }
7705 return {
7706 render,
7707 hydrate,
7708 createApp: createAppAPI(render, hydrate)
7709 };
7710}
7711function toggleRecurse({ effect, update }, allowed) {
7712 effect.allowRecurse = update.allowRecurse = allowed;
7713}
7714/**
7715 * #1156
7716 * When a component is HMR-enabled, we need to make sure that all static nodes
7717 * inside a block also inherit the DOM element from the previous tree so that
7718 * HMR updates (which are full updates) can retrieve the element for patching.
7719 *
7720 * #2080
7721 * Inside keyed `template` fragment static children, if a fragment is moved,
7722 * the children will always be moved. Therefore, in order to ensure correct move
7723 * position, el should be inherited from previous nodes.
7724 */
7725function traverseStaticChildren(n1, n2, shallow = false) {
7726 const ch1 = n1.children;
7727 const ch2 = n2.children;
7728 if (isArray(ch1) && isArray(ch2)) {
7729 for (let i = 0; i < ch1.length; i++) {
7730 // this is only called in the optimized path so array children are
7731 // guaranteed to be vnodes
7732 const c1 = ch1[i];
7733 let c2 = ch2[i];
7734 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
7735 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
7736 c2 = ch2[i] = cloneIfMounted(ch2[i]);
7737 c2.el = c1.el;
7738 }
7739 if (!shallow)
7740 traverseStaticChildren(c1, c2);
7741 }
7742 // also inherit for comment nodes, but not placeholders (e.g. v-if which
7743 // would have received .el during block patch)
7744 if (c2.type === Comment && !c2.el) {
7745 c2.el = c1.el;
7746 }
7747 }
7748 }
7749}
7750// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
7751function getSequence(arr) {
7752 const p = arr.slice();
7753 const result = [0];
7754 let i, j, u, v, c;
7755 const len = arr.length;
7756 for (i = 0; i < len; i++) {
7757 const arrI = arr[i];
7758 if (arrI !== 0) {
7759 j = result[result.length - 1];
7760 if (arr[j] < arrI) {
7761 p[i] = j;
7762 result.push(i);
7763 continue;
7764 }
7765 u = 0;
7766 v = result.length - 1;
7767 while (u < v) {
7768 c = (u + v) >> 1;
7769 if (arr[result[c]] < arrI) {
7770 u = c + 1;
7771 }
7772 else {
7773 v = c;
7774 }
7775 }
7776 if (arrI < arr[result[u]]) {
7777 if (u > 0) {
7778 p[i] = result[u - 1];
7779 }
7780 result[u] = i;
7781 }
7782 }
7783 }
7784 u = result.length;
7785 v = result[u - 1];
7786 while (u-- > 0) {
7787 result[u] = v;
7788 v = p[v];
7789 }
7790 return result;
7791}
7792
7793const isTeleport = (type) => type.__isTeleport;
7794const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
7795const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
7796const resolveTarget = (props, select) => {
7797 const targetSelector = props && props.to;
7798 if (isString(targetSelector)) {
7799 if (!select) {
7800 warn$1(`Current renderer does not support string target for Teleports. ` +
7801 `(missing querySelector renderer option)`);
7802 return null;
7803 }
7804 else {
7805 const target = select(targetSelector);
7806 if (!target) {
7807 warn$1(`Failed to locate Teleport target with selector "${targetSelector}". ` +
7808 `Note the target element must exist before the component is mounted - ` +
7809 `i.e. the target cannot be rendered by the component itself, and ` +
7810 `ideally should be outside of the entire Vue component tree.`);
7811 }
7812 return target;
7813 }
7814 }
7815 else {
7816 if (!targetSelector && !isTeleportDisabled(props)) {
7817 warn$1(`Invalid Teleport target: ${targetSelector}`);
7818 }
7819 return targetSelector;
7820 }
7821};
7822const TeleportImpl = {
7823 __isTeleport: true,
7824 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
7825 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
7826 const disabled = isTeleportDisabled(n2.props);
7827 let { shapeFlag, children, dynamicChildren } = n2;
7828 // #3302
7829 // HMR updated, force full diff
7830 if (isHmrUpdating) {
7831 optimized = false;
7832 dynamicChildren = null;
7833 }
7834 if (n1 == null) {
7835 // insert anchors in the main view
7836 const placeholder = (n2.el = createComment('teleport start')
7837 );
7838 const mainAnchor = (n2.anchor = createComment('teleport end')
7839 );
7840 insert(placeholder, container, anchor);
7841 insert(mainAnchor, container, anchor);
7842 const target = (n2.target = resolveTarget(n2.props, querySelector));
7843 const targetAnchor = (n2.targetAnchor = createText(''));
7844 if (target) {
7845 insert(targetAnchor, target);
7846 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
7847 isSVG = isSVG || isTargetSVG(target);
7848 }
7849 else if (!disabled) {
7850 warn$1('Invalid Teleport target on mount:', target, `(${typeof target})`);
7851 }
7852 const mount = (container, anchor) => {
7853 // Teleport *always* has Array children. This is enforced in both the
7854 // compiler and vnode children normalization.
7855 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7856 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7857 }
7858 };
7859 if (disabled) {
7860 mount(container, mainAnchor);
7861 }
7862 else if (target) {
7863 mount(target, targetAnchor);
7864 }
7865 }
7866 else {
7867 // update content
7868 n2.el = n1.el;
7869 const mainAnchor = (n2.anchor = n1.anchor);
7870 const target = (n2.target = n1.target);
7871 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
7872 const wasDisabled = isTeleportDisabled(n1.props);
7873 const currentContainer = wasDisabled ? container : target;
7874 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
7875 isSVG = isSVG || isTargetSVG(target);
7876 if (dynamicChildren) {
7877 // fast path when the teleport happens to be a block root
7878 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
7879 // even in block tree mode we need to make sure all root-level nodes
7880 // in the teleport inherit previous DOM references so that they can
7881 // be moved in future patches.
7882 traverseStaticChildren(n1, n2, true);
7883 }
7884 else if (!optimized) {
7885 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
7886 }
7887 if (disabled) {
7888 if (!wasDisabled) {
7889 // enabled -> disabled
7890 // move into main container
7891 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
7892 }
7893 }
7894 else {
7895 // target changed
7896 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
7897 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
7898 if (nextTarget) {
7899 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
7900 }
7901 else {
7902 warn$1('Invalid Teleport target on update:', target, `(${typeof target})`);
7903 }
7904 }
7905 else if (wasDisabled) {
7906 // disabled -> enabled
7907 // move into teleport target
7908 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
7909 }
7910 }
7911 }
7912 },
7913 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
7914 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
7915 if (target) {
7916 hostRemove(targetAnchor);
7917 }
7918 // an unmounted teleport should always remove its children if not disabled
7919 if (doRemove || !isTeleportDisabled(props)) {
7920 hostRemove(anchor);
7921 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7922 for (let i = 0; i < children.length; i++) {
7923 const child = children[i];
7924 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
7925 }
7926 }
7927 }
7928 },
7929 move: moveTeleport,
7930 hydrate: hydrateTeleport
7931};
7932function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
7933 // move target anchor if this is a target change.
7934 if (moveType === 0 /* TARGET_CHANGE */) {
7935 insert(vnode.targetAnchor, container, parentAnchor);
7936 }
7937 const { el, anchor, shapeFlag, children, props } = vnode;
7938 const isReorder = moveType === 2 /* REORDER */;
7939 // move main view anchor if this is a re-order.
7940 if (isReorder) {
7941 insert(el, container, parentAnchor);
7942 }
7943 // if this is a re-order and teleport is enabled (content is in target)
7944 // do not move children. So the opposite is: only move children if this
7945 // is not a reorder, or the teleport is disabled
7946 if (!isReorder || isTeleportDisabled(props)) {
7947 // Teleport has either Array children or no children.
7948 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7949 for (let i = 0; i < children.length; i++) {
7950 move(children[i], container, parentAnchor, 2 /* REORDER */);
7951 }
7952 }
7953 }
7954 // move main view anchor if this is a re-order.
7955 if (isReorder) {
7956 insert(anchor, container, parentAnchor);
7957 }
7958}
7959function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
7960 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
7961 if (target) {
7962 // if multiple teleports rendered to the same target element, we need to
7963 // pick up from where the last teleport finished instead of the first node
7964 const targetNode = target._lpa || target.firstChild;
7965 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
7966 if (isTeleportDisabled(vnode.props)) {
7967 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
7968 vnode.targetAnchor = targetNode;
7969 }
7970 else {
7971 vnode.anchor = nextSibling(node);
7972 // lookahead until we find the target anchor
7973 // we cannot rely on return value of hydrateChildren() because there
7974 // could be nested teleports
7975 let targetAnchor = targetNode;
7976 while (targetAnchor) {
7977 targetAnchor = nextSibling(targetAnchor);
7978 if (targetAnchor &&
7979 targetAnchor.nodeType === 8 &&
7980 targetAnchor.data === 'teleport anchor') {
7981 vnode.targetAnchor = targetAnchor;
7982 target._lpa =
7983 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
7984 break;
7985 }
7986 }
7987 hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
7988 }
7989 }
7990 }
7991 return vnode.anchor && nextSibling(vnode.anchor);
7992}
7993// Force-casted public typing for h and TSX props inference
7994const Teleport = TeleportImpl;
7995
7996const Fragment = Symbol('Fragment' );
7997const Text = Symbol('Text' );
7998const Comment = Symbol('Comment' );
7999const Static = Symbol('Static' );
8000// Since v-if and v-for are the two possible ways node structure can dynamically
8001// change, once we consider v-if branches and each v-for fragment a block, we
8002// can divide a template into nested blocks, and within each block the node
8003// structure would be stable. This allows us to skip most children diffing
8004// and only worry about the dynamic nodes (indicated by patch flags).
8005const blockStack = [];
8006let currentBlock = null;
8007/**
8008 * Open a block.
8009 * This must be called before `createBlock`. It cannot be part of `createBlock`
8010 * because the children of the block are evaluated before `createBlock` itself
8011 * is called. The generated code typically looks like this:
8012 *
8013 * ```js
8014 * function render() {
8015 * return (openBlock(),createBlock('div', null, [...]))
8016 * }
8017 * ```
8018 * disableTracking is true when creating a v-for fragment block, since a v-for
8019 * fragment always diffs its children.
8020 *
8021 * @private
8022 */
8023function openBlock(disableTracking = false) {
8024 blockStack.push((currentBlock = disableTracking ? null : []));
8025}
8026function closeBlock() {
8027 blockStack.pop();
8028 currentBlock = blockStack[blockStack.length - 1] || null;
8029}
8030// Whether we should be tracking dynamic child nodes inside a block.
8031// Only tracks when this value is > 0
8032// We are not using a simple boolean because this value may need to be
8033// incremented/decremented by nested usage of v-once (see below)
8034let isBlockTreeEnabled = 1;
8035/**
8036 * Block tracking sometimes needs to be disabled, for example during the
8037 * creation of a tree that needs to be cached by v-once. The compiler generates
8038 * code like this:
8039 *
8040 * ``` js
8041 * _cache[1] || (
8042 * setBlockTracking(-1),
8043 * _cache[1] = createVNode(...),
8044 * setBlockTracking(1),
8045 * _cache[1]
8046 * )
8047 * ```
8048 *
8049 * @private
8050 */
8051function setBlockTracking(value) {
8052 isBlockTreeEnabled += value;
8053}
8054function setupBlock(vnode) {
8055 // save current block children on the block vnode
8056 vnode.dynamicChildren =
8057 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
8058 // close block
8059 closeBlock();
8060 // a block is always going to be patched, so track it as a child of its
8061 // parent block
8062 if (isBlockTreeEnabled > 0 && currentBlock) {
8063 currentBlock.push(vnode);
8064 }
8065 return vnode;
8066}
8067/**
8068 * @private
8069 */
8070function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
8071 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
8072}
8073/**
8074 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
8075 * A block root keeps track of dynamic nodes within the block in the
8076 * `dynamicChildren` array.
8077 *
8078 * @private
8079 */
8080function createBlock(type, props, children, patchFlag, dynamicProps) {
8081 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
8082}
8083function isVNode(value) {
8084 return value ? value.__v_isVNode === true : false;
8085}
8086function isSameVNodeType(n1, n2) {
8087 if (n2.shapeFlag & 6 /* COMPONENT */ &&
8088 hmrDirtyComponents.has(n2.type)) {
8089 // HMR only: if the component has been hot-updated, force a reload.
8090 return false;
8091 }
8092 return n1.type === n2.type && n1.key === n2.key;
8093}
8094let vnodeArgsTransformer;
8095/**
8096 * Internal API for registering an arguments transform for createVNode
8097 * used for creating stubs in the test-utils
8098 * It is *internal* but needs to be exposed for test-utils to pick up proper
8099 * typings
8100 */
8101function transformVNodeArgs(transformer) {
8102 vnodeArgsTransformer = transformer;
8103}
8104const createVNodeWithArgsTransform = (...args) => {
8105 return _createVNode(...(vnodeArgsTransformer
8106 ? vnodeArgsTransformer(args, currentRenderingInstance)
8107 : args));
8108};
8109const InternalObjectKey = `__vInternal`;
8110const normalizeKey = ({ key }) => key != null ? key : null;
8111const normalizeRef = ({ ref, ref_key, ref_for }) => {
8112 return (ref != null
8113 ? isString(ref) || isRef(ref) || isFunction(ref)
8114 ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8115 : ref
8116 : null);
8117};
8118function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
8119 const vnode = {
8120 __v_isVNode: true,
8121 __v_skip: true,
8122 type,
8123 props,
8124 key: props && normalizeKey(props),
8125 ref: props && normalizeRef(props),
8126 scopeId: currentScopeId,
8127 slotScopeIds: null,
8128 children,
8129 component: null,
8130 suspense: null,
8131 ssContent: null,
8132 ssFallback: null,
8133 dirs: null,
8134 transition: null,
8135 el: null,
8136 anchor: null,
8137 target: null,
8138 targetAnchor: null,
8139 staticCount: 0,
8140 shapeFlag,
8141 patchFlag,
8142 dynamicProps,
8143 dynamicChildren: null,
8144 appContext: null
8145 };
8146 if (needFullChildrenNormalization) {
8147 normalizeChildren(vnode, children);
8148 // normalize suspense children
8149 if (shapeFlag & 128 /* SUSPENSE */) {
8150 type.normalize(vnode);
8151 }
8152 }
8153 else if (children) {
8154 // compiled element vnode - if children is passed, only possible types are
8155 // string or Array.
8156 vnode.shapeFlag |= isString(children)
8157 ? 8 /* TEXT_CHILDREN */
8158 : 16 /* ARRAY_CHILDREN */;
8159 }
8160 // validate key
8161 if (vnode.key !== vnode.key) {
8162 warn$1(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
8163 }
8164 // track vnode for block tree
8165 if (isBlockTreeEnabled > 0 &&
8166 // avoid a block node from tracking itself
8167 !isBlockNode &&
8168 // has current parent block
8169 currentBlock &&
8170 // presence of a patch flag indicates this node needs patching on updates.
8171 // component nodes also should always be patched, because even if the
8172 // component doesn't need to update, it needs to persist the instance on to
8173 // the next vnode so that it can be properly unmounted later.
8174 (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
8175 // the EVENTS flag is only for hydration and if it is the only flag, the
8176 // vnode should not be considered dynamic due to handler caching.
8177 vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
8178 currentBlock.push(vnode);
8179 }
8180 return vnode;
8181}
8182const createVNode = (createVNodeWithArgsTransform );
8183function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
8184 if (!type || type === NULL_DYNAMIC_COMPONENT) {
8185 if (!type) {
8186 warn$1(`Invalid vnode type when creating vnode: ${type}.`);
8187 }
8188 type = Comment;
8189 }
8190 if (isVNode(type)) {
8191 // createVNode receiving an existing vnode. This happens in cases like
8192 // <component :is="vnode"/>
8193 // #2078 make sure to merge refs during the clone instead of overwriting it
8194 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
8195 if (children) {
8196 normalizeChildren(cloned, children);
8197 }
8198 if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) {
8199 if (cloned.shapeFlag & 6 /* COMPONENT */) {
8200 currentBlock[currentBlock.indexOf(type)] = cloned;
8201 }
8202 else {
8203 currentBlock.push(cloned);
8204 }
8205 }
8206 cloned.patchFlag |= -2 /* BAIL */;
8207 return cloned;
8208 }
8209 // class component normalization.
8210 if (isClassComponent(type)) {
8211 type = type.__vccOpts;
8212 }
8213 // class & style normalization.
8214 if (props) {
8215 // for reactive or proxy objects, we need to clone it to enable mutation.
8216 props = guardReactiveProps(props);
8217 let { class: klass, style } = props;
8218 if (klass && !isString(klass)) {
8219 props.class = normalizeClass(klass);
8220 }
8221 if (isObject(style)) {
8222 // reactive state objects need to be cloned since they are likely to be
8223 // mutated
8224 if (isProxy(style) && !isArray(style)) {
8225 style = extend({}, style);
8226 }
8227 props.style = normalizeStyle(style);
8228 }
8229 }
8230 // encode the vnode type information into a bitmap
8231 const shapeFlag = isString(type)
8232 ? 1 /* ELEMENT */
8233 : isSuspense(type)
8234 ? 128 /* SUSPENSE */
8235 : isTeleport(type)
8236 ? 64 /* TELEPORT */
8237 : isObject(type)
8238 ? 4 /* STATEFUL_COMPONENT */
8239 : isFunction(type)
8240 ? 2 /* FUNCTIONAL_COMPONENT */
8241 : 0;
8242 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
8243 type = toRaw(type);
8244 warn$1(`Vue received a Component which was made a reactive object. This can ` +
8245 `lead to unnecessary performance overhead, and should be avoided by ` +
8246 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
8247 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
8248 }
8249 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
8250}
8251function guardReactiveProps(props) {
8252 if (!props)
8253 return null;
8254 return isProxy(props) || InternalObjectKey in props
8255 ? extend({}, props)
8256 : props;
8257}
8258function cloneVNode(vnode, extraProps, mergeRef = false) {
8259 // This is intentionally NOT using spread or extend to avoid the runtime
8260 // key enumeration cost.
8261 const { props, ref, patchFlag, children } = vnode;
8262 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
8263 const cloned = {
8264 __v_isVNode: true,
8265 __v_skip: true,
8266 type: vnode.type,
8267 props: mergedProps,
8268 key: mergedProps && normalizeKey(mergedProps),
8269 ref: extraProps && extraProps.ref
8270 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
8271 // if the vnode itself already has a ref, cloneVNode will need to merge
8272 // the refs so the single vnode can be set on multiple refs
8273 mergeRef && ref
8274 ? isArray(ref)
8275 ? ref.concat(normalizeRef(extraProps))
8276 : [ref, normalizeRef(extraProps)]
8277 : normalizeRef(extraProps)
8278 : ref,
8279 scopeId: vnode.scopeId,
8280 slotScopeIds: vnode.slotScopeIds,
8281 children: patchFlag === -1 /* HOISTED */ && isArray(children)
8282 ? children.map(deepCloneVNode)
8283 : children,
8284 target: vnode.target,
8285 targetAnchor: vnode.targetAnchor,
8286 staticCount: vnode.staticCount,
8287 shapeFlag: vnode.shapeFlag,
8288 // if the vnode is cloned with extra props, we can no longer assume its
8289 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
8290 // note: preserve flag for fragments since they use the flag for children
8291 // fast paths only.
8292 patchFlag: extraProps && vnode.type !== Fragment
8293 ? patchFlag === -1 // hoisted node
8294 ? 16 /* FULL_PROPS */
8295 : patchFlag | 16 /* FULL_PROPS */
8296 : patchFlag,
8297 dynamicProps: vnode.dynamicProps,
8298 dynamicChildren: vnode.dynamicChildren,
8299 appContext: vnode.appContext,
8300 dirs: vnode.dirs,
8301 transition: vnode.transition,
8302 // These should technically only be non-null on mounted VNodes. However,
8303 // they *should* be copied for kept-alive vnodes. So we just always copy
8304 // them since them being non-null during a mount doesn't affect the logic as
8305 // they will simply be overwritten.
8306 component: vnode.component,
8307 suspense: vnode.suspense,
8308 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
8309 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
8310 el: vnode.el,
8311 anchor: vnode.anchor
8312 };
8313 return cloned;
8314}
8315/**
8316 * Dev only, for HMR of hoisted vnodes reused in v-for
8317 * https://github.com/vitejs/vite/issues/2022
8318 */
8319function deepCloneVNode(vnode) {
8320 const cloned = cloneVNode(vnode);
8321 if (isArray(vnode.children)) {
8322 cloned.children = vnode.children.map(deepCloneVNode);
8323 }
8324 return cloned;
8325}
8326/**
8327 * @private
8328 */
8329function createTextVNode(text = ' ', flag = 0) {
8330 return createVNode(Text, null, text, flag);
8331}
8332/**
8333 * @private
8334 */
8335function createStaticVNode(content, numberOfNodes) {
8336 // A static vnode can contain multiple stringified elements, and the number
8337 // of elements is necessary for hydration.
8338 const vnode = createVNode(Static, null, content);
8339 vnode.staticCount = numberOfNodes;
8340 return vnode;
8341}
8342/**
8343 * @private
8344 */
8345function createCommentVNode(text = '',
8346// when used as the v-else branch, the comment node must be created as a
8347// block to ensure correct updates.
8348asBlock = false) {
8349 return asBlock
8350 ? (openBlock(), createBlock(Comment, null, text))
8351 : createVNode(Comment, null, text);
8352}
8353function normalizeVNode(child) {
8354 if (child == null || typeof child === 'boolean') {
8355 // empty placeholder
8356 return createVNode(Comment);
8357 }
8358 else if (isArray(child)) {
8359 // fragment
8360 return createVNode(Fragment, null,
8361 // #3666, avoid reference pollution when reusing vnode
8362 child.slice());
8363 }
8364 else if (typeof child === 'object') {
8365 // already vnode, this should be the most common since compiled templates
8366 // always produce all-vnode children arrays
8367 return cloneIfMounted(child);
8368 }
8369 else {
8370 // strings and numbers
8371 return createVNode(Text, null, String(child));
8372 }
8373}
8374// optimized normalization for template-compiled render fns
8375function cloneIfMounted(child) {
8376 return child.el === null || child.memo ? child : cloneVNode(child);
8377}
8378function normalizeChildren(vnode, children) {
8379 let type = 0;
8380 const { shapeFlag } = vnode;
8381 if (children == null) {
8382 children = null;
8383 }
8384 else if (isArray(children)) {
8385 type = 16 /* ARRAY_CHILDREN */;
8386 }
8387 else if (typeof children === 'object') {
8388 if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
8389 // Normalize slot to plain children for plain element and Teleport
8390 const slot = children.default;
8391 if (slot) {
8392 // _c marker is added by withCtx() indicating this is a compiled slot
8393 slot._c && (slot._d = false);
8394 normalizeChildren(vnode, slot());
8395 slot._c && (slot._d = true);
8396 }
8397 return;
8398 }
8399 else {
8400 type = 32 /* SLOTS_CHILDREN */;
8401 const slotFlag = children._;
8402 if (!slotFlag && !(InternalObjectKey in children)) {
8403 children._ctx = currentRenderingInstance;
8404 }
8405 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
8406 // a child component receives forwarded slots from the parent.
8407 // its slot type is determined by its parent's slot type.
8408 if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
8409 children._ = 1 /* STABLE */;
8410 }
8411 else {
8412 children._ = 2 /* DYNAMIC */;
8413 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
8414 }
8415 }
8416 }
8417 }
8418 else if (isFunction(children)) {
8419 children = { default: children, _ctx: currentRenderingInstance };
8420 type = 32 /* SLOTS_CHILDREN */;
8421 }
8422 else {
8423 children = String(children);
8424 // force teleport children to array so it can be moved around
8425 if (shapeFlag & 64 /* TELEPORT */) {
8426 type = 16 /* ARRAY_CHILDREN */;
8427 children = [createTextVNode(children)];
8428 }
8429 else {
8430 type = 8 /* TEXT_CHILDREN */;
8431 }
8432 }
8433 vnode.children = children;
8434 vnode.shapeFlag |= type;
8435}
8436function mergeProps(...args) {
8437 const ret = {};
8438 for (let i = 0; i < args.length; i++) {
8439 const toMerge = args[i];
8440 for (const key in toMerge) {
8441 if (key === 'class') {
8442 if (ret.class !== toMerge.class) {
8443 ret.class = normalizeClass([ret.class, toMerge.class]);
8444 }
8445 }
8446 else if (key === 'style') {
8447 ret.style = normalizeStyle([ret.style, toMerge.style]);
8448 }
8449 else if (isOn(key)) {
8450 const existing = ret[key];
8451 const incoming = toMerge[key];
8452 if (incoming &&
8453 existing !== incoming &&
8454 !(isArray(existing) && existing.includes(incoming))) {
8455 ret[key] = existing
8456 ? [].concat(existing, incoming)
8457 : incoming;
8458 }
8459 }
8460 else if (key !== '') {
8461 ret[key] = toMerge[key];
8462 }
8463 }
8464 }
8465 return ret;
8466}
8467function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8468 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
8469 vnode,
8470 prevVNode
8471 ]);
8472}
8473
8474const emptyAppContext = createAppContext();
8475let uid$1 = 0;
8476function createComponentInstance(vnode, parent, suspense) {
8477 const type = vnode.type;
8478 // inherit parent app context - or - if root, adopt from root vnode
8479 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
8480 const instance = {
8481 uid: uid$1++,
8482 vnode,
8483 type,
8484 parent,
8485 appContext,
8486 root: null,
8487 next: null,
8488 subTree: null,
8489 effect: null,
8490 update: null,
8491 scope: new EffectScope(true /* detached */),
8492 render: null,
8493 proxy: null,
8494 exposed: null,
8495 exposeProxy: null,
8496 withProxy: null,
8497 provides: parent ? parent.provides : Object.create(appContext.provides),
8498 accessCache: null,
8499 renderCache: [],
8500 // local resolved assets
8501 components: null,
8502 directives: null,
8503 // resolved props and emits options
8504 propsOptions: normalizePropsOptions(type, appContext),
8505 emitsOptions: normalizeEmitsOptions(type, appContext),
8506 // emit
8507 emit: null,
8508 emitted: null,
8509 // props default value
8510 propsDefaults: EMPTY_OBJ,
8511 // inheritAttrs
8512 inheritAttrs: type.inheritAttrs,
8513 // state
8514 ctx: EMPTY_OBJ,
8515 data: EMPTY_OBJ,
8516 props: EMPTY_OBJ,
8517 attrs: EMPTY_OBJ,
8518 slots: EMPTY_OBJ,
8519 refs: EMPTY_OBJ,
8520 setupState: EMPTY_OBJ,
8521 setupContext: null,
8522 // suspense related
8523 suspense,
8524 suspenseId: suspense ? suspense.pendingId : 0,
8525 asyncDep: null,
8526 asyncResolved: false,
8527 // lifecycle hooks
8528 // not using enums here because it results in computed properties
8529 isMounted: false,
8530 isUnmounted: false,
8531 isDeactivated: false,
8532 bc: null,
8533 c: null,
8534 bm: null,
8535 m: null,
8536 bu: null,
8537 u: null,
8538 um: null,
8539 bum: null,
8540 da: null,
8541 a: null,
8542 rtg: null,
8543 rtc: null,
8544 ec: null,
8545 sp: null
8546 };
8547 {
8548 instance.ctx = createDevRenderContext(instance);
8549 }
8550 instance.root = parent ? parent.root : instance;
8551 instance.emit = emit$1.bind(null, instance);
8552 // apply custom element special handling
8553 if (vnode.ce) {
8554 vnode.ce(instance);
8555 }
8556 return instance;
8557}
8558let currentInstance = null;
8559const getCurrentInstance = () => currentInstance || currentRenderingInstance;
8560const setCurrentInstance = (instance) => {
8561 currentInstance = instance;
8562 instance.scope.on();
8563};
8564const unsetCurrentInstance = () => {
8565 currentInstance && currentInstance.scope.off();
8566 currentInstance = null;
8567};
8568const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
8569function validateComponentName(name, config) {
8570 const appIsNativeTag = config.isNativeTag || NO;
8571 if (isBuiltInTag(name) || appIsNativeTag(name)) {
8572 warn$1('Do not use built-in or reserved HTML elements as component id: ' + name);
8573 }
8574}
8575function isStatefulComponent(instance) {
8576 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
8577}
8578let isInSSRComponentSetup = false;
8579function setupComponent(instance, isSSR = false) {
8580 isInSSRComponentSetup = isSSR;
8581 const { props, children } = instance.vnode;
8582 const isStateful = isStatefulComponent(instance);
8583 initProps(instance, props, isStateful, isSSR);
8584 initSlots(instance, children);
8585 const setupResult = isStateful
8586 ? setupStatefulComponent(instance, isSSR)
8587 : undefined;
8588 isInSSRComponentSetup = false;
8589 return setupResult;
8590}
8591function setupStatefulComponent(instance, isSSR) {
8592 var _a;
8593 const Component = instance.type;
8594 {
8595 if (Component.name) {
8596 validateComponentName(Component.name, instance.appContext.config);
8597 }
8598 if (Component.components) {
8599 const names = Object.keys(Component.components);
8600 for (let i = 0; i < names.length; i++) {
8601 validateComponentName(names[i], instance.appContext.config);
8602 }
8603 }
8604 if (Component.directives) {
8605 const names = Object.keys(Component.directives);
8606 for (let i = 0; i < names.length; i++) {
8607 validateDirectiveName(names[i]);
8608 }
8609 }
8610 if (Component.compilerOptions && isRuntimeOnly()) {
8611 warn$1(`"compilerOptions" is only supported when using a build of Vue that ` +
8612 `includes the runtime compiler. Since you are using a runtime-only ` +
8613 `build, the options should be passed via your build tool config instead.`);
8614 }
8615 }
8616 // 0. create render proxy property access cache
8617 instance.accessCache = Object.create(null);
8618 // 1. create public instance / render proxy
8619 // also mark it raw so it's never observed
8620 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
8621 {
8622 exposePropsOnRenderContext(instance);
8623 }
8624 // 2. call setup()
8625 const { setup } = Component;
8626 if (setup) {
8627 const setupContext = (instance.setupContext =
8628 setup.length > 1 ? createSetupContext(instance) : null);
8629 setCurrentInstance(instance);
8630 pauseTracking();
8631 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
8632 resetTracking();
8633 unsetCurrentInstance();
8634 if (isPromise(setupResult)) {
8635 setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
8636 if (isSSR) {
8637 // return the promise so server-renderer can wait on it
8638 return setupResult
8639 .then((resolvedResult) => {
8640 handleSetupResult(instance, resolvedResult, isSSR);
8641 })
8642 .catch(e => {
8643 handleError(e, instance, 0 /* SETUP_FUNCTION */);
8644 });
8645 }
8646 else {
8647 // async setup returned Promise.
8648 // bail here and wait for re-entry.
8649 instance.asyncDep = setupResult;
8650 if (!instance.suspense) {
8651 const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
8652 warn$1(`Component <${name}>: setup function returned a promise, but no ` +
8653 `<Suspense> boundary was found in the parent component tree. ` +
8654 `A component with async setup() must be nested in a <Suspense> ` +
8655 `in order to be rendered.`);
8656 }
8657 }
8658 }
8659 else {
8660 handleSetupResult(instance, setupResult, isSSR);
8661 }
8662 }
8663 else {
8664 finishComponentSetup(instance, isSSR);
8665 }
8666}
8667function handleSetupResult(instance, setupResult, isSSR) {
8668 if (isFunction(setupResult)) {
8669 // setup returned an inline render function
8670 {
8671 instance.render = setupResult;
8672 }
8673 }
8674 else if (isObject(setupResult)) {
8675 if (isVNode(setupResult)) {
8676 warn$1(`setup() should not return VNodes directly - ` +
8677 `return a render function instead.`);
8678 }
8679 // setup returned bindings.
8680 // assuming a render function compiled from template is present.
8681 {
8682 instance.devtoolsRawSetupState = setupResult;
8683 }
8684 instance.setupState = proxyRefs(setupResult);
8685 {
8686 exposeSetupStateOnRenderContext(instance);
8687 }
8688 }
8689 else if (setupResult !== undefined) {
8690 warn$1(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
8691 }
8692 finishComponentSetup(instance, isSSR);
8693}
8694let compile;
8695let installWithProxy;
8696/**
8697 * For runtime-dom to register the compiler.
8698 * Note the exported method uses any to avoid d.ts relying on the compiler types.
8699 */
8700function registerRuntimeCompiler(_compile) {
8701 compile = _compile;
8702 installWithProxy = i => {
8703 if (i.render._rc) {
8704 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
8705 }
8706 };
8707}
8708// dev only
8709const isRuntimeOnly = () => !compile;
8710function finishComponentSetup(instance, isSSR, skipOptions) {
8711 const Component = instance.type;
8712 // template / render function normalization
8713 // could be already set when returned from setup()
8714 if (!instance.render) {
8715 // only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
8716 // is done by server-renderer
8717 if (!isSSR && compile && !Component.render) {
8718 const template = Component.template;
8719 if (template) {
8720 {
8721 startMeasure(instance, `compile`);
8722 }
8723 const { isCustomElement, compilerOptions } = instance.appContext.config;
8724 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
8725 const finalCompilerOptions = extend(extend({
8726 isCustomElement,
8727 delimiters
8728 }, compilerOptions), componentCompilerOptions);
8729 Component.render = compile(template, finalCompilerOptions);
8730 {
8731 endMeasure(instance, `compile`);
8732 }
8733 }
8734 }
8735 instance.render = (Component.render || NOOP);
8736 // for runtime-compiled render functions using `with` blocks, the render
8737 // proxy used needs a different `has` handler which is more performant and
8738 // also only allows a whitelist of globals to fallthrough.
8739 if (installWithProxy) {
8740 installWithProxy(instance);
8741 }
8742 }
8743 // support for 2.x options
8744 {
8745 setCurrentInstance(instance);
8746 pauseTracking();
8747 applyOptions(instance);
8748 resetTracking();
8749 unsetCurrentInstance();
8750 }
8751 // warn missing template/render
8752 // the runtime compilation of template in SSR is done by server-render
8753 if (!Component.render && instance.render === NOOP && !isSSR) {
8754 /* istanbul ignore if */
8755 if (!compile && Component.template) {
8756 warn$1(`Component provided template option but ` +
8757 `runtime compilation is not supported in this build of Vue.` +
8758 (` Use "vue.esm-browser.js" instead.`
8759 ) /* should not happen */);
8760 }
8761 else {
8762 warn$1(`Component is missing template or render function.`);
8763 }
8764 }
8765}
8766function createAttrsProxy(instance) {
8767 return new Proxy(instance.attrs, {
8768 get(target, key) {
8769 markAttrsAccessed();
8770 track(instance, "get" /* GET */, '$attrs');
8771 return target[key];
8772 },
8773 set() {
8774 warn$1(`setupContext.attrs is readonly.`);
8775 return false;
8776 },
8777 deleteProperty() {
8778 warn$1(`setupContext.attrs is readonly.`);
8779 return false;
8780 }
8781 }
8782 );
8783}
8784function createSetupContext(instance) {
8785 const expose = exposed => {
8786 if (instance.exposed) {
8787 warn$1(`expose() should be called only once per setup().`);
8788 }
8789 instance.exposed = exposed || {};
8790 };
8791 let attrs;
8792 {
8793 // We use getters in dev in case libs like test-utils overwrite instance
8794 // properties (overwrites should not be done in prod)
8795 return Object.freeze({
8796 get attrs() {
8797 return attrs || (attrs = createAttrsProxy(instance));
8798 },
8799 get slots() {
8800 return shallowReadonly(instance.slots);
8801 },
8802 get emit() {
8803 return (event, ...args) => instance.emit(event, ...args);
8804 },
8805 expose
8806 });
8807 }
8808}
8809function getExposeProxy(instance) {
8810 if (instance.exposed) {
8811 return (instance.exposeProxy ||
8812 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
8813 get(target, key) {
8814 if (key in target) {
8815 return target[key];
8816 }
8817 else if (key in publicPropertiesMap) {
8818 return publicPropertiesMap[key](instance);
8819 }
8820 }
8821 })));
8822 }
8823}
8824const classifyRE = /(?:^|[-_])(\w)/g;
8825const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
8826function getComponentName(Component, includeInferred = true) {
8827 return isFunction(Component)
8828 ? Component.displayName || Component.name
8829 : Component.name || (includeInferred && Component.__name);
8830}
8831/* istanbul ignore next */
8832function formatComponentName(instance, Component, isRoot = false) {
8833 let name = getComponentName(Component);
8834 if (!name && Component.__file) {
8835 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
8836 if (match) {
8837 name = match[1];
8838 }
8839 }
8840 if (!name && instance && instance.parent) {
8841 // try to infer the name based on reverse resolution
8842 const inferFromRegistry = (registry) => {
8843 for (const key in registry) {
8844 if (registry[key] === Component) {
8845 return key;
8846 }
8847 }
8848 };
8849 name =
8850 inferFromRegistry(instance.components ||
8851 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
8852 }
8853 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
8854}
8855function isClassComponent(value) {
8856 return isFunction(value) && '__vccOpts' in value;
8857}
8858
8859const computed$1 = ((getterOrOptions, debugOptions) => {
8860 // @ts-ignore
8861 return computed(getterOrOptions, debugOptions, isInSSRComponentSetup);
8862});
8863
8864// dev only
8865const warnRuntimeUsage = (method) => warn$1(`${method}() is a compiler-hint helper that is only usable inside ` +
8866 `<script setup> of a single file component. Its arguments should be ` +
8867 `compiled away and passing it at runtime has no effect.`);
8868// implementation
8869function defineProps() {
8870 {
8871 warnRuntimeUsage(`defineProps`);
8872 }
8873 return null;
8874}
8875// implementation
8876function defineEmits() {
8877 {
8878 warnRuntimeUsage(`defineEmits`);
8879 }
8880 return null;
8881}
8882/**
8883 * Vue `<script setup>` compiler macro for declaring a component's exposed
8884 * instance properties when it is accessed by a parent component via template
8885 * refs.
8886 *
8887 * `<script setup>` components are closed by default - i.e. variables inside
8888 * the `<script setup>` scope is not exposed to parent unless explicitly exposed
8889 * via `defineExpose`.
8890 *
8891 * This is only usable inside `<script setup>`, is compiled away in the
8892 * output and should **not** be actually called at runtime.
8893 */
8894function defineExpose(exposed) {
8895 {
8896 warnRuntimeUsage(`defineExpose`);
8897 }
8898}
8899/**
8900 * Vue `<script setup>` compiler macro for providing props default values when
8901 * using type-based `defineProps` declaration.
8902 *
8903 * Example usage:
8904 * ```ts
8905 * withDefaults(defineProps<{
8906 * size?: number
8907 * labels?: string[]
8908 * }>(), {
8909 * size: 3,
8910 * labels: () => ['default label']
8911 * })
8912 * ```
8913 *
8914 * This is only usable inside `<script setup>`, is compiled away in the output
8915 * and should **not** be actually called at runtime.
8916 */
8917function withDefaults(props, defaults) {
8918 {
8919 warnRuntimeUsage(`withDefaults`);
8920 }
8921 return null;
8922}
8923function useSlots() {
8924 return getContext().slots;
8925}
8926function useAttrs() {
8927 return getContext().attrs;
8928}
8929function getContext() {
8930 const i = getCurrentInstance();
8931 if (!i) {
8932 warn$1(`useContext() called without active instance.`);
8933 }
8934 return i.setupContext || (i.setupContext = createSetupContext(i));
8935}
8936/**
8937 * Runtime helper for merging default declarations. Imported by compiled code
8938 * only.
8939 * @internal
8940 */
8941function mergeDefaults(raw, defaults) {
8942 const props = isArray(raw)
8943 ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {})
8944 : raw;
8945 for (const key in defaults) {
8946 const opt = props[key];
8947 if (opt) {
8948 if (isArray(opt) || isFunction(opt)) {
8949 props[key] = { type: opt, default: defaults[key] };
8950 }
8951 else {
8952 opt.default = defaults[key];
8953 }
8954 }
8955 else if (opt === null) {
8956 props[key] = { default: defaults[key] };
8957 }
8958 else {
8959 warn$1(`props default key "${key}" has no corresponding declaration.`);
8960 }
8961 }
8962 return props;
8963}
8964/**
8965 * Used to create a proxy for the rest element when destructuring props with
8966 * defineProps().
8967 * @internal
8968 */
8969function createPropsRestProxy(props, excludedKeys) {
8970 const ret = {};
8971 for (const key in props) {
8972 if (!excludedKeys.includes(key)) {
8973 Object.defineProperty(ret, key, {
8974 enumerable: true,
8975 get: () => props[key]
8976 });
8977 }
8978 }
8979 return ret;
8980}
8981/**
8982 * `<script setup>` helper for persisting the current instance context over
8983 * async/await flows.
8984 *
8985 * `@vue/compiler-sfc` converts the following:
8986 *
8987 * ```ts
8988 * const x = await foo()
8989 * ```
8990 *
8991 * into:
8992 *
8993 * ```ts
8994 * let __temp, __restore
8995 * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
8996 * ```
8997 * @internal
8998 */
8999function withAsyncContext(getAwaitable) {
9000 const ctx = getCurrentInstance();
9001 if (!ctx) {
9002 warn$1(`withAsyncContext called without active current instance. ` +
9003 `This is likely a bug.`);
9004 }
9005 let awaitable = getAwaitable();
9006 unsetCurrentInstance();
9007 if (isPromise(awaitable)) {
9008 awaitable = awaitable.catch(e => {
9009 setCurrentInstance(ctx);
9010 throw e;
9011 });
9012 }
9013 return [awaitable, () => setCurrentInstance(ctx)];
9014}
9015
9016// Actual implementation
9017function h(type, propsOrChildren, children) {
9018 const l = arguments.length;
9019 if (l === 2) {
9020 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
9021 // single vnode without props
9022 if (isVNode(propsOrChildren)) {
9023 return createVNode(type, null, [propsOrChildren]);
9024 }
9025 // props without children
9026 return createVNode(type, propsOrChildren);
9027 }
9028 else {
9029 // omit props
9030 return createVNode(type, null, propsOrChildren);
9031 }
9032 }
9033 else {
9034 if (l > 3) {
9035 children = Array.prototype.slice.call(arguments, 2);
9036 }
9037 else if (l === 3 && isVNode(children)) {
9038 children = [children];
9039 }
9040 return createVNode(type, propsOrChildren, children);
9041 }
9042}
9043
9044const ssrContextKey = Symbol(`ssrContext` );
9045const useSSRContext = () => {
9046 {
9047 const ctx = inject(ssrContextKey);
9048 if (!ctx) {
9049 warn$1(`Server rendering context not provided. Make sure to only call ` +
9050 `useSSRContext() conditionally in the server build.`);
9051 }
9052 return ctx;
9053 }
9054};
9055
9056function initCustomFormatter() {
9057 /* eslint-disable no-restricted-globals */
9058 if (typeof window === 'undefined') {
9059 return;
9060 }
9061 const vueStyle = { style: 'color:#3ba776' };
9062 const numberStyle = { style: 'color:#0b1bc9' };
9063 const stringStyle = { style: 'color:#b62e24' };
9064 const keywordStyle = { style: 'color:#9d288c' };
9065 // custom formatter for Chrome
9066 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
9067 const formatter = {
9068 header(obj) {
9069 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
9070 if (!isObject(obj)) {
9071 return null;
9072 }
9073 if (obj.__isVue) {
9074 return ['div', vueStyle, `VueInstance`];
9075 }
9076 else if (isRef(obj)) {
9077 return [
9078 'div',
9079 {},
9080 ['span', vueStyle, genRefFlag(obj)],
9081 '<',
9082 formatValue(obj.value),
9083 `>`
9084 ];
9085 }
9086 else if (isReactive(obj)) {
9087 return [
9088 'div',
9089 {},
9090 ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
9091 '<',
9092 formatValue(obj),
9093 `>${isReadonly(obj) ? ` (readonly)` : ``}`
9094 ];
9095 }
9096 else if (isReadonly(obj)) {
9097 return [
9098 'div',
9099 {},
9100 ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
9101 '<',
9102 formatValue(obj),
9103 '>'
9104 ];
9105 }
9106 return null;
9107 },
9108 hasBody(obj) {
9109 return obj && obj.__isVue;
9110 },
9111 body(obj) {
9112 if (obj && obj.__isVue) {
9113 return [
9114 'div',
9115 {},
9116 ...formatInstance(obj.$)
9117 ];
9118 }
9119 }
9120 };
9121 function formatInstance(instance) {
9122 const blocks = [];
9123 if (instance.type.props && instance.props) {
9124 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
9125 }
9126 if (instance.setupState !== EMPTY_OBJ) {
9127 blocks.push(createInstanceBlock('setup', instance.setupState));
9128 }
9129 if (instance.data !== EMPTY_OBJ) {
9130 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
9131 }
9132 const computed = extractKeys(instance, 'computed');
9133 if (computed) {
9134 blocks.push(createInstanceBlock('computed', computed));
9135 }
9136 const injected = extractKeys(instance, 'inject');
9137 if (injected) {
9138 blocks.push(createInstanceBlock('injected', injected));
9139 }
9140 blocks.push([
9141 'div',
9142 {},
9143 [
9144 'span',
9145 {
9146 style: keywordStyle.style + ';opacity:0.66'
9147 },
9148 '$ (internal): '
9149 ],
9150 ['object', { object: instance }]
9151 ]);
9152 return blocks;
9153 }
9154 function createInstanceBlock(type, target) {
9155 target = extend({}, target);
9156 if (!Object.keys(target).length) {
9157 return ['span', {}];
9158 }
9159 return [
9160 'div',
9161 { style: 'line-height:1.25em;margin-bottom:0.6em' },
9162 [
9163 'div',
9164 {
9165 style: 'color:#476582'
9166 },
9167 type
9168 ],
9169 [
9170 'div',
9171 {
9172 style: 'padding-left:1.25em'
9173 },
9174 ...Object.keys(target).map(key => {
9175 return [
9176 'div',
9177 {},
9178 ['span', keywordStyle, key + ': '],
9179 formatValue(target[key], false)
9180 ];
9181 })
9182 ]
9183 ];
9184 }
9185 function formatValue(v, asRaw = true) {
9186 if (typeof v === 'number') {
9187 return ['span', numberStyle, v];
9188 }
9189 else if (typeof v === 'string') {
9190 return ['span', stringStyle, JSON.stringify(v)];
9191 }
9192 else if (typeof v === 'boolean') {
9193 return ['span', keywordStyle, v];
9194 }
9195 else if (isObject(v)) {
9196 return ['object', { object: asRaw ? toRaw(v) : v }];
9197 }
9198 else {
9199 return ['span', stringStyle, String(v)];
9200 }
9201 }
9202 function extractKeys(instance, type) {
9203 const Comp = instance.type;
9204 if (isFunction(Comp)) {
9205 return;
9206 }
9207 const extracted = {};
9208 for (const key in instance.ctx) {
9209 if (isKeyOfType(Comp, key, type)) {
9210 extracted[key] = instance.ctx[key];
9211 }
9212 }
9213 return extracted;
9214 }
9215 function isKeyOfType(Comp, key, type) {
9216 const opts = Comp[type];
9217 if ((isArray(opts) && opts.includes(key)) ||
9218 (isObject(opts) && key in opts)) {
9219 return true;
9220 }
9221 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
9222 return true;
9223 }
9224 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
9225 return true;
9226 }
9227 }
9228 function genRefFlag(v) {
9229 if (isShallow(v)) {
9230 return `ShallowRef`;
9231 }
9232 if (v.effect) {
9233 return `ComputedRef`;
9234 }
9235 return `Ref`;
9236 }
9237 if (window.devtoolsFormatters) {
9238 window.devtoolsFormatters.push(formatter);
9239 }
9240 else {
9241 window.devtoolsFormatters = [formatter];
9242 }
9243}
9244
9245function withMemo(memo, render, cache, index) {
9246 const cached = cache[index];
9247 if (cached && isMemoSame(cached, memo)) {
9248 return cached;
9249 }
9250 const ret = render();
9251 // shallow clone
9252 ret.memo = memo.slice();
9253 return (cache[index] = ret);
9254}
9255function isMemoSame(cached, memo) {
9256 const prev = cached.memo;
9257 if (prev.length != memo.length) {
9258 return false;
9259 }
9260 for (let i = 0; i < prev.length; i++) {
9261 if (hasChanged(prev[i], memo[i])) {
9262 return false;
9263 }
9264 }
9265 // make sure to let parent block track it when returning cached
9266 if (isBlockTreeEnabled > 0 && currentBlock) {
9267 currentBlock.push(cached);
9268 }
9269 return true;
9270}
9271
9272// Core API ------------------------------------------------------------------
9273const version = "3.2.37";
9274/**
9275 * SSR utils for \@vue/server-renderer. Only exposed in ssr-possible builds.
9276 * @internal
9277 */
9278const ssrUtils = (null);
9279/**
9280 * @internal only exposed in compat builds
9281 */
9282const resolveFilter = null;
9283/**
9284 * @internal only exposed in compat builds.
9285 */
9286const compatUtils = (null);
9287
9288const svgNS = 'http://www.w3.org/2000/svg';
9289const doc = (typeof document !== 'undefined' ? document : null);
9290const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
9291const nodeOps = {
9292 insert: (child, parent, anchor) => {
9293 parent.insertBefore(child, anchor || null);
9294 },
9295 remove: child => {
9296 const parent = child.parentNode;
9297 if (parent) {
9298 parent.removeChild(child);
9299 }
9300 },
9301 createElement: (tag, isSVG, is, props) => {
9302 const el = isSVG
9303 ? doc.createElementNS(svgNS, tag)
9304 : doc.createElement(tag, is ? { is } : undefined);
9305 if (tag === 'select' && props && props.multiple != null) {
9306 el.setAttribute('multiple', props.multiple);
9307 }
9308 return el;
9309 },
9310 createText: text => doc.createTextNode(text),
9311 createComment: text => doc.createComment(text),
9312 setText: (node, text) => {
9313 node.nodeValue = text;
9314 },
9315 setElementText: (el, text) => {
9316 el.textContent = text;
9317 },
9318 parentNode: node => node.parentNode,
9319 nextSibling: node => node.nextSibling,
9320 querySelector: selector => doc.querySelector(selector),
9321 setScopeId(el, id) {
9322 el.setAttribute(id, '');
9323 },
9324 cloneNode(el) {
9325 const cloned = el.cloneNode(true);
9326 // #3072
9327 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
9328 // - normally, elements using `:value` bindings will not be hoisted, but if
9329 // the bound value is a constant, e.g. `:value="true"` - they do get
9330 // hoisted.
9331 // - in production, hoisted nodes are cloned when subsequent inserts, but
9332 // cloneNode() does not copy the custom property we attached.
9333 // - This may need to account for other custom DOM properties we attach to
9334 // elements in addition to `_value` in the future.
9335 if (`_value` in el) {
9336 cloned._value = el._value;
9337 }
9338 return cloned;
9339 },
9340 // __UNSAFE__
9341 // Reason: innerHTML.
9342 // Static content here can only come from compiled templates.
9343 // As long as the user only uses trusted templates, this is safe.
9344 insertStaticContent(content, parent, anchor, isSVG, start, end) {
9345 // <parent> before | first ... last | anchor </parent>
9346 const before = anchor ? anchor.previousSibling : parent.lastChild;
9347 // #5308 can only take cached path if:
9348 // - has a single root node
9349 // - nextSibling info is still available
9350 if (start && (start === end || start.nextSibling)) {
9351 // cached
9352 while (true) {
9353 parent.insertBefore(start.cloneNode(true), anchor);
9354 if (start === end || !(start = start.nextSibling))
9355 break;
9356 }
9357 }
9358 else {
9359 // fresh insert
9360 templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
9361 const template = templateContainer.content;
9362 if (isSVG) {
9363 // remove outer svg wrapper
9364 const wrapper = template.firstChild;
9365 while (wrapper.firstChild) {
9366 template.appendChild(wrapper.firstChild);
9367 }
9368 template.removeChild(wrapper);
9369 }
9370 parent.insertBefore(template, anchor);
9371 }
9372 return [
9373 // first
9374 before ? before.nextSibling : parent.firstChild,
9375 // last
9376 anchor ? anchor.previousSibling : parent.lastChild
9377 ];
9378 }
9379};
9380
9381// compiler should normalize class + :class bindings on the same element
9382// into a single binding ['staticClass', dynamic]
9383function patchClass(el, value, isSVG) {
9384 // directly setting className should be faster than setAttribute in theory
9385 // if this is an element during a transition, take the temporary transition
9386 // classes into account.
9387 const transitionClasses = el._vtc;
9388 if (transitionClasses) {
9389 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
9390 }
9391 if (value == null) {
9392 el.removeAttribute('class');
9393 }
9394 else if (isSVG) {
9395 el.setAttribute('class', value);
9396 }
9397 else {
9398 el.className = value;
9399 }
9400}
9401
9402function patchStyle(el, prev, next) {
9403 const style = el.style;
9404 const isCssString = isString(next);
9405 if (next && !isCssString) {
9406 for (const key in next) {
9407 setStyle(style, key, next[key]);
9408 }
9409 if (prev && !isString(prev)) {
9410 for (const key in prev) {
9411 if (next[key] == null) {
9412 setStyle(style, key, '');
9413 }
9414 }
9415 }
9416 }
9417 else {
9418 const currentDisplay = style.display;
9419 if (isCssString) {
9420 if (prev !== next) {
9421 style.cssText = next;
9422 }
9423 }
9424 else if (prev) {
9425 el.removeAttribute('style');
9426 }
9427 // indicates that the `display` of the element is controlled by `v-show`,
9428 // so we always keep the current `display` value regardless of the `style`
9429 // value, thus handing over control to `v-show`.
9430 if ('_vod' in el) {
9431 style.display = currentDisplay;
9432 }
9433 }
9434}
9435const importantRE = /\s*!important$/;
9436function setStyle(style, name, val) {
9437 if (isArray(val)) {
9438 val.forEach(v => setStyle(style, name, v));
9439 }
9440 else {
9441 if (val == null)
9442 val = '';
9443 if (name.startsWith('--')) {
9444 // custom property definition
9445 style.setProperty(name, val);
9446 }
9447 else {
9448 const prefixed = autoPrefix(style, name);
9449 if (importantRE.test(val)) {
9450 // !important
9451 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
9452 }
9453 else {
9454 style[prefixed] = val;
9455 }
9456 }
9457 }
9458}
9459const prefixes = ['Webkit', 'Moz', 'ms'];
9460const prefixCache = {};
9461function autoPrefix(style, rawName) {
9462 const cached = prefixCache[rawName];
9463 if (cached) {
9464 return cached;
9465 }
9466 let name = camelize(rawName);
9467 if (name !== 'filter' && name in style) {
9468 return (prefixCache[rawName] = name);
9469 }
9470 name = capitalize(name);
9471 for (let i = 0; i < prefixes.length; i++) {
9472 const prefixed = prefixes[i] + name;
9473 if (prefixed in style) {
9474 return (prefixCache[rawName] = prefixed);
9475 }
9476 }
9477 return rawName;
9478}
9479
9480const xlinkNS = 'http://www.w3.org/1999/xlink';
9481function patchAttr(el, key, value, isSVG, instance) {
9482 if (isSVG && key.startsWith('xlink:')) {
9483 if (value == null) {
9484 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
9485 }
9486 else {
9487 el.setAttributeNS(xlinkNS, key, value);
9488 }
9489 }
9490 else {
9491 // note we are only checking boolean attributes that don't have a
9492 // corresponding dom prop of the same name here.
9493 const isBoolean = isSpecialBooleanAttr(key);
9494 if (value == null || (isBoolean && !includeBooleanAttr(value))) {
9495 el.removeAttribute(key);
9496 }
9497 else {
9498 el.setAttribute(key, isBoolean ? '' : value);
9499 }
9500 }
9501}
9502
9503// __UNSAFE__
9504// functions. The user is responsible for using them with only trusted content.
9505function patchDOMProp(el, key, value,
9506// the following args are passed only due to potential innerHTML/textContent
9507// overriding existing VNodes, in which case the old tree must be properly
9508// unmounted.
9509prevChildren, parentComponent, parentSuspense, unmountChildren) {
9510 if (key === 'innerHTML' || key === 'textContent') {
9511 if (prevChildren) {
9512 unmountChildren(prevChildren, parentComponent, parentSuspense);
9513 }
9514 el[key] = value == null ? '' : value;
9515 return;
9516 }
9517 if (key === 'value' &&
9518 el.tagName !== 'PROGRESS' &&
9519 // custom elements may use _value internally
9520 !el.tagName.includes('-')) {
9521 // store value as _value as well since
9522 // non-string values will be stringified.
9523 el._value = value;
9524 const newValue = value == null ? '' : value;
9525 if (el.value !== newValue ||
9526 // #4956: always set for OPTION elements because its value falls back to
9527 // textContent if no value attribute is present. And setting .value for
9528 // OPTION has no side effect
9529 el.tagName === 'OPTION') {
9530 el.value = newValue;
9531 }
9532 if (value == null) {
9533 el.removeAttribute(key);
9534 }
9535 return;
9536 }
9537 let needRemove = false;
9538 if (value === '' || value == null) {
9539 const type = typeof el[key];
9540 if (type === 'boolean') {
9541 // e.g. <select multiple> compiles to { multiple: '' }
9542 value = includeBooleanAttr(value);
9543 }
9544 else if (value == null && type === 'string') {
9545 // e.g. <div :id="null">
9546 value = '';
9547 needRemove = true;
9548 }
9549 else if (type === 'number') {
9550 // e.g. <img :width="null">
9551 // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
9552 value = 0;
9553 needRemove = true;
9554 }
9555 }
9556 // some properties perform value validation and throw,
9557 // some properties has getter, no setter, will error in 'use strict'
9558 // eg. <select :type="null"></select> <select :willValidate="null"></select>
9559 try {
9560 el[key] = value;
9561 }
9562 catch (e) {
9563 {
9564 warn$1(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9565 `value ${value} is invalid.`, e);
9566 }
9567 }
9568 needRemove && el.removeAttribute(key);
9569}
9570
9571// Async edge case fix requires storing an event listener's attach timestamp.
9572const [_getNow, skipTimestampCheck] = /*#__PURE__*/ (() => {
9573 let _getNow = Date.now;
9574 let skipTimestampCheck = false;
9575 if (typeof window !== 'undefined') {
9576 // Determine what event timestamp the browser is using. Annoyingly, the
9577 // timestamp can either be hi-res (relative to page load) or low-res
9578 // (relative to UNIX epoch), so in order to compare time we have to use the
9579 // same timestamp type when saving the flush timestamp.
9580 if (Date.now() > document.createEvent('Event').timeStamp) {
9581 // if the low-res timestamp which is bigger than the event timestamp
9582 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
9583 // and we need to use the hi-res version for event listeners as well.
9584 _getNow = performance.now.bind(performance);
9585 }
9586 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
9587 // and does not fire microtasks in between event propagation, so safe to exclude.
9588 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
9589 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
9590 }
9591 return [_getNow, skipTimestampCheck];
9592})();
9593// To avoid the overhead of repeatedly calling performance.now(), we cache
9594// and use the same timestamp for all event listeners attached in the same tick.
9595let cachedNow = 0;
9596const p = /*#__PURE__*/ Promise.resolve();
9597const reset = () => {
9598 cachedNow = 0;
9599};
9600const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
9601function addEventListener(el, event, handler, options) {
9602 el.addEventListener(event, handler, options);
9603}
9604function removeEventListener(el, event, handler, options) {
9605 el.removeEventListener(event, handler, options);
9606}
9607function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9608 // vei = vue event invokers
9609 const invokers = el._vei || (el._vei = {});
9610 const existingInvoker = invokers[rawName];
9611 if (nextValue && existingInvoker) {
9612 // patch
9613 existingInvoker.value = nextValue;
9614 }
9615 else {
9616 const [name, options] = parseName(rawName);
9617 if (nextValue) {
9618 // add
9619 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9620 addEventListener(el, name, invoker, options);
9621 }
9622 else if (existingInvoker) {
9623 // remove
9624 removeEventListener(el, name, existingInvoker, options);
9625 invokers[rawName] = undefined;
9626 }
9627 }
9628}
9629const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9630function parseName(name) {
9631 let options;
9632 if (optionsModifierRE.test(name)) {
9633 options = {};
9634 let m;
9635 while ((m = name.match(optionsModifierRE))) {
9636 name = name.slice(0, name.length - m[0].length);
9637 options[m[0].toLowerCase()] = true;
9638 }
9639 }
9640 return [hyphenate(name.slice(2)), options];
9641}
9642function createInvoker(initialValue, instance) {
9643 const invoker = (e) => {
9644 // async edge case #6566: inner click event triggers patch, event handler
9645 // attached to outer element during patch, and triggered again. This
9646 // happens because browsers fire microtask ticks between event propagation.
9647 // the solution is simple: we save the timestamp when a handler is attached,
9648 // and the handler would only fire if the event passed to it was fired
9649 // AFTER it was attached.
9650 const timeStamp = e.timeStamp || _getNow();
9651 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
9652 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
9653 }
9654 };
9655 invoker.value = initialValue;
9656 invoker.attached = getNow();
9657 return invoker;
9658}
9659function patchStopImmediatePropagation(e, value) {
9660 if (isArray(value)) {
9661 const originalStop = e.stopImmediatePropagation;
9662 e.stopImmediatePropagation = () => {
9663 originalStop.call(e);
9664 e._stopped = true;
9665 };
9666 return value.map(fn => (e) => !e._stopped && fn && fn(e));
9667 }
9668 else {
9669 return value;
9670 }
9671}
9672
9673const nativeOnRE = /^on[a-z]/;
9674const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9675 if (key === 'class') {
9676 patchClass(el, nextValue, isSVG);
9677 }
9678 else if (key === 'style') {
9679 patchStyle(el, prevValue, nextValue);
9680 }
9681 else if (isOn(key)) {
9682 // ignore v-model listeners
9683 if (!isModelListener(key)) {
9684 patchEvent(el, key, prevValue, nextValue, parentComponent);
9685 }
9686 }
9687 else if (key[0] === '.'
9688 ? ((key = key.slice(1)), true)
9689 : key[0] === '^'
9690 ? ((key = key.slice(1)), false)
9691 : shouldSetAsProp(el, key, nextValue, isSVG)) {
9692 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9693 }
9694 else {
9695 // special case for <input v-model type="checkbox"> with
9696 // :true-value & :false-value
9697 // store value as dom properties since non-string values will be
9698 // stringified.
9699 if (key === 'true-value') {
9700 el._trueValue = nextValue;
9701 }
9702 else if (key === 'false-value') {
9703 el._falseValue = nextValue;
9704 }
9705 patchAttr(el, key, nextValue, isSVG);
9706 }
9707};
9708function shouldSetAsProp(el, key, value, isSVG) {
9709 if (isSVG) {
9710 // most keys must be set as attribute on svg elements to work
9711 // ...except innerHTML & textContent
9712 if (key === 'innerHTML' || key === 'textContent') {
9713 return true;
9714 }
9715 // or native onclick with function values
9716 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9717 return true;
9718 }
9719 return false;
9720 }
9721 // these are enumerated attrs, however their corresponding DOM properties
9722 // are actually booleans - this leads to setting it with a string "false"
9723 // value leading it to be coerced to `true`, so we need to always treat
9724 // them as attributes.
9725 // Note that `contentEditable` doesn't have this problem: its DOM
9726 // property is also enumerated string values.
9727 if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
9728 return false;
9729 }
9730 // #1787, #2840 form property on form elements is readonly and must be set as
9731 // attribute.
9732 if (key === 'form') {
9733 return false;
9734 }
9735 // #1526 <input list> must be set as attribute
9736 if (key === 'list' && el.tagName === 'INPUT') {
9737 return false;
9738 }
9739 // #2766 <textarea type> must be set as attribute
9740 if (key === 'type' && el.tagName === 'TEXTAREA') {
9741 return false;
9742 }
9743 // native onclick with string value, must be set as attribute
9744 if (nativeOnRE.test(key) && isString(value)) {
9745 return false;
9746 }
9747 return key in el;
9748}
9749
9750function defineCustomElement(options, hydrate) {
9751 const Comp = defineComponent(options);
9752 class VueCustomElement extends VueElement {
9753 constructor(initialProps) {
9754 super(Comp, initialProps, hydrate);
9755 }
9756 }
9757 VueCustomElement.def = Comp;
9758 return VueCustomElement;
9759}
9760const defineSSRCustomElement = ((options) => {
9761 // @ts-ignore
9762 return defineCustomElement(options, hydrate);
9763});
9764const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
9765});
9766class VueElement extends BaseClass {
9767 constructor(_def, _props = {}, hydrate) {
9768 super();
9769 this._def = _def;
9770 this._props = _props;
9771 /**
9772 * @internal
9773 */
9774 this._instance = null;
9775 this._connected = false;
9776 this._resolved = false;
9777 this._numberProps = null;
9778 if (this.shadowRoot && hydrate) {
9779 hydrate(this._createVNode(), this.shadowRoot);
9780 }
9781 else {
9782 if (this.shadowRoot) {
9783 warn$1(`Custom element has pre-rendered declarative shadow root but is not ` +
9784 `defined as hydratable. Use \`defineSSRCustomElement\`.`);
9785 }
9786 this.attachShadow({ mode: 'open' });
9787 }
9788 }
9789 connectedCallback() {
9790 this._connected = true;
9791 if (!this._instance) {
9792 this._resolveDef();
9793 }
9794 }
9795 disconnectedCallback() {
9796 this._connected = false;
9797 nextTick(() => {
9798 if (!this._connected) {
9799 render(null, this.shadowRoot);
9800 this._instance = null;
9801 }
9802 });
9803 }
9804 /**
9805 * resolve inner component definition (handle possible async component)
9806 */
9807 _resolveDef() {
9808 if (this._resolved) {
9809 return;
9810 }
9811 this._resolved = true;
9812 // set initial attrs
9813 for (let i = 0; i < this.attributes.length; i++) {
9814 this._setAttr(this.attributes[i].name);
9815 }
9816 // watch future attr changes
9817 new MutationObserver(mutations => {
9818 for (const m of mutations) {
9819 this._setAttr(m.attributeName);
9820 }
9821 }).observe(this, { attributes: true });
9822 const resolve = (def) => {
9823 const { props, styles } = def;
9824 const hasOptions = !isArray(props);
9825 const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
9826 // cast Number-type props set before resolve
9827 let numberProps;
9828 if (hasOptions) {
9829 for (const key in this._props) {
9830 const opt = props[key];
9831 if (opt === Number || (opt && opt.type === Number)) {
9832 this._props[key] = toNumber(this._props[key]);
9833 (numberProps || (numberProps = Object.create(null)))[key] = true;
9834 }
9835 }
9836 }
9837 this._numberProps = numberProps;
9838 // check if there are props set pre-upgrade or connect
9839 for (const key of Object.keys(this)) {
9840 if (key[0] !== '_') {
9841 this._setProp(key, this[key], true, false);
9842 }
9843 }
9844 // defining getter/setters on prototype
9845 for (const key of rawKeys.map(camelize)) {
9846 Object.defineProperty(this, key, {
9847 get() {
9848 return this._getProp(key);
9849 },
9850 set(val) {
9851 this._setProp(key, val);
9852 }
9853 });
9854 }
9855 // apply CSS
9856 this._applyStyles(styles);
9857 // initial render
9858 this._update();
9859 };
9860 const asyncDef = this._def.__asyncLoader;
9861 if (asyncDef) {
9862 asyncDef().then(resolve);
9863 }
9864 else {
9865 resolve(this._def);
9866 }
9867 }
9868 _setAttr(key) {
9869 let value = this.getAttribute(key);
9870 if (this._numberProps && this._numberProps[key]) {
9871 value = toNumber(value);
9872 }
9873 this._setProp(camelize(key), value, false);
9874 }
9875 /**
9876 * @internal
9877 */
9878 _getProp(key) {
9879 return this._props[key];
9880 }
9881 /**
9882 * @internal
9883 */
9884 _setProp(key, val, shouldReflect = true, shouldUpdate = true) {
9885 if (val !== this._props[key]) {
9886 this._props[key] = val;
9887 if (shouldUpdate && this._instance) {
9888 this._update();
9889 }
9890 // reflect
9891 if (shouldReflect) {
9892 if (val === true) {
9893 this.setAttribute(hyphenate(key), '');
9894 }
9895 else if (typeof val === 'string' || typeof val === 'number') {
9896 this.setAttribute(hyphenate(key), val + '');
9897 }
9898 else if (!val) {
9899 this.removeAttribute(hyphenate(key));
9900 }
9901 }
9902 }
9903 }
9904 _update() {
9905 render(this._createVNode(), this.shadowRoot);
9906 }
9907 _createVNode() {
9908 const vnode = createVNode(this._def, extend({}, this._props));
9909 if (!this._instance) {
9910 vnode.ce = instance => {
9911 this._instance = instance;
9912 instance.isCE = true;
9913 // HMR
9914 {
9915 instance.ceReload = newStyles => {
9916 // always reset styles
9917 if (this._styles) {
9918 this._styles.forEach(s => this.shadowRoot.removeChild(s));
9919 this._styles.length = 0;
9920 }
9921 this._applyStyles(newStyles);
9922 // if this is an async component, ceReload is called from the inner
9923 // component so no need to reload the async wrapper
9924 if (!this._def.__asyncLoader) {
9925 // reload
9926 this._instance = null;
9927 this._update();
9928 }
9929 };
9930 }
9931 // intercept emit
9932 instance.emit = (event, ...args) => {
9933 this.dispatchEvent(new CustomEvent(event, {
9934 detail: args
9935 }));
9936 };
9937 // locate nearest Vue custom element parent for provide/inject
9938 let parent = this;
9939 while ((parent =
9940 parent && (parent.parentNode || parent.host))) {
9941 if (parent instanceof VueElement) {
9942 instance.parent = parent._instance;
9943 break;
9944 }
9945 }
9946 };
9947 }
9948 return vnode;
9949 }
9950 _applyStyles(styles) {
9951 if (styles) {
9952 styles.forEach(css => {
9953 const s = document.createElement('style');
9954 s.textContent = css;
9955 this.shadowRoot.appendChild(s);
9956 // record for HMR
9957 {
9958 (this._styles || (this._styles = [])).push(s);
9959 }
9960 });
9961 }
9962 }
9963}
9964
9965function useCssModule(name = '$style') {
9966 /* istanbul ignore else */
9967 {
9968 const instance = getCurrentInstance();
9969 if (!instance) {
9970 warn$1(`useCssModule must be called inside setup()`);
9971 return EMPTY_OBJ;
9972 }
9973 const modules = instance.type.__cssModules;
9974 if (!modules) {
9975 warn$1(`Current instance does not have CSS modules injected.`);
9976 return EMPTY_OBJ;
9977 }
9978 const mod = modules[name];
9979 if (!mod) {
9980 warn$1(`Current instance does not have CSS module named "${name}".`);
9981 return EMPTY_OBJ;
9982 }
9983 return mod;
9984 }
9985}
9986
9987/**
9988 * Runtime helper for SFC's CSS variable injection feature.
9989 * @private
9990 */
9991function useCssVars(getter) {
9992 const instance = getCurrentInstance();
9993 /* istanbul ignore next */
9994 if (!instance) {
9995 warn$1(`useCssVars is called without current active component instance.`);
9996 return;
9997 }
9998 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
9999 watchPostEffect(setVars);
10000 onMounted(() => {
10001 const ob = new MutationObserver(setVars);
10002 ob.observe(instance.subTree.el.parentNode, { childList: true });
10003 onUnmounted(() => ob.disconnect());
10004 });
10005}
10006function setVarsOnVNode(vnode, vars) {
10007 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
10008 const suspense = vnode.suspense;
10009 vnode = suspense.activeBranch;
10010 if (suspense.pendingBranch && !suspense.isHydrating) {
10011 suspense.effects.push(() => {
10012 setVarsOnVNode(suspense.activeBranch, vars);
10013 });
10014 }
10015 }
10016 // drill down HOCs until it's a non-component vnode
10017 while (vnode.component) {
10018 vnode = vnode.component.subTree;
10019 }
10020 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
10021 setVarsOnNode(vnode.el, vars);
10022 }
10023 else if (vnode.type === Fragment) {
10024 vnode.children.forEach(c => setVarsOnVNode(c, vars));
10025 }
10026 else if (vnode.type === Static) {
10027 let { el, anchor } = vnode;
10028 while (el) {
10029 setVarsOnNode(el, vars);
10030 if (el === anchor)
10031 break;
10032 el = el.nextSibling;
10033 }
10034 }
10035}
10036function setVarsOnNode(el, vars) {
10037 if (el.nodeType === 1) {
10038 const style = el.style;
10039 for (const key in vars) {
10040 style.setProperty(`--${key}`, vars[key]);
10041 }
10042 }
10043}
10044
10045const TRANSITION = 'transition';
10046const ANIMATION = 'animation';
10047// DOM Transition is a higher-order-component based on the platform-agnostic
10048// base Transition component, with DOM-specific logic.
10049const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
10050Transition.displayName = 'Transition';
10051const DOMTransitionPropsValidators = {
10052 name: String,
10053 type: String,
10054 css: {
10055 type: Boolean,
10056 default: true
10057 },
10058 duration: [String, Number, Object],
10059 enterFromClass: String,
10060 enterActiveClass: String,
10061 enterToClass: String,
10062 appearFromClass: String,
10063 appearActiveClass: String,
10064 appearToClass: String,
10065 leaveFromClass: String,
10066 leaveActiveClass: String,
10067 leaveToClass: String
10068};
10069const TransitionPropsValidators = (Transition.props =
10070 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
10071/**
10072 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
10073 * with custom HOCs.
10074 */
10075const callHook$1 = (hook, args = []) => {
10076 if (isArray(hook)) {
10077 hook.forEach(h => h(...args));
10078 }
10079 else if (hook) {
10080 hook(...args);
10081 }
10082};
10083/**
10084 * Check if a hook expects a callback (2nd arg), which means the user
10085 * intends to explicitly control the end of the transition.
10086 */
10087const hasExplicitCallback = (hook) => {
10088 return hook
10089 ? isArray(hook)
10090 ? hook.some(h => h.length > 1)
10091 : hook.length > 1
10092 : false;
10093};
10094function resolveTransitionProps(rawProps) {
10095 const baseProps = {};
10096 for (const key in rawProps) {
10097 if (!(key in DOMTransitionPropsValidators)) {
10098 baseProps[key] = rawProps[key];
10099 }
10100 }
10101 if (rawProps.css === false) {
10102 return baseProps;
10103 }
10104 const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
10105 const durations = normalizeDuration(duration);
10106 const enterDuration = durations && durations[0];
10107 const leaveDuration = durations && durations[1];
10108 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
10109 const finishEnter = (el, isAppear, done) => {
10110 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
10111 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
10112 done && done();
10113 };
10114 const finishLeave = (el, done) => {
10115 el._isLeaving = false;
10116 removeTransitionClass(el, leaveFromClass);
10117 removeTransitionClass(el, leaveToClass);
10118 removeTransitionClass(el, leaveActiveClass);
10119 done && done();
10120 };
10121 const makeEnterHook = (isAppear) => {
10122 return (el, done) => {
10123 const hook = isAppear ? onAppear : onEnter;
10124 const resolve = () => finishEnter(el, isAppear, done);
10125 callHook$1(hook, [el, resolve]);
10126 nextFrame(() => {
10127 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
10128 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
10129 if (!hasExplicitCallback(hook)) {
10130 whenTransitionEnds(el, type, enterDuration, resolve);
10131 }
10132 });
10133 };
10134 };
10135 return extend(baseProps, {
10136 onBeforeEnter(el) {
10137 callHook$1(onBeforeEnter, [el]);
10138 addTransitionClass(el, enterFromClass);
10139 addTransitionClass(el, enterActiveClass);
10140 },
10141 onBeforeAppear(el) {
10142 callHook$1(onBeforeAppear, [el]);
10143 addTransitionClass(el, appearFromClass);
10144 addTransitionClass(el, appearActiveClass);
10145 },
10146 onEnter: makeEnterHook(false),
10147 onAppear: makeEnterHook(true),
10148 onLeave(el, done) {
10149 el._isLeaving = true;
10150 const resolve = () => finishLeave(el, done);
10151 addTransitionClass(el, leaveFromClass);
10152 // force reflow so *-leave-from classes immediately take effect (#2593)
10153 forceReflow();
10154 addTransitionClass(el, leaveActiveClass);
10155 nextFrame(() => {
10156 if (!el._isLeaving) {
10157 // cancelled
10158 return;
10159 }
10160 removeTransitionClass(el, leaveFromClass);
10161 addTransitionClass(el, leaveToClass);
10162 if (!hasExplicitCallback(onLeave)) {
10163 whenTransitionEnds(el, type, leaveDuration, resolve);
10164 }
10165 });
10166 callHook$1(onLeave, [el, resolve]);
10167 },
10168 onEnterCancelled(el) {
10169 finishEnter(el, false);
10170 callHook$1(onEnterCancelled, [el]);
10171 },
10172 onAppearCancelled(el) {
10173 finishEnter(el, true);
10174 callHook$1(onAppearCancelled, [el]);
10175 },
10176 onLeaveCancelled(el) {
10177 finishLeave(el);
10178 callHook$1(onLeaveCancelled, [el]);
10179 }
10180 });
10181}
10182function normalizeDuration(duration) {
10183 if (duration == null) {
10184 return null;
10185 }
10186 else if (isObject(duration)) {
10187 return [NumberOf(duration.enter), NumberOf(duration.leave)];
10188 }
10189 else {
10190 const n = NumberOf(duration);
10191 return [n, n];
10192 }
10193}
10194function NumberOf(val) {
10195 const res = toNumber(val);
10196 validateDuration(res);
10197 return res;
10198}
10199function validateDuration(val) {
10200 if (typeof val !== 'number') {
10201 warn$1(`<transition> explicit duration is not a valid number - ` +
10202 `got ${JSON.stringify(val)}.`);
10203 }
10204 else if (isNaN(val)) {
10205 warn$1(`<transition> explicit duration is NaN - ` +
10206 'the duration expression might be incorrect.');
10207 }
10208}
10209function addTransitionClass(el, cls) {
10210 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
10211 (el._vtc ||
10212 (el._vtc = new Set())).add(cls);
10213}
10214function removeTransitionClass(el, cls) {
10215 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
10216 const { _vtc } = el;
10217 if (_vtc) {
10218 _vtc.delete(cls);
10219 if (!_vtc.size) {
10220 el._vtc = undefined;
10221 }
10222 }
10223}
10224function nextFrame(cb) {
10225 requestAnimationFrame(() => {
10226 requestAnimationFrame(cb);
10227 });
10228}
10229let endId = 0;
10230function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
10231 const id = (el._endId = ++endId);
10232 const resolveIfNotStale = () => {
10233 if (id === el._endId) {
10234 resolve();
10235 }
10236 };
10237 if (explicitTimeout) {
10238 return setTimeout(resolveIfNotStale, explicitTimeout);
10239 }
10240 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
10241 if (!type) {
10242 return resolve();
10243 }
10244 const endEvent = type + 'end';
10245 let ended = 0;
10246 const end = () => {
10247 el.removeEventListener(endEvent, onEnd);
10248 resolveIfNotStale();
10249 };
10250 const onEnd = (e) => {
10251 if (e.target === el && ++ended >= propCount) {
10252 end();
10253 }
10254 };
10255 setTimeout(() => {
10256 if (ended < propCount) {
10257 end();
10258 }
10259 }, timeout + 1);
10260 el.addEventListener(endEvent, onEnd);
10261}
10262function getTransitionInfo(el, expectedType) {
10263 const styles = window.getComputedStyle(el);
10264 // JSDOM may return undefined for transition properties
10265 const getStyleProperties = (key) => (styles[key] || '').split(', ');
10266 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
10267 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
10268 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
10269 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
10270 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
10271 const animationTimeout = getTimeout(animationDelays, animationDurations);
10272 let type = null;
10273 let timeout = 0;
10274 let propCount = 0;
10275 /* istanbul ignore if */
10276 if (expectedType === TRANSITION) {
10277 if (transitionTimeout > 0) {
10278 type = TRANSITION;
10279 timeout = transitionTimeout;
10280 propCount = transitionDurations.length;
10281 }
10282 }
10283 else if (expectedType === ANIMATION) {
10284 if (animationTimeout > 0) {
10285 type = ANIMATION;
10286 timeout = animationTimeout;
10287 propCount = animationDurations.length;
10288 }
10289 }
10290 else {
10291 timeout = Math.max(transitionTimeout, animationTimeout);
10292 type =
10293 timeout > 0
10294 ? transitionTimeout > animationTimeout
10295 ? TRANSITION
10296 : ANIMATION
10297 : null;
10298 propCount = type
10299 ? type === TRANSITION
10300 ? transitionDurations.length
10301 : animationDurations.length
10302 : 0;
10303 }
10304 const hasTransform = type === TRANSITION &&
10305 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
10306 return {
10307 type,
10308 timeout,
10309 propCount,
10310 hasTransform
10311 };
10312}
10313function getTimeout(delays, durations) {
10314 while (delays.length < durations.length) {
10315 delays = delays.concat(delays);
10316 }
10317 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
10318}
10319// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
10320// numbers in a locale-dependent way, using a comma instead of a dot.
10321// If comma is not replaced with a dot, the input will be rounded down
10322// (i.e. acting as a floor function) causing unexpected behaviors
10323function toMs(s) {
10324 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
10325}
10326// synchronously force layout to put elements into a certain state
10327function forceReflow() {
10328 return document.body.offsetHeight;
10329}
10330
10331const positionMap = new WeakMap();
10332const newPositionMap = new WeakMap();
10333const TransitionGroupImpl = {
10334 name: 'TransitionGroup',
10335 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
10336 tag: String,
10337 moveClass: String
10338 }),
10339 setup(props, { slots }) {
10340 const instance = getCurrentInstance();
10341 const state = useTransitionState();
10342 let prevChildren;
10343 let children;
10344 onUpdated(() => {
10345 // children is guaranteed to exist after initial render
10346 if (!prevChildren.length) {
10347 return;
10348 }
10349 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
10350 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
10351 return;
10352 }
10353 // we divide the work into three loops to avoid mixing DOM reads and writes
10354 // in each iteration - which helps prevent layout thrashing.
10355 prevChildren.forEach(callPendingCbs);
10356 prevChildren.forEach(recordPosition);
10357 const movedChildren = prevChildren.filter(applyTranslation);
10358 // force reflow to put everything in position
10359 forceReflow();
10360 movedChildren.forEach(c => {
10361 const el = c.el;
10362 const style = el.style;
10363 addTransitionClass(el, moveClass);
10364 style.transform = style.webkitTransform = style.transitionDuration = '';
10365 const cb = (el._moveCb = (e) => {
10366 if (e && e.target !== el) {
10367 return;
10368 }
10369 if (!e || /transform$/.test(e.propertyName)) {
10370 el.removeEventListener('transitionend', cb);
10371 el._moveCb = null;
10372 removeTransitionClass(el, moveClass);
10373 }
10374 });
10375 el.addEventListener('transitionend', cb);
10376 });
10377 });
10378 return () => {
10379 const rawProps = toRaw(props);
10380 const cssTransitionProps = resolveTransitionProps(rawProps);
10381 let tag = rawProps.tag || Fragment;
10382 prevChildren = children;
10383 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
10384 for (let i = 0; i < children.length; i++) {
10385 const child = children[i];
10386 if (child.key != null) {
10387 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10388 }
10389 else {
10390 warn$1(`<TransitionGroup> children must be keyed.`);
10391 }
10392 }
10393 if (prevChildren) {
10394 for (let i = 0; i < prevChildren.length; i++) {
10395 const child = prevChildren[i];
10396 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10397 positionMap.set(child, child.el.getBoundingClientRect());
10398 }
10399 }
10400 return createVNode(tag, null, children);
10401 };
10402 }
10403};
10404const TransitionGroup = TransitionGroupImpl;
10405function callPendingCbs(c) {
10406 const el = c.el;
10407 if (el._moveCb) {
10408 el._moveCb();
10409 }
10410 if (el._enterCb) {
10411 el._enterCb();
10412 }
10413}
10414function recordPosition(c) {
10415 newPositionMap.set(c, c.el.getBoundingClientRect());
10416}
10417function applyTranslation(c) {
10418 const oldPos = positionMap.get(c);
10419 const newPos = newPositionMap.get(c);
10420 const dx = oldPos.left - newPos.left;
10421 const dy = oldPos.top - newPos.top;
10422 if (dx || dy) {
10423 const s = c.el.style;
10424 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
10425 s.transitionDuration = '0s';
10426 return c;
10427 }
10428}
10429function hasCSSTransform(el, root, moveClass) {
10430 // Detect whether an element with the move class applied has
10431 // CSS transitions. Since the element may be inside an entering
10432 // transition at this very moment, we make a clone of it and remove
10433 // all other transition classes applied to ensure only the move class
10434 // is applied.
10435 const clone = el.cloneNode();
10436 if (el._vtc) {
10437 el._vtc.forEach(cls => {
10438 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
10439 });
10440 }
10441 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
10442 clone.style.display = 'none';
10443 const container = (root.nodeType === 1 ? root : root.parentNode);
10444 container.appendChild(clone);
10445 const { hasTransform } = getTransitionInfo(clone);
10446 container.removeChild(clone);
10447 return hasTransform;
10448}
10449
10450const getModelAssigner = (vnode) => {
10451 const fn = vnode.props['onUpdate:modelValue'] ||
10452 (false );
10453 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
10454};
10455function onCompositionStart(e) {
10456 e.target.composing = true;
10457}
10458function onCompositionEnd(e) {
10459 const target = e.target;
10460 if (target.composing) {
10461 target.composing = false;
10462 target.dispatchEvent(new Event('input'));
10463 }
10464}
10465// We are exporting the v-model runtime directly as vnode hooks so that it can
10466// be tree-shaken in case v-model is never used.
10467const vModelText = {
10468 created(el, { modifiers: { lazy, trim, number } }, vnode) {
10469 el._assign = getModelAssigner(vnode);
10470 const castToNumber = number || (vnode.props && vnode.props.type === 'number');
10471 addEventListener(el, lazy ? 'change' : 'input', e => {
10472 if (e.target.composing)
10473 return;
10474 let domValue = el.value;
10475 if (trim) {
10476 domValue = domValue.trim();
10477 }
10478 if (castToNumber) {
10479 domValue = toNumber(domValue);
10480 }
10481 el._assign(domValue);
10482 });
10483 if (trim) {
10484 addEventListener(el, 'change', () => {
10485 el.value = el.value.trim();
10486 });
10487 }
10488 if (!lazy) {
10489 addEventListener(el, 'compositionstart', onCompositionStart);
10490 addEventListener(el, 'compositionend', onCompositionEnd);
10491 // Safari < 10.2 & UIWebView doesn't fire compositionend when
10492 // switching focus before confirming composition choice
10493 // this also fixes the issue where some browsers e.g. iOS Chrome
10494 // fires "change" instead of "input" on autocomplete.
10495 addEventListener(el, 'change', onCompositionEnd);
10496 }
10497 },
10498 // set value on mounted so it's after min/max for type="range"
10499 mounted(el, { value }) {
10500 el.value = value == null ? '' : value;
10501 },
10502 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
10503 el._assign = getModelAssigner(vnode);
10504 // avoid clearing unresolved text. #2302
10505 if (el.composing)
10506 return;
10507 if (document.activeElement === el && el.type !== 'range') {
10508 if (lazy) {
10509 return;
10510 }
10511 if (trim && el.value.trim() === value) {
10512 return;
10513 }
10514 if ((number || el.type === 'number') && toNumber(el.value) === value) {
10515 return;
10516 }
10517 }
10518 const newValue = value == null ? '' : value;
10519 if (el.value !== newValue) {
10520 el.value = newValue;
10521 }
10522 }
10523};
10524const vModelCheckbox = {
10525 // #4096 array checkboxes need to be deep traversed
10526 deep: true,
10527 created(el, _, vnode) {
10528 el._assign = getModelAssigner(vnode);
10529 addEventListener(el, 'change', () => {
10530 const modelValue = el._modelValue;
10531 const elementValue = getValue(el);
10532 const checked = el.checked;
10533 const assign = el._assign;
10534 if (isArray(modelValue)) {
10535 const index = looseIndexOf(modelValue, elementValue);
10536 const found = index !== -1;
10537 if (checked && !found) {
10538 assign(modelValue.concat(elementValue));
10539 }
10540 else if (!checked && found) {
10541 const filtered = [...modelValue];
10542 filtered.splice(index, 1);
10543 assign(filtered);
10544 }
10545 }
10546 else if (isSet(modelValue)) {
10547 const cloned = new Set(modelValue);
10548 if (checked) {
10549 cloned.add(elementValue);
10550 }
10551 else {
10552 cloned.delete(elementValue);
10553 }
10554 assign(cloned);
10555 }
10556 else {
10557 assign(getCheckboxValue(el, checked));
10558 }
10559 });
10560 },
10561 // set initial checked on mount to wait for true-value/false-value
10562 mounted: setChecked,
10563 beforeUpdate(el, binding, vnode) {
10564 el._assign = getModelAssigner(vnode);
10565 setChecked(el, binding, vnode);
10566 }
10567};
10568function setChecked(el, { value, oldValue }, vnode) {
10569 el._modelValue = value;
10570 if (isArray(value)) {
10571 el.checked = looseIndexOf(value, vnode.props.value) > -1;
10572 }
10573 else if (isSet(value)) {
10574 el.checked = value.has(vnode.props.value);
10575 }
10576 else if (value !== oldValue) {
10577 el.checked = looseEqual(value, getCheckboxValue(el, true));
10578 }
10579}
10580const vModelRadio = {
10581 created(el, { value }, vnode) {
10582 el.checked = looseEqual(value, vnode.props.value);
10583 el._assign = getModelAssigner(vnode);
10584 addEventListener(el, 'change', () => {
10585 el._assign(getValue(el));
10586 });
10587 },
10588 beforeUpdate(el, { value, oldValue }, vnode) {
10589 el._assign = getModelAssigner(vnode);
10590 if (value !== oldValue) {
10591 el.checked = looseEqual(value, vnode.props.value);
10592 }
10593 }
10594};
10595const vModelSelect = {
10596 // <select multiple> value need to be deep traversed
10597 deep: true,
10598 created(el, { value, modifiers: { number } }, vnode) {
10599 const isSetModel = isSet(value);
10600 addEventListener(el, 'change', () => {
10601 const selectedVal = Array.prototype.filter
10602 .call(el.options, (o) => o.selected)
10603 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
10604 el._assign(el.multiple
10605 ? isSetModel
10606 ? new Set(selectedVal)
10607 : selectedVal
10608 : selectedVal[0]);
10609 });
10610 el._assign = getModelAssigner(vnode);
10611 },
10612 // set value in mounted & updated because <select> relies on its children
10613 // <option>s.
10614 mounted(el, { value }) {
10615 setSelected(el, value);
10616 },
10617 beforeUpdate(el, _binding, vnode) {
10618 el._assign = getModelAssigner(vnode);
10619 },
10620 updated(el, { value }) {
10621 setSelected(el, value);
10622 }
10623};
10624function setSelected(el, value) {
10625 const isMultiple = el.multiple;
10626 if (isMultiple && !isArray(value) && !isSet(value)) {
10627 warn$1(`<select multiple v-model> expects an Array or Set value for its binding, ` +
10628 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
10629 return;
10630 }
10631 for (let i = 0, l = el.options.length; i < l; i++) {
10632 const option = el.options[i];
10633 const optionValue = getValue(option);
10634 if (isMultiple) {
10635 if (isArray(value)) {
10636 option.selected = looseIndexOf(value, optionValue) > -1;
10637 }
10638 else {
10639 option.selected = value.has(optionValue);
10640 }
10641 }
10642 else {
10643 if (looseEqual(getValue(option), value)) {
10644 if (el.selectedIndex !== i)
10645 el.selectedIndex = i;
10646 return;
10647 }
10648 }
10649 }
10650 if (!isMultiple && el.selectedIndex !== -1) {
10651 el.selectedIndex = -1;
10652 }
10653}
10654// retrieve raw value set via :value bindings
10655function getValue(el) {
10656 return '_value' in el ? el._value : el.value;
10657}
10658// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
10659function getCheckboxValue(el, checked) {
10660 const key = checked ? '_trueValue' : '_falseValue';
10661 return key in el ? el[key] : checked;
10662}
10663const vModelDynamic = {
10664 created(el, binding, vnode) {
10665 callModelHook(el, binding, vnode, null, 'created');
10666 },
10667 mounted(el, binding, vnode) {
10668 callModelHook(el, binding, vnode, null, 'mounted');
10669 },
10670 beforeUpdate(el, binding, vnode, prevVNode) {
10671 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
10672 },
10673 updated(el, binding, vnode, prevVNode) {
10674 callModelHook(el, binding, vnode, prevVNode, 'updated');
10675 }
10676};
10677function resolveDynamicModel(tagName, type) {
10678 switch (tagName) {
10679 case 'SELECT':
10680 return vModelSelect;
10681 case 'TEXTAREA':
10682 return vModelText;
10683 default:
10684 switch (type) {
10685 case 'checkbox':
10686 return vModelCheckbox;
10687 case 'radio':
10688 return vModelRadio;
10689 default:
10690 return vModelText;
10691 }
10692 }
10693}
10694function callModelHook(el, binding, vnode, prevVNode, hook) {
10695 const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
10696 const fn = modelToUse[hook];
10697 fn && fn(el, binding, vnode, prevVNode);
10698}
10699
10700const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
10701const modifierGuards = {
10702 stop: e => e.stopPropagation(),
10703 prevent: e => e.preventDefault(),
10704 self: e => e.target !== e.currentTarget,
10705 ctrl: e => !e.ctrlKey,
10706 shift: e => !e.shiftKey,
10707 alt: e => !e.altKey,
10708 meta: e => !e.metaKey,
10709 left: e => 'button' in e && e.button !== 0,
10710 middle: e => 'button' in e && e.button !== 1,
10711 right: e => 'button' in e && e.button !== 2,
10712 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
10713};
10714/**
10715 * @private
10716 */
10717const withModifiers = (fn, modifiers) => {
10718 return (event, ...args) => {
10719 for (let i = 0; i < modifiers.length; i++) {
10720 const guard = modifierGuards[modifiers[i]];
10721 if (guard && guard(event, modifiers))
10722 return;
10723 }
10724 return fn(event, ...args);
10725 };
10726};
10727// Kept for 2.x compat.
10728// Note: IE11 compat for `spacebar` and `del` is removed for now.
10729const keyNames = {
10730 esc: 'escape',
10731 space: ' ',
10732 up: 'arrow-up',
10733 left: 'arrow-left',
10734 right: 'arrow-right',
10735 down: 'arrow-down',
10736 delete: 'backspace'
10737};
10738/**
10739 * @private
10740 */
10741const withKeys = (fn, modifiers) => {
10742 return (event) => {
10743 if (!('key' in event)) {
10744 return;
10745 }
10746 const eventKey = hyphenate(event.key);
10747 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
10748 return fn(event);
10749 }
10750 };
10751};
10752
10753const vShow = {
10754 beforeMount(el, { value }, { transition }) {
10755 el._vod = el.style.display === 'none' ? '' : el.style.display;
10756 if (transition && value) {
10757 transition.beforeEnter(el);
10758 }
10759 else {
10760 setDisplay(el, value);
10761 }
10762 },
10763 mounted(el, { value }, { transition }) {
10764 if (transition && value) {
10765 transition.enter(el);
10766 }
10767 },
10768 updated(el, { value, oldValue }, { transition }) {
10769 if (!value === !oldValue)
10770 return;
10771 if (transition) {
10772 if (value) {
10773 transition.beforeEnter(el);
10774 setDisplay(el, true);
10775 transition.enter(el);
10776 }
10777 else {
10778 transition.leave(el, () => {
10779 setDisplay(el, false);
10780 });
10781 }
10782 }
10783 else {
10784 setDisplay(el, value);
10785 }
10786 },
10787 beforeUnmount(el, { value }) {
10788 setDisplay(el, value);
10789 }
10790};
10791function setDisplay(el, value) {
10792 el.style.display = value ? el._vod : 'none';
10793}
10794
10795const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps);
10796// lazy create the renderer - this makes core renderer logic tree-shakable
10797// in case the user only imports reactivity utilities from Vue.
10798let renderer;
10799let enabledHydration = false;
10800function ensureRenderer() {
10801 return (renderer ||
10802 (renderer = createRenderer(rendererOptions)));
10803}
10804function ensureHydrationRenderer() {
10805 renderer = enabledHydration
10806 ? renderer
10807 : createHydrationRenderer(rendererOptions);
10808 enabledHydration = true;
10809 return renderer;
10810}
10811// use explicit type casts here to avoid import() calls in rolled-up d.ts
10812const render = ((...args) => {
10813 ensureRenderer().render(...args);
10814});
10815const hydrate = ((...args) => {
10816 ensureHydrationRenderer().hydrate(...args);
10817});
10818const createApp = ((...args) => {
10819 const app = ensureRenderer().createApp(...args);
10820 {
10821 injectNativeTagCheck(app);
10822 injectCompilerOptionsCheck(app);
10823 }
10824 const { mount } = app;
10825 app.mount = (containerOrSelector) => {
10826 const container = normalizeContainer(containerOrSelector);
10827 if (!container)
10828 return;
10829 const component = app._component;
10830 if (!isFunction(component) && !component.render && !component.template) {
10831 // __UNSAFE__
10832 // Reason: potential execution of JS expressions in in-DOM template.
10833 // The user must make sure the in-DOM template is trusted. If it's
10834 // rendered by the server, the template should not contain any user data.
10835 component.template = container.innerHTML;
10836 }
10837 // clear content before mounting
10838 container.innerHTML = '';
10839 const proxy = mount(container, false, container instanceof SVGElement);
10840 if (container instanceof Element) {
10841 container.removeAttribute('v-cloak');
10842 container.setAttribute('data-v-app', '');
10843 }
10844 return proxy;
10845 };
10846 return app;
10847});
10848const createSSRApp = ((...args) => {
10849 const app = ensureHydrationRenderer().createApp(...args);
10850 {
10851 injectNativeTagCheck(app);
10852 injectCompilerOptionsCheck(app);
10853 }
10854 const { mount } = app;
10855 app.mount = (containerOrSelector) => {
10856 const container = normalizeContainer(containerOrSelector);
10857 if (container) {
10858 return mount(container, true, container instanceof SVGElement);
10859 }
10860 };
10861 return app;
10862});
10863function injectNativeTagCheck(app) {
10864 // Inject `isNativeTag`
10865 // this is used for component name validation (dev only)
10866 Object.defineProperty(app.config, 'isNativeTag', {
10867 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
10868 writable: false
10869 });
10870}
10871// dev only
10872function injectCompilerOptionsCheck(app) {
10873 if (isRuntimeOnly()) {
10874 const isCustomElement = app.config.isCustomElement;
10875 Object.defineProperty(app.config, 'isCustomElement', {
10876 get() {
10877 return isCustomElement;
10878 },
10879 set() {
10880 warn$1(`The \`isCustomElement\` config option is deprecated. Use ` +
10881 `\`compilerOptions.isCustomElement\` instead.`);
10882 }
10883 });
10884 const compilerOptions = app.config.compilerOptions;
10885 const msg = `The \`compilerOptions\` config option is only respected when using ` +
10886 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
10887 `Since you are using the runtime-only build, \`compilerOptions\` ` +
10888 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
10889 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
10890 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
10891 `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom`;
10892 Object.defineProperty(app.config, 'compilerOptions', {
10893 get() {
10894 warn$1(msg);
10895 return compilerOptions;
10896 },
10897 set() {
10898 warn$1(msg);
10899 }
10900 });
10901 }
10902}
10903function normalizeContainer(container) {
10904 if (isString(container)) {
10905 const res = document.querySelector(container);
10906 if (!res) {
10907 warn$1(`Failed to mount app: mount target selector "${container}" returned null.`);
10908 }
10909 return res;
10910 }
10911 if (window.ShadowRoot &&
10912 container instanceof window.ShadowRoot &&
10913 container.mode === 'closed') {
10914 warn$1(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
10915 }
10916 return container;
10917}
10918/**
10919 * @internal
10920 */
10921const initDirectivesForSSR = NOOP;
10922
10923var runtimeDom = /*#__PURE__*/Object.freeze({
10924 __proto__: null,
10925 render: render,
10926 hydrate: hydrate,
10927 createApp: createApp,
10928 createSSRApp: createSSRApp,
10929 initDirectivesForSSR: initDirectivesForSSR,
10930 defineCustomElement: defineCustomElement,
10931 defineSSRCustomElement: defineSSRCustomElement,
10932 VueElement: VueElement,
10933 useCssModule: useCssModule,
10934 useCssVars: useCssVars,
10935 Transition: Transition,
10936 TransitionGroup: TransitionGroup,
10937 vModelText: vModelText,
10938 vModelCheckbox: vModelCheckbox,
10939 vModelRadio: vModelRadio,
10940 vModelSelect: vModelSelect,
10941 vModelDynamic: vModelDynamic,
10942 withModifiers: withModifiers,
10943 withKeys: withKeys,
10944 vShow: vShow,
10945 reactive: reactive,
10946 ref: ref,
10947 readonly: readonly,
10948 unref: unref,
10949 proxyRefs: proxyRefs,
10950 isRef: isRef,
10951 toRef: toRef,
10952 toRefs: toRefs,
10953 isProxy: isProxy,
10954 isReactive: isReactive,
10955 isReadonly: isReadonly,
10956 isShallow: isShallow,
10957 customRef: customRef,
10958 triggerRef: triggerRef,
10959 shallowRef: shallowRef,
10960 shallowReactive: shallowReactive,
10961 shallowReadonly: shallowReadonly,
10962 markRaw: markRaw,
10963 toRaw: toRaw,
10964 effect: effect,
10965 stop: stop,
10966 ReactiveEffect: ReactiveEffect,
10967 effectScope: effectScope,
10968 EffectScope: EffectScope,
10969 getCurrentScope: getCurrentScope,
10970 onScopeDispose: onScopeDispose,
10971 computed: computed$1,
10972 watch: watch,
10973 watchEffect: watchEffect,
10974 watchPostEffect: watchPostEffect,
10975 watchSyncEffect: watchSyncEffect,
10976 onBeforeMount: onBeforeMount,
10977 onMounted: onMounted,
10978 onBeforeUpdate: onBeforeUpdate,
10979 onUpdated: onUpdated,
10980 onBeforeUnmount: onBeforeUnmount,
10981 onUnmounted: onUnmounted,
10982 onActivated: onActivated,
10983 onDeactivated: onDeactivated,
10984 onRenderTracked: onRenderTracked,
10985 onRenderTriggered: onRenderTriggered,
10986 onErrorCaptured: onErrorCaptured,
10987 onServerPrefetch: onServerPrefetch,
10988 provide: provide,
10989 inject: inject,
10990 nextTick: nextTick,
10991 defineComponent: defineComponent,
10992 defineAsyncComponent: defineAsyncComponent,
10993 useAttrs: useAttrs,
10994 useSlots: useSlots,
10995 defineProps: defineProps,
10996 defineEmits: defineEmits,
10997 defineExpose: defineExpose,
10998 withDefaults: withDefaults,
10999 mergeDefaults: mergeDefaults,
11000 createPropsRestProxy: createPropsRestProxy,
11001 withAsyncContext: withAsyncContext,
11002 getCurrentInstance: getCurrentInstance,
11003 h: h,
11004 createVNode: createVNode,
11005 cloneVNode: cloneVNode,
11006 mergeProps: mergeProps,
11007 isVNode: isVNode,
11008 Fragment: Fragment,
11009 Text: Text,
11010 Comment: Comment,
11011 Static: Static,
11012 Teleport: Teleport,
11013 Suspense: Suspense,
11014 KeepAlive: KeepAlive,
11015 BaseTransition: BaseTransition,
11016 withDirectives: withDirectives,
11017 useSSRContext: useSSRContext,
11018 ssrContextKey: ssrContextKey,
11019 createRenderer: createRenderer,
11020 createHydrationRenderer: createHydrationRenderer,
11021 queuePostFlushCb: queuePostFlushCb,
11022 warn: warn$1,
11023 handleError: handleError,
11024 callWithErrorHandling: callWithErrorHandling,
11025 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
11026 resolveComponent: resolveComponent,
11027 resolveDirective: resolveDirective,
11028 resolveDynamicComponent: resolveDynamicComponent,
11029 registerRuntimeCompiler: registerRuntimeCompiler,
11030 isRuntimeOnly: isRuntimeOnly,
11031 useTransitionState: useTransitionState,
11032 resolveTransitionHooks: resolveTransitionHooks,
11033 setTransitionHooks: setTransitionHooks,
11034 getTransitionRawChildren: getTransitionRawChildren,
11035 initCustomFormatter: initCustomFormatter,
11036 get devtools () { return devtools; },
11037 setDevtoolsHook: setDevtoolsHook,
11038 withCtx: withCtx,
11039 pushScopeId: pushScopeId,
11040 popScopeId: popScopeId,
11041 withScopeId: withScopeId,
11042 renderList: renderList,
11043 toHandlers: toHandlers,
11044 renderSlot: renderSlot,
11045 createSlots: createSlots,
11046 withMemo: withMemo,
11047 isMemoSame: isMemoSame,
11048 openBlock: openBlock,
11049 createBlock: createBlock,
11050 setBlockTracking: setBlockTracking,
11051 createTextVNode: createTextVNode,
11052 createCommentVNode: createCommentVNode,
11053 createStaticVNode: createStaticVNode,
11054 createElementVNode: createBaseVNode,
11055 createElementBlock: createElementBlock,
11056 guardReactiveProps: guardReactiveProps,
11057 toDisplayString: toDisplayString,
11058 camelize: camelize,
11059 capitalize: capitalize,
11060 toHandlerKey: toHandlerKey,
11061 normalizeProps: normalizeProps,
11062 normalizeClass: normalizeClass,
11063 normalizeStyle: normalizeStyle,
11064 transformVNodeArgs: transformVNodeArgs,
11065 version: version,
11066 ssrUtils: ssrUtils,
11067 resolveFilter: resolveFilter,
11068 compatUtils: compatUtils
11069});
11070
11071function initDev() {
11072 {
11073 {
11074 console.info(`You are running a development build of Vue.\n` +
11075 `Make sure to use the production build (*.prod.js) when deploying for production.`);
11076 }
11077 initCustomFormatter();
11078 }
11079}
11080
11081function defaultOnError(error) {
11082 throw error;
11083}
11084function defaultOnWarn(msg) {
11085 console.warn(`[Vue warn] ${msg.message}`);
11086}
11087function createCompilerError(code, loc, messages, additionalMessage) {
11088 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
11089 ;
11090 const error = new SyntaxError(String(msg));
11091 error.code = code;
11092 error.loc = loc;
11093 return error;
11094}
11095const errorMessages = {
11096 // parse errors
11097 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
11098 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
11099 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
11100 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
11101 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
11102 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
11103 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
11104 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
11105 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
11106 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
11107 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
11108 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
11109 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
11110 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
11111 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
11112 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
11113 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
11114 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
11115 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
11116 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
11117 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
11118 [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
11119 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
11120 // Vue-specific parse errors
11121 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
11122 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
11123 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
11124 [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
11125 'Note that dynamic directive argument cannot contain spaces.',
11126 [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
11127 // transform errors
11128 [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
11129 [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
11130 [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
11131 [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
11132 [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
11133 [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
11134 [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
11135 [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
11136 [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
11137 [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
11138 `When there are multiple named slots, all slots should use <template> ` +
11139 `syntax to avoid scope ambiguity.`,
11140 [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
11141 [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
11142 `default slot. These children will be ignored.`,
11143 [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
11144 [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
11145 [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
11146 [43 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
11147 [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
11148 [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
11149 // generic errors
11150 [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
11151 [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
11152 [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
11153 [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
11154 // just to fulfill types
11155 [50 /* __EXTEND_POINT__ */]: ``
11156};
11157
11158const FRAGMENT = Symbol(`Fragment` );
11159const TELEPORT = Symbol(`Teleport` );
11160const SUSPENSE = Symbol(`Suspense` );
11161const KEEP_ALIVE = Symbol(`KeepAlive` );
11162const BASE_TRANSITION = Symbol(`BaseTransition` );
11163const OPEN_BLOCK = Symbol(`openBlock` );
11164const CREATE_BLOCK = Symbol(`createBlock` );
11165const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` );
11166const CREATE_VNODE = Symbol(`createVNode` );
11167const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` );
11168const CREATE_COMMENT = Symbol(`createCommentVNode` );
11169const CREATE_TEXT = Symbol(`createTextVNode` );
11170const CREATE_STATIC = Symbol(`createStaticVNode` );
11171const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
11172const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
11173const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
11174const RESOLVE_FILTER = Symbol(`resolveFilter` );
11175const WITH_DIRECTIVES = Symbol(`withDirectives` );
11176const RENDER_LIST = Symbol(`renderList` );
11177const RENDER_SLOT = Symbol(`renderSlot` );
11178const CREATE_SLOTS = Symbol(`createSlots` );
11179const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
11180const MERGE_PROPS = Symbol(`mergeProps` );
11181const NORMALIZE_CLASS = Symbol(`normalizeClass` );
11182const NORMALIZE_STYLE = Symbol(`normalizeStyle` );
11183const NORMALIZE_PROPS = Symbol(`normalizeProps` );
11184const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` );
11185const TO_HANDLERS = Symbol(`toHandlers` );
11186const CAMELIZE = Symbol(`camelize` );
11187const CAPITALIZE = Symbol(`capitalize` );
11188const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
11189const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
11190const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
11191const POP_SCOPE_ID = Symbol(`popScopeId` );
11192const WITH_CTX = Symbol(`withCtx` );
11193const UNREF = Symbol(`unref` );
11194const IS_REF = Symbol(`isRef` );
11195const WITH_MEMO = Symbol(`withMemo` );
11196const IS_MEMO_SAME = Symbol(`isMemoSame` );
11197// Name mapping for runtime helpers that need to be imported from 'vue' in
11198// generated code. Make sure these are correctly exported in the runtime!
11199// Using `any` here because TS doesn't allow symbols as index type.
11200const helperNameMap = {
11201 [FRAGMENT]: `Fragment`,
11202 [TELEPORT]: `Teleport`,
11203 [SUSPENSE]: `Suspense`,
11204 [KEEP_ALIVE]: `KeepAlive`,
11205 [BASE_TRANSITION]: `BaseTransition`,
11206 [OPEN_BLOCK]: `openBlock`,
11207 [CREATE_BLOCK]: `createBlock`,
11208 [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
11209 [CREATE_VNODE]: `createVNode`,
11210 [CREATE_ELEMENT_VNODE]: `createElementVNode`,
11211 [CREATE_COMMENT]: `createCommentVNode`,
11212 [CREATE_TEXT]: `createTextVNode`,
11213 [CREATE_STATIC]: `createStaticVNode`,
11214 [RESOLVE_COMPONENT]: `resolveComponent`,
11215 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
11216 [RESOLVE_DIRECTIVE]: `resolveDirective`,
11217 [RESOLVE_FILTER]: `resolveFilter`,
11218 [WITH_DIRECTIVES]: `withDirectives`,
11219 [RENDER_LIST]: `renderList`,
11220 [RENDER_SLOT]: `renderSlot`,
11221 [CREATE_SLOTS]: `createSlots`,
11222 [TO_DISPLAY_STRING]: `toDisplayString`,
11223 [MERGE_PROPS]: `mergeProps`,
11224 [NORMALIZE_CLASS]: `normalizeClass`,
11225 [NORMALIZE_STYLE]: `normalizeStyle`,
11226 [NORMALIZE_PROPS]: `normalizeProps`,
11227 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
11228 [TO_HANDLERS]: `toHandlers`,
11229 [CAMELIZE]: `camelize`,
11230 [CAPITALIZE]: `capitalize`,
11231 [TO_HANDLER_KEY]: `toHandlerKey`,
11232 [SET_BLOCK_TRACKING]: `setBlockTracking`,
11233 [PUSH_SCOPE_ID]: `pushScopeId`,
11234 [POP_SCOPE_ID]: `popScopeId`,
11235 [WITH_CTX]: `withCtx`,
11236 [UNREF]: `unref`,
11237 [IS_REF]: `isRef`,
11238 [WITH_MEMO]: `withMemo`,
11239 [IS_MEMO_SAME]: `isMemoSame`
11240};
11241function registerRuntimeHelpers(helpers) {
11242 Object.getOwnPropertySymbols(helpers).forEach(s => {
11243 helperNameMap[s] = helpers[s];
11244 });
11245}
11246
11247// AST Utilities ---------------------------------------------------------------
11248// Some expressions, e.g. sequence and conditional expressions, are never
11249// associated with template nodes, so their source locations are just a stub.
11250// Container types like CompoundExpression also don't need a real location.
11251const locStub = {
11252 source: '',
11253 start: { line: 1, column: 1, offset: 0 },
11254 end: { line: 1, column: 1, offset: 0 }
11255};
11256function createRoot(children, loc = locStub) {
11257 return {
11258 type: 0 /* ROOT */,
11259 children,
11260 helpers: [],
11261 components: [],
11262 directives: [],
11263 hoists: [],
11264 imports: [],
11265 cached: 0,
11266 temps: 0,
11267 codegenNode: undefined,
11268 loc
11269 };
11270}
11271function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
11272 if (context) {
11273 if (isBlock) {
11274 context.helper(OPEN_BLOCK);
11275 context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
11276 }
11277 else {
11278 context.helper(getVNodeHelper(context.inSSR, isComponent));
11279 }
11280 if (directives) {
11281 context.helper(WITH_DIRECTIVES);
11282 }
11283 }
11284 return {
11285 type: 13 /* VNODE_CALL */,
11286 tag,
11287 props,
11288 children,
11289 patchFlag,
11290 dynamicProps,
11291 directives,
11292 isBlock,
11293 disableTracking,
11294 isComponent,
11295 loc
11296 };
11297}
11298function createArrayExpression(elements, loc = locStub) {
11299 return {
11300 type: 17 /* JS_ARRAY_EXPRESSION */,
11301 loc,
11302 elements
11303 };
11304}
11305function createObjectExpression(properties, loc = locStub) {
11306 return {
11307 type: 15 /* JS_OBJECT_EXPRESSION */,
11308 loc,
11309 properties
11310 };
11311}
11312function createObjectProperty(key, value) {
11313 return {
11314 type: 16 /* JS_PROPERTY */,
11315 loc: locStub,
11316 key: isString(key) ? createSimpleExpression(key, true) : key,
11317 value
11318 };
11319}
11320function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
11321 return {
11322 type: 4 /* SIMPLE_EXPRESSION */,
11323 loc,
11324 content,
11325 isStatic,
11326 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
11327 };
11328}
11329function createCompoundExpression(children, loc = locStub) {
11330 return {
11331 type: 8 /* COMPOUND_EXPRESSION */,
11332 loc,
11333 children
11334 };
11335}
11336function createCallExpression(callee, args = [], loc = locStub) {
11337 return {
11338 type: 14 /* JS_CALL_EXPRESSION */,
11339 loc,
11340 callee,
11341 arguments: args
11342 };
11343}
11344function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
11345 return {
11346 type: 18 /* JS_FUNCTION_EXPRESSION */,
11347 params,
11348 returns,
11349 newline,
11350 isSlot,
11351 loc
11352 };
11353}
11354function createConditionalExpression(test, consequent, alternate, newline = true) {
11355 return {
11356 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
11357 test,
11358 consequent,
11359 alternate,
11360 newline,
11361 loc: locStub
11362 };
11363}
11364function createCacheExpression(index, value, isVNode = false) {
11365 return {
11366 type: 20 /* JS_CACHE_EXPRESSION */,
11367 index,
11368 value,
11369 isVNode,
11370 loc: locStub
11371 };
11372}
11373function createBlockStatement(body) {
11374 return {
11375 type: 21 /* JS_BLOCK_STATEMENT */,
11376 body,
11377 loc: locStub
11378 };
11379}
11380
11381const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
11382const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
11383function isCoreComponent(tag) {
11384 if (isBuiltInType(tag, 'Teleport')) {
11385 return TELEPORT;
11386 }
11387 else if (isBuiltInType(tag, 'Suspense')) {
11388 return SUSPENSE;
11389 }
11390 else if (isBuiltInType(tag, 'KeepAlive')) {
11391 return KEEP_ALIVE;
11392 }
11393 else if (isBuiltInType(tag, 'BaseTransition')) {
11394 return BASE_TRANSITION;
11395 }
11396}
11397const nonIdentifierRE = /^\d|[^\$\w]/;
11398const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
11399const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
11400const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
11401const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
11402/**
11403 * Simple lexer to check if an expression is a member expression. This is
11404 * lax and only checks validity at the root level (i.e. does not validate exps
11405 * inside square brackets), but it's ok since these are only used on template
11406 * expressions and false positives are invalid expressions in the first place.
11407 */
11408const isMemberExpressionBrowser = (path) => {
11409 // remove whitespaces around . or [ first
11410 path = path.trim().replace(whitespaceRE, s => s.trim());
11411 let state = 0 /* inMemberExp */;
11412 let stateStack = [];
11413 let currentOpenBracketCount = 0;
11414 let currentOpenParensCount = 0;
11415 let currentStringType = null;
11416 for (let i = 0; i < path.length; i++) {
11417 const char = path.charAt(i);
11418 switch (state) {
11419 case 0 /* inMemberExp */:
11420 if (char === '[') {
11421 stateStack.push(state);
11422 state = 1 /* inBrackets */;
11423 currentOpenBracketCount++;
11424 }
11425 else if (char === '(') {
11426 stateStack.push(state);
11427 state = 2 /* inParens */;
11428 currentOpenParensCount++;
11429 }
11430 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
11431 return false;
11432 }
11433 break;
11434 case 1 /* inBrackets */:
11435 if (char === `'` || char === `"` || char === '`') {
11436 stateStack.push(state);
11437 state = 3 /* inString */;
11438 currentStringType = char;
11439 }
11440 else if (char === `[`) {
11441 currentOpenBracketCount++;
11442 }
11443 else if (char === `]`) {
11444 if (!--currentOpenBracketCount) {
11445 state = stateStack.pop();
11446 }
11447 }
11448 break;
11449 case 2 /* inParens */:
11450 if (char === `'` || char === `"` || char === '`') {
11451 stateStack.push(state);
11452 state = 3 /* inString */;
11453 currentStringType = char;
11454 }
11455 else if (char === `(`) {
11456 currentOpenParensCount++;
11457 }
11458 else if (char === `)`) {
11459 // if the exp ends as a call then it should not be considered valid
11460 if (i === path.length - 1) {
11461 return false;
11462 }
11463 if (!--currentOpenParensCount) {
11464 state = stateStack.pop();
11465 }
11466 }
11467 break;
11468 case 3 /* inString */:
11469 if (char === currentStringType) {
11470 state = stateStack.pop();
11471 currentStringType = null;
11472 }
11473 break;
11474 }
11475 }
11476 return !currentOpenBracketCount && !currentOpenParensCount;
11477};
11478const isMemberExpression = isMemberExpressionBrowser
11479 ;
11480function getInnerRange(loc, offset, length) {
11481 const source = loc.source.slice(offset, offset + length);
11482 const newLoc = {
11483 source,
11484 start: advancePositionWithClone(loc.start, loc.source, offset),
11485 end: loc.end
11486 };
11487 if (length != null) {
11488 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
11489 }
11490 return newLoc;
11491}
11492function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
11493 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
11494}
11495// advance by mutation without cloning (for performance reasons), since this
11496// gets called a lot in the parser
11497function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
11498 let linesCount = 0;
11499 let lastNewLinePos = -1;
11500 for (let i = 0; i < numberOfCharacters; i++) {
11501 if (source.charCodeAt(i) === 10 /* newline char code */) {
11502 linesCount++;
11503 lastNewLinePos = i;
11504 }
11505 }
11506 pos.offset += numberOfCharacters;
11507 pos.line += linesCount;
11508 pos.column =
11509 lastNewLinePos === -1
11510 ? pos.column + numberOfCharacters
11511 : numberOfCharacters - lastNewLinePos;
11512 return pos;
11513}
11514function assert(condition, msg) {
11515 /* istanbul ignore if */
11516 if (!condition) {
11517 throw new Error(msg || `unexpected compiler condition`);
11518 }
11519}
11520function findDir(node, name, allowEmpty = false) {
11521 for (let i = 0; i < node.props.length; i++) {
11522 const p = node.props[i];
11523 if (p.type === 7 /* DIRECTIVE */ &&
11524 (allowEmpty || p.exp) &&
11525 (isString(name) ? p.name === name : name.test(p.name))) {
11526 return p;
11527 }
11528 }
11529}
11530function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11531 for (let i = 0; i < node.props.length; i++) {
11532 const p = node.props[i];
11533 if (p.type === 6 /* ATTRIBUTE */) {
11534 if (dynamicOnly)
11535 continue;
11536 if (p.name === name && (p.value || allowEmpty)) {
11537 return p;
11538 }
11539 }
11540 else if (p.name === 'bind' &&
11541 (p.exp || allowEmpty) &&
11542 isStaticArgOf(p.arg, name)) {
11543 return p;
11544 }
11545 }
11546}
11547function isStaticArgOf(arg, name) {
11548 return !!(arg && isStaticExp(arg) && arg.content === name);
11549}
11550function hasDynamicKeyVBind(node) {
11551 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
11552 p.name === 'bind' &&
11553 (!p.arg || // v-bind="obj"
11554 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
11555 !p.arg.isStatic) // v-bind:[foo]
11556 );
11557}
11558function isText(node) {
11559 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
11560}
11561function isVSlot(p) {
11562 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
11563}
11564function isTemplateNode(node) {
11565 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
11566}
11567function isSlotOutlet(node) {
11568 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
11569}
11570function getVNodeHelper(ssr, isComponent) {
11571 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
11572}
11573function getVNodeBlockHelper(ssr, isComponent) {
11574 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
11575}
11576const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
11577function getUnnormalizedProps(props, callPath = []) {
11578 if (props &&
11579 !isString(props) &&
11580 props.type === 14 /* JS_CALL_EXPRESSION */) {
11581 const callee = props.callee;
11582 if (!isString(callee) && propsHelperSet.has(callee)) {
11583 return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
11584 }
11585 }
11586 return [props, callPath];
11587}
11588function injectProp(node, prop, context) {
11589 let propsWithInjection;
11590 /**
11591 * 1. mergeProps(...)
11592 * 2. toHandlers(...)
11593 * 3. normalizeProps(...)
11594 * 4. normalizeProps(guardReactiveProps(...))
11595 *
11596 * we need to get the real props before normalization
11597 */
11598 let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11599 let callPath = [];
11600 let parentCall;
11601 if (props &&
11602 !isString(props) &&
11603 props.type === 14 /* JS_CALL_EXPRESSION */) {
11604 const ret = getUnnormalizedProps(props);
11605 props = ret[0];
11606 callPath = ret[1];
11607 parentCall = callPath[callPath.length - 1];
11608 }
11609 if (props == null || isString(props)) {
11610 propsWithInjection = createObjectExpression([prop]);
11611 }
11612 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
11613 // merged props... add ours
11614 // only inject key to object literal if it's the first argument so that
11615 // if doesn't override user provided keys
11616 const first = props.arguments[0];
11617 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
11618 first.properties.unshift(prop);
11619 }
11620 else {
11621 if (props.callee === TO_HANDLERS) {
11622 // #2366
11623 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11624 createObjectExpression([prop]),
11625 props
11626 ]);
11627 }
11628 else {
11629 props.arguments.unshift(createObjectExpression([prop]));
11630 }
11631 }
11632 !propsWithInjection && (propsWithInjection = props);
11633 }
11634 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
11635 let alreadyExists = false;
11636 // check existing key to avoid overriding user provided keys
11637 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
11638 const propKeyName = prop.key.content;
11639 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
11640 p.key.content === propKeyName);
11641 }
11642 if (!alreadyExists) {
11643 props.properties.unshift(prop);
11644 }
11645 propsWithInjection = props;
11646 }
11647 else {
11648 // single v-bind with expression, return a merged replacement
11649 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11650 createObjectExpression([prop]),
11651 props
11652 ]);
11653 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
11654 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
11655 // the `guardReactiveProps` will no longer be needed
11656 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
11657 parentCall = callPath[callPath.length - 2];
11658 }
11659 }
11660 if (node.type === 13 /* VNODE_CALL */) {
11661 if (parentCall) {
11662 parentCall.arguments[0] = propsWithInjection;
11663 }
11664 else {
11665 node.props = propsWithInjection;
11666 }
11667 }
11668 else {
11669 if (parentCall) {
11670 parentCall.arguments[0] = propsWithInjection;
11671 }
11672 else {
11673 node.arguments[2] = propsWithInjection;
11674 }
11675 }
11676}
11677function toValidAssetId(name, type) {
11678 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
11679 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
11680 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
11681 })}`;
11682}
11683function getMemoedVNodeCall(node) {
11684 if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
11685 return node.arguments[1].returns;
11686 }
11687 else {
11688 return node;
11689 }
11690}
11691function makeBlock(node, { helper, removeHelper, inSSR }) {
11692 if (!node.isBlock) {
11693 node.isBlock = true;
11694 removeHelper(getVNodeHelper(inSSR, node.isComponent));
11695 helper(OPEN_BLOCK);
11696 helper(getVNodeBlockHelper(inSSR, node.isComponent));
11697 }
11698}
11699
11700const deprecationData = {
11701 ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
11702 message: `Platform-native elements with "is" prop will no longer be ` +
11703 `treated as components in Vue 3 unless the "is" value is explicitly ` +
11704 `prefixed with "vue:".`,
11705 link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
11706 },
11707 ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
11708 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
11709 `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
11710 `\`v-model:${key}\`.`,
11711 link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
11712 },
11713 ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
11714 message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
11715 `Vue 3 will automatically set a binding as DOM property when appropriate.`
11716 },
11717 ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
11718 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
11719 `object spread: it will now overwrite an existing non-mergeable attribute ` +
11720 `that appears before v-bind in the case of conflict. ` +
11721 `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
11722 `You can also suppress this warning if the usage is intended.`,
11723 link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
11724 },
11725 ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
11726 message: `.native modifier for v-on has been removed as is no longer necessary.`,
11727 link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
11728 },
11729 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
11730 message: `v-if / v-for precedence when used on the same element has changed ` +
11731 `in Vue 3: v-if now takes higher precedence and will no longer have ` +
11732 `access to v-for scope variables. It is best to avoid the ambiguity ` +
11733 `with <template> tags or use a computed property that filters v-for ` +
11734 `data source.`,
11735 link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
11736 },
11737 ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
11738 message: `<template> with no special directives will render as a native template ` +
11739 `element instead of its inner content in Vue 3.`
11740 },
11741 ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
11742 message: `"inline-template" has been removed in Vue 3.`,
11743 link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
11744 },
11745 ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
11746 message: `filters have been removed in Vue 3. ` +
11747 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
11748 `Use method calls or computed properties instead.`,
11749 link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
11750 }
11751};
11752function getCompatValue(key, context) {
11753 const config = context.options
11754 ? context.options.compatConfig
11755 : context.compatConfig;
11756 const value = config && config[key];
11757 if (key === 'MODE') {
11758 return value || 3; // compiler defaults to v3 behavior
11759 }
11760 else {
11761 return value;
11762 }
11763}
11764function isCompatEnabled(key, context) {
11765 const mode = getCompatValue('MODE', context);
11766 const value = getCompatValue(key, context);
11767 // in v3 mode, only enable if explicitly set to true
11768 // otherwise enable for any non-false value
11769 return mode === 3 ? value === true : value !== false;
11770}
11771function checkCompatEnabled(key, context, loc, ...args) {
11772 const enabled = isCompatEnabled(key, context);
11773 if (enabled) {
11774 warnDeprecation(key, context, loc, ...args);
11775 }
11776 return enabled;
11777}
11778function warnDeprecation(key, context, loc, ...args) {
11779 const val = getCompatValue(key, context);
11780 if (val === 'suppress-warning') {
11781 return;
11782 }
11783 const { message, link } = deprecationData[key];
11784 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
11785 const err = new SyntaxError(msg);
11786 err.code = key;
11787 if (loc)
11788 err.loc = loc;
11789 context.onWarn(err);
11790}
11791
11792// The default decoder only provides escapes for characters reserved as part of
11793// the template syntax, and is only used if the custom renderer did not provide
11794// a platform-specific decoder.
11795const decodeRE = /&(gt|lt|amp|apos|quot);/g;
11796const decodeMap = {
11797 gt: '>',
11798 lt: '<',
11799 amp: '&',
11800 apos: "'",
11801 quot: '"'
11802};
11803const defaultParserOptions = {
11804 delimiters: [`{{`, `}}`],
11805 getNamespace: () => 0 /* HTML */,
11806 getTextMode: () => 0 /* DATA */,
11807 isVoidTag: NO,
11808 isPreTag: NO,
11809 isCustomElement: NO,
11810 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
11811 onError: defaultOnError,
11812 onWarn: defaultOnWarn,
11813 comments: true
11814};
11815function baseParse(content, options = {}) {
11816 const context = createParserContext(content, options);
11817 const start = getCursor(context);
11818 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
11819}
11820function createParserContext(content, rawOptions) {
11821 const options = extend({}, defaultParserOptions);
11822 let key;
11823 for (key in rawOptions) {
11824 // @ts-ignore
11825 options[key] =
11826 rawOptions[key] === undefined
11827 ? defaultParserOptions[key]
11828 : rawOptions[key];
11829 }
11830 return {
11831 options,
11832 column: 1,
11833 line: 1,
11834 offset: 0,
11835 originalSource: content,
11836 source: content,
11837 inPre: false,
11838 inVPre: false,
11839 onWarn: options.onWarn
11840 };
11841}
11842function parseChildren(context, mode, ancestors) {
11843 const parent = last(ancestors);
11844 const ns = parent ? parent.ns : 0 /* HTML */;
11845 const nodes = [];
11846 while (!isEnd(context, mode, ancestors)) {
11847 const s = context.source;
11848 let node = undefined;
11849 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
11850 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
11851 // '{{'
11852 node = parseInterpolation(context, mode);
11853 }
11854 else if (mode === 0 /* DATA */ && s[0] === '<') {
11855 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
11856 if (s.length === 1) {
11857 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
11858 }
11859 else if (s[1] === '!') {
11860 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
11861 if (startsWith(s, '<!--')) {
11862 node = parseComment(context);
11863 }
11864 else if (startsWith(s, '<!DOCTYPE')) {
11865 // Ignore DOCTYPE by a limitation.
11866 node = parseBogusComment(context);
11867 }
11868 else if (startsWith(s, '<![CDATA[')) {
11869 if (ns !== 0 /* HTML */) {
11870 node = parseCDATA(context, ancestors);
11871 }
11872 else {
11873 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
11874 node = parseBogusComment(context);
11875 }
11876 }
11877 else {
11878 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
11879 node = parseBogusComment(context);
11880 }
11881 }
11882 else if (s[1] === '/') {
11883 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
11884 if (s.length === 2) {
11885 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
11886 }
11887 else if (s[2] === '>') {
11888 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
11889 advanceBy(context, 3);
11890 continue;
11891 }
11892 else if (/[a-z]/i.test(s[2])) {
11893 emitError(context, 23 /* X_INVALID_END_TAG */);
11894 parseTag(context, 1 /* End */, parent);
11895 continue;
11896 }
11897 else {
11898 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
11899 node = parseBogusComment(context);
11900 }
11901 }
11902 else if (/[a-z]/i.test(s[1])) {
11903 node = parseElement(context, ancestors);
11904 }
11905 else if (s[1] === '?') {
11906 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
11907 node = parseBogusComment(context);
11908 }
11909 else {
11910 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
11911 }
11912 }
11913 }
11914 if (!node) {
11915 node = parseText(context, mode);
11916 }
11917 if (isArray(node)) {
11918 for (let i = 0; i < node.length; i++) {
11919 pushNode(nodes, node[i]);
11920 }
11921 }
11922 else {
11923 pushNode(nodes, node);
11924 }
11925 }
11926 // Whitespace handling strategy like v2
11927 let removedWhitespace = false;
11928 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
11929 const shouldCondense = context.options.whitespace !== 'preserve';
11930 for (let i = 0; i < nodes.length; i++) {
11931 const node = nodes[i];
11932 if (!context.inPre && node.type === 2 /* TEXT */) {
11933 if (!/[^\t\r\n\f ]/.test(node.content)) {
11934 const prev = nodes[i - 1];
11935 const next = nodes[i + 1];
11936 // Remove if:
11937 // - the whitespace is the first or last node, or:
11938 // - (condense mode) the whitespace is adjacent to a comment, or:
11939 // - (condense mode) the whitespace is between two elements AND contains newline
11940 if (!prev ||
11941 !next ||
11942 (shouldCondense &&
11943 (prev.type === 3 /* COMMENT */ ||
11944 next.type === 3 /* COMMENT */ ||
11945 (prev.type === 1 /* ELEMENT */ &&
11946 next.type === 1 /* ELEMENT */ &&
11947 /[\r\n]/.test(node.content))))) {
11948 removedWhitespace = true;
11949 nodes[i] = null;
11950 }
11951 else {
11952 // Otherwise, the whitespace is condensed into a single space
11953 node.content = ' ';
11954 }
11955 }
11956 else if (shouldCondense) {
11957 // in condense mode, consecutive whitespaces in text are condensed
11958 // down to a single space.
11959 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11960 }
11961 }
11962 // Remove comment nodes if desired by configuration.
11963 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
11964 removedWhitespace = true;
11965 nodes[i] = null;
11966 }
11967 }
11968 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
11969 // remove leading newline per html spec
11970 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
11971 const first = nodes[0];
11972 if (first && first.type === 2 /* TEXT */) {
11973 first.content = first.content.replace(/^\r?\n/, '');
11974 }
11975 }
11976 }
11977 return removedWhitespace ? nodes.filter(Boolean) : nodes;
11978}
11979function pushNode(nodes, node) {
11980 if (node.type === 2 /* TEXT */) {
11981 const prev = last(nodes);
11982 // Merge if both this and the previous node are text and those are
11983 // consecutive. This happens for cases like "a < b".
11984 if (prev &&
11985 prev.type === 2 /* TEXT */ &&
11986 prev.loc.end.offset === node.loc.start.offset) {
11987 prev.content += node.content;
11988 prev.loc.end = node.loc.end;
11989 prev.loc.source += node.loc.source;
11990 return;
11991 }
11992 }
11993 nodes.push(node);
11994}
11995function parseCDATA(context, ancestors) {
11996 advanceBy(context, 9);
11997 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
11998 if (context.source.length === 0) {
11999 emitError(context, 6 /* EOF_IN_CDATA */);
12000 }
12001 else {
12002 advanceBy(context, 3);
12003 }
12004 return nodes;
12005}
12006function parseComment(context) {
12007 const start = getCursor(context);
12008 let content;
12009 // Regular comment.
12010 const match = /--(\!)?>/.exec(context.source);
12011 if (!match) {
12012 content = context.source.slice(4);
12013 advanceBy(context, context.source.length);
12014 emitError(context, 7 /* EOF_IN_COMMENT */);
12015 }
12016 else {
12017 if (match.index <= 3) {
12018 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
12019 }
12020 if (match[1]) {
12021 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
12022 }
12023 content = context.source.slice(4, match.index);
12024 // Advancing with reporting nested comments.
12025 const s = context.source.slice(0, match.index);
12026 let prevIndex = 1, nestedIndex = 0;
12027 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
12028 advanceBy(context, nestedIndex - prevIndex + 1);
12029 if (nestedIndex + 4 < s.length) {
12030 emitError(context, 16 /* NESTED_COMMENT */);
12031 }
12032 prevIndex = nestedIndex + 1;
12033 }
12034 advanceBy(context, match.index + match[0].length - prevIndex + 1);
12035 }
12036 return {
12037 type: 3 /* COMMENT */,
12038 content,
12039 loc: getSelection(context, start)
12040 };
12041}
12042function parseBogusComment(context) {
12043 const start = getCursor(context);
12044 const contentStart = context.source[1] === '?' ? 1 : 2;
12045 let content;
12046 const closeIndex = context.source.indexOf('>');
12047 if (closeIndex === -1) {
12048 content = context.source.slice(contentStart);
12049 advanceBy(context, context.source.length);
12050 }
12051 else {
12052 content = context.source.slice(contentStart, closeIndex);
12053 advanceBy(context, closeIndex + 1);
12054 }
12055 return {
12056 type: 3 /* COMMENT */,
12057 content,
12058 loc: getSelection(context, start)
12059 };
12060}
12061function parseElement(context, ancestors) {
12062 // Start tag.
12063 const wasInPre = context.inPre;
12064 const wasInVPre = context.inVPre;
12065 const parent = last(ancestors);
12066 const element = parseTag(context, 0 /* Start */, parent);
12067 const isPreBoundary = context.inPre && !wasInPre;
12068 const isVPreBoundary = context.inVPre && !wasInVPre;
12069 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
12070 // #4030 self-closing <pre> tag
12071 if (isPreBoundary) {
12072 context.inPre = false;
12073 }
12074 if (isVPreBoundary) {
12075 context.inVPre = false;
12076 }
12077 return element;
12078 }
12079 // Children.
12080 ancestors.push(element);
12081 const mode = context.options.getTextMode(element, parent);
12082 const children = parseChildren(context, mode, ancestors);
12083 ancestors.pop();
12084 element.children = children;
12085 // End tag.
12086 if (startsWithEndTagOpen(context.source, element.tag)) {
12087 parseTag(context, 1 /* End */, parent);
12088 }
12089 else {
12090 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
12091 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
12092 const first = children[0];
12093 if (first && startsWith(first.loc.source, '<!--')) {
12094 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
12095 }
12096 }
12097 }
12098 element.loc = getSelection(context, element.loc.start);
12099 if (isPreBoundary) {
12100 context.inPre = false;
12101 }
12102 if (isVPreBoundary) {
12103 context.inVPre = false;
12104 }
12105 return element;
12106}
12107const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
12108function parseTag(context, type, parent) {
12109 // Tag open.
12110 const start = getCursor(context);
12111 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
12112 const tag = match[1];
12113 const ns = context.options.getNamespace(tag, parent);
12114 advanceBy(context, match[0].length);
12115 advanceSpaces(context);
12116 // save current state in case we need to re-parse attributes with v-pre
12117 const cursor = getCursor(context);
12118 const currentSource = context.source;
12119 // check <pre> tag
12120 if (context.options.isPreTag(tag)) {
12121 context.inPre = true;
12122 }
12123 // Attributes.
12124 let props = parseAttributes(context, type);
12125 // check v-pre
12126 if (type === 0 /* Start */ &&
12127 !context.inVPre &&
12128 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
12129 context.inVPre = true;
12130 // reset context
12131 extend(context, cursor);
12132 context.source = currentSource;
12133 // re-parse attrs and filter out v-pre itself
12134 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
12135 }
12136 // Tag close.
12137 let isSelfClosing = false;
12138 if (context.source.length === 0) {
12139 emitError(context, 9 /* EOF_IN_TAG */);
12140 }
12141 else {
12142 isSelfClosing = startsWith(context.source, '/>');
12143 if (type === 1 /* End */ && isSelfClosing) {
12144 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
12145 }
12146 advanceBy(context, isSelfClosing ? 2 : 1);
12147 }
12148 if (type === 1 /* End */) {
12149 return;
12150 }
12151 let tagType = 0 /* ELEMENT */;
12152 if (!context.inVPre) {
12153 if (tag === 'slot') {
12154 tagType = 2 /* SLOT */;
12155 }
12156 else if (tag === 'template') {
12157 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
12158 tagType = 3 /* TEMPLATE */;
12159 }
12160 }
12161 else if (isComponent(tag, props, context)) {
12162 tagType = 1 /* COMPONENT */;
12163 }
12164 }
12165 return {
12166 type: 1 /* ELEMENT */,
12167 ns,
12168 tag,
12169 tagType,
12170 props,
12171 isSelfClosing,
12172 children: [],
12173 loc: getSelection(context, start),
12174 codegenNode: undefined // to be created during transform phase
12175 };
12176}
12177function isComponent(tag, props, context) {
12178 const options = context.options;
12179 if (options.isCustomElement(tag)) {
12180 return false;
12181 }
12182 if (tag === 'component' ||
12183 /^[A-Z]/.test(tag) ||
12184 isCoreComponent(tag) ||
12185 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
12186 (options.isNativeTag && !options.isNativeTag(tag))) {
12187 return true;
12188 }
12189 // at this point the tag should be a native tag, but check for potential "is"
12190 // casting
12191 for (let i = 0; i < props.length; i++) {
12192 const p = props[i];
12193 if (p.type === 6 /* ATTRIBUTE */) {
12194 if (p.name === 'is' && p.value) {
12195 if (p.value.content.startsWith('vue:')) {
12196 return true;
12197 }
12198 }
12199 }
12200 else {
12201 // directive
12202 // v-is (TODO Deprecate)
12203 if (p.name === 'is') {
12204 return true;
12205 }
12206 else if (
12207 // :is on plain element - only treat as component in compat mode
12208 p.name === 'bind' &&
12209 isStaticArgOf(p.arg, 'is') &&
12210 false &&
12211 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
12212 return true;
12213 }
12214 }
12215 }
12216}
12217function parseAttributes(context, type) {
12218 const props = [];
12219 const attributeNames = new Set();
12220 while (context.source.length > 0 &&
12221 !startsWith(context.source, '>') &&
12222 !startsWith(context.source, '/>')) {
12223 if (startsWith(context.source, '/')) {
12224 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
12225 advanceBy(context, 1);
12226 advanceSpaces(context);
12227 continue;
12228 }
12229 if (type === 1 /* End */) {
12230 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
12231 }
12232 const attr = parseAttribute(context, attributeNames);
12233 // Trim whitespace between class
12234 // https://github.com/vuejs/core/issues/4251
12235 if (attr.type === 6 /* ATTRIBUTE */ &&
12236 attr.value &&
12237 attr.name === 'class') {
12238 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
12239 }
12240 if (type === 0 /* Start */) {
12241 props.push(attr);
12242 }
12243 if (/^[^\t\r\n\f />]/.test(context.source)) {
12244 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
12245 }
12246 advanceSpaces(context);
12247 }
12248 return props;
12249}
12250function parseAttribute(context, nameSet) {
12251 // Name.
12252 const start = getCursor(context);
12253 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
12254 const name = match[0];
12255 if (nameSet.has(name)) {
12256 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
12257 }
12258 nameSet.add(name);
12259 if (name[0] === '=') {
12260 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
12261 }
12262 {
12263 const pattern = /["'<]/g;
12264 let m;
12265 while ((m = pattern.exec(name))) {
12266 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
12267 }
12268 }
12269 advanceBy(context, name.length);
12270 // Value
12271 let value = undefined;
12272 if (/^[\t\r\n\f ]*=/.test(context.source)) {
12273 advanceSpaces(context);
12274 advanceBy(context, 1);
12275 advanceSpaces(context);
12276 value = parseAttributeValue(context);
12277 if (!value) {
12278 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
12279 }
12280 }
12281 const loc = getSelection(context, start);
12282 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
12283 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
12284 let isPropShorthand = startsWith(name, '.');
12285 let dirName = match[1] ||
12286 (isPropShorthand || startsWith(name, ':')
12287 ? 'bind'
12288 : startsWith(name, '@')
12289 ? 'on'
12290 : 'slot');
12291 let arg;
12292 if (match[2]) {
12293 const isSlot = dirName === 'slot';
12294 const startOffset = name.lastIndexOf(match[2]);
12295 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
12296 let content = match[2];
12297 let isStatic = true;
12298 if (content.startsWith('[')) {
12299 isStatic = false;
12300 if (!content.endsWith(']')) {
12301 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
12302 content = content.slice(1);
12303 }
12304 else {
12305 content = content.slice(1, content.length - 1);
12306 }
12307 }
12308 else if (isSlot) {
12309 // #1241 special case for v-slot: vuetify relies extensively on slot
12310 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
12311 // supports such usage so we are keeping it consistent with 2.x.
12312 content += match[3] || '';
12313 }
12314 arg = {
12315 type: 4 /* SIMPLE_EXPRESSION */,
12316 content,
12317 isStatic,
12318 constType: isStatic
12319 ? 3 /* CAN_STRINGIFY */
12320 : 0 /* NOT_CONSTANT */,
12321 loc
12322 };
12323 }
12324 if (value && value.isQuoted) {
12325 const valueLoc = value.loc;
12326 valueLoc.start.offset++;
12327 valueLoc.start.column++;
12328 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
12329 valueLoc.source = valueLoc.source.slice(1, -1);
12330 }
12331 const modifiers = match[3] ? match[3].slice(1).split('.') : [];
12332 if (isPropShorthand)
12333 modifiers.push('prop');
12334 return {
12335 type: 7 /* DIRECTIVE */,
12336 name: dirName,
12337 exp: value && {
12338 type: 4 /* SIMPLE_EXPRESSION */,
12339 content: value.content,
12340 isStatic: false,
12341 // Treat as non-constant by default. This can be potentially set to
12342 // other values by `transformExpression` to make it eligible for hoisting.
12343 constType: 0 /* NOT_CONSTANT */,
12344 loc: value.loc
12345 },
12346 arg,
12347 modifiers,
12348 loc
12349 };
12350 }
12351 // missing directive name or illegal directive name
12352 if (!context.inVPre && startsWith(name, 'v-')) {
12353 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);
12354 }
12355 return {
12356 type: 6 /* ATTRIBUTE */,
12357 name,
12358 value: value && {
12359 type: 2 /* TEXT */,
12360 content: value.content,
12361 loc: value.loc
12362 },
12363 loc
12364 };
12365}
12366function parseAttributeValue(context) {
12367 const start = getCursor(context);
12368 let content;
12369 const quote = context.source[0];
12370 const isQuoted = quote === `"` || quote === `'`;
12371 if (isQuoted) {
12372 // Quoted value.
12373 advanceBy(context, 1);
12374 const endIndex = context.source.indexOf(quote);
12375 if (endIndex === -1) {
12376 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
12377 }
12378 else {
12379 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
12380 advanceBy(context, 1);
12381 }
12382 }
12383 else {
12384 // Unquoted
12385 const match = /^[^\t\r\n\f >]+/.exec(context.source);
12386 if (!match) {
12387 return undefined;
12388 }
12389 const unexpectedChars = /["'<=`]/g;
12390 let m;
12391 while ((m = unexpectedChars.exec(match[0]))) {
12392 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
12393 }
12394 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
12395 }
12396 return { content, isQuoted, loc: getSelection(context, start) };
12397}
12398function parseInterpolation(context, mode) {
12399 const [open, close] = context.options.delimiters;
12400 const closeIndex = context.source.indexOf(close, open.length);
12401 if (closeIndex === -1) {
12402 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
12403 return undefined;
12404 }
12405 const start = getCursor(context);
12406 advanceBy(context, open.length);
12407 const innerStart = getCursor(context);
12408 const innerEnd = getCursor(context);
12409 const rawContentLength = closeIndex - open.length;
12410 const rawContent = context.source.slice(0, rawContentLength);
12411 const preTrimContent = parseTextData(context, rawContentLength, mode);
12412 const content = preTrimContent.trim();
12413 const startOffset = preTrimContent.indexOf(content);
12414 if (startOffset > 0) {
12415 advancePositionWithMutation(innerStart, rawContent, startOffset);
12416 }
12417 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
12418 advancePositionWithMutation(innerEnd, rawContent, endOffset);
12419 advanceBy(context, close.length);
12420 return {
12421 type: 5 /* INTERPOLATION */,
12422 content: {
12423 type: 4 /* SIMPLE_EXPRESSION */,
12424 isStatic: false,
12425 // Set `isConstant` to false by default and will decide in transformExpression
12426 constType: 0 /* NOT_CONSTANT */,
12427 content,
12428 loc: getSelection(context, innerStart, innerEnd)
12429 },
12430 loc: getSelection(context, start)
12431 };
12432}
12433function parseText(context, mode) {
12434 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
12435 let endIndex = context.source.length;
12436 for (let i = 0; i < endTokens.length; i++) {
12437 const index = context.source.indexOf(endTokens[i], 1);
12438 if (index !== -1 && endIndex > index) {
12439 endIndex = index;
12440 }
12441 }
12442 const start = getCursor(context);
12443 const content = parseTextData(context, endIndex, mode);
12444 return {
12445 type: 2 /* TEXT */,
12446 content,
12447 loc: getSelection(context, start)
12448 };
12449}
12450/**
12451 * Get text data with a given length from the current location.
12452 * This translates HTML entities in the text data.
12453 */
12454function parseTextData(context, length, mode) {
12455 const rawText = context.source.slice(0, length);
12456 advanceBy(context, length);
12457 if (mode === 2 /* RAWTEXT */ ||
12458 mode === 3 /* CDATA */ ||
12459 !rawText.includes('&')) {
12460 return rawText;
12461 }
12462 else {
12463 // DATA or RCDATA containing "&"". Entity decoding required.
12464 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
12465 }
12466}
12467function getCursor(context) {
12468 const { column, line, offset } = context;
12469 return { column, line, offset };
12470}
12471function getSelection(context, start, end) {
12472 end = end || getCursor(context);
12473 return {
12474 start,
12475 end,
12476 source: context.originalSource.slice(start.offset, end.offset)
12477 };
12478}
12479function last(xs) {
12480 return xs[xs.length - 1];
12481}
12482function startsWith(source, searchString) {
12483 return source.startsWith(searchString);
12484}
12485function advanceBy(context, numberOfCharacters) {
12486 const { source } = context;
12487 advancePositionWithMutation(context, source, numberOfCharacters);
12488 context.source = source.slice(numberOfCharacters);
12489}
12490function advanceSpaces(context) {
12491 const match = /^[\t\r\n\f ]+/.exec(context.source);
12492 if (match) {
12493 advanceBy(context, match[0].length);
12494 }
12495}
12496function getNewPosition(context, start, numberOfCharacters) {
12497 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
12498}
12499function emitError(context, code, offset, loc = getCursor(context)) {
12500 if (offset) {
12501 loc.offset += offset;
12502 loc.column += offset;
12503 }
12504 context.options.onError(createCompilerError(code, {
12505 start: loc,
12506 end: loc,
12507 source: ''
12508 }));
12509}
12510function isEnd(context, mode, ancestors) {
12511 const s = context.source;
12512 switch (mode) {
12513 case 0 /* DATA */:
12514 if (startsWith(s, '</')) {
12515 // TODO: probably bad performance
12516 for (let i = ancestors.length - 1; i >= 0; --i) {
12517 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
12518 return true;
12519 }
12520 }
12521 }
12522 break;
12523 case 1 /* RCDATA */:
12524 case 2 /* RAWTEXT */: {
12525 const parent = last(ancestors);
12526 if (parent && startsWithEndTagOpen(s, parent.tag)) {
12527 return true;
12528 }
12529 break;
12530 }
12531 case 3 /* CDATA */:
12532 if (startsWith(s, ']]>')) {
12533 return true;
12534 }
12535 break;
12536 }
12537 return !s;
12538}
12539function startsWithEndTagOpen(source, tag) {
12540 return (startsWith(source, '</') &&
12541 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
12542 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
12543}
12544
12545function hoistStatic(root, context) {
12546 walk(root, context,
12547 // Root node is unfortunately non-hoistable due to potential parent
12548 // fallthrough attributes.
12549 isSingleElementRoot(root, root.children[0]));
12550}
12551function isSingleElementRoot(root, child) {
12552 const { children } = root;
12553 return (children.length === 1 &&
12554 child.type === 1 /* ELEMENT */ &&
12555 !isSlotOutlet(child));
12556}
12557function walk(node, context, doNotHoistNode = false) {
12558 const { children } = node;
12559 const originalCount = children.length;
12560 let hoistedCount = 0;
12561 for (let i = 0; i < children.length; i++) {
12562 const child = children[i];
12563 // only plain elements & text calls are eligible for hoisting.
12564 if (child.type === 1 /* ELEMENT */ &&
12565 child.tagType === 0 /* ELEMENT */) {
12566 const constantType = doNotHoistNode
12567 ? 0 /* NOT_CONSTANT */
12568 : getConstantType(child, context);
12569 if (constantType > 0 /* NOT_CONSTANT */) {
12570 if (constantType >= 2 /* CAN_HOIST */) {
12571 child.codegenNode.patchFlag =
12572 -1 /* HOISTED */ + (` /* HOISTED */` );
12573 child.codegenNode = context.hoist(child.codegenNode);
12574 hoistedCount++;
12575 continue;
12576 }
12577 }
12578 else {
12579 // node may contain dynamic children, but its props may be eligible for
12580 // hoisting.
12581 const codegenNode = child.codegenNode;
12582 if (codegenNode.type === 13 /* VNODE_CALL */) {
12583 const flag = getPatchFlag(codegenNode);
12584 if ((!flag ||
12585 flag === 512 /* NEED_PATCH */ ||
12586 flag === 1 /* TEXT */) &&
12587 getGeneratedPropsConstantType(child, context) >=
12588 2 /* CAN_HOIST */) {
12589 const props = getNodeProps(child);
12590 if (props) {
12591 codegenNode.props = context.hoist(props);
12592 }
12593 }
12594 if (codegenNode.dynamicProps) {
12595 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
12596 }
12597 }
12598 }
12599 }
12600 else if (child.type === 12 /* TEXT_CALL */ &&
12601 getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
12602 child.codegenNode = context.hoist(child.codegenNode);
12603 hoistedCount++;
12604 }
12605 // walk further
12606 if (child.type === 1 /* ELEMENT */) {
12607 const isComponent = child.tagType === 1 /* COMPONENT */;
12608 if (isComponent) {
12609 context.scopes.vSlot++;
12610 }
12611 walk(child, context);
12612 if (isComponent) {
12613 context.scopes.vSlot--;
12614 }
12615 }
12616 else if (child.type === 11 /* FOR */) {
12617 // Do not hoist v-for single child because it has to be a block
12618 walk(child, context, child.children.length === 1);
12619 }
12620 else if (child.type === 9 /* IF */) {
12621 for (let i = 0; i < child.branches.length; i++) {
12622 // Do not hoist v-if single child because it has to be a block
12623 walk(child.branches[i], context, child.branches[i].children.length === 1);
12624 }
12625 }
12626 }
12627 if (hoistedCount && context.transformHoist) {
12628 context.transformHoist(children, context, node);
12629 }
12630 // all children were hoisted - the entire children array is hoistable.
12631 if (hoistedCount &&
12632 hoistedCount === originalCount &&
12633 node.type === 1 /* ELEMENT */ &&
12634 node.tagType === 0 /* ELEMENT */ &&
12635 node.codegenNode &&
12636 node.codegenNode.type === 13 /* VNODE_CALL */ &&
12637 isArray(node.codegenNode.children)) {
12638 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
12639 }
12640}
12641function getConstantType(node, context) {
12642 const { constantCache } = context;
12643 switch (node.type) {
12644 case 1 /* ELEMENT */:
12645 if (node.tagType !== 0 /* ELEMENT */) {
12646 return 0 /* NOT_CONSTANT */;
12647 }
12648 const cached = constantCache.get(node);
12649 if (cached !== undefined) {
12650 return cached;
12651 }
12652 const codegenNode = node.codegenNode;
12653 if (codegenNode.type !== 13 /* VNODE_CALL */) {
12654 return 0 /* NOT_CONSTANT */;
12655 }
12656 if (codegenNode.isBlock &&
12657 node.tag !== 'svg' &&
12658 node.tag !== 'foreignObject') {
12659 return 0 /* NOT_CONSTANT */;
12660 }
12661 const flag = getPatchFlag(codegenNode);
12662 if (!flag) {
12663 let returnType = 3 /* CAN_STRINGIFY */;
12664 // Element itself has no patch flag. However we still need to check:
12665 // 1. Even for a node with no patch flag, it is possible for it to contain
12666 // non-hoistable expressions that refers to scope variables, e.g. compiler
12667 // injected keys or cached event handlers. Therefore we need to always
12668 // check the codegenNode's props to be sure.
12669 const generatedPropsType = getGeneratedPropsConstantType(node, context);
12670 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
12671 constantCache.set(node, 0 /* NOT_CONSTANT */);
12672 return 0 /* NOT_CONSTANT */;
12673 }
12674 if (generatedPropsType < returnType) {
12675 returnType = generatedPropsType;
12676 }
12677 // 2. its children.
12678 for (let i = 0; i < node.children.length; i++) {
12679 const childType = getConstantType(node.children[i], context);
12680 if (childType === 0 /* NOT_CONSTANT */) {
12681 constantCache.set(node, 0 /* NOT_CONSTANT */);
12682 return 0 /* NOT_CONSTANT */;
12683 }
12684 if (childType < returnType) {
12685 returnType = childType;
12686 }
12687 }
12688 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
12689 // type, check if any of the props can cause the type to be lowered
12690 // we can skip can_patch because it's guaranteed by the absence of a
12691 // patchFlag.
12692 if (returnType > 1 /* CAN_SKIP_PATCH */) {
12693 for (let i = 0; i < node.props.length; i++) {
12694 const p = node.props[i];
12695 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
12696 const expType = getConstantType(p.exp, context);
12697 if (expType === 0 /* NOT_CONSTANT */) {
12698 constantCache.set(node, 0 /* NOT_CONSTANT */);
12699 return 0 /* NOT_CONSTANT */;
12700 }
12701 if (expType < returnType) {
12702 returnType = expType;
12703 }
12704 }
12705 }
12706 }
12707 // only svg/foreignObject could be block here, however if they are
12708 // static then they don't need to be blocks since there will be no
12709 // nested updates.
12710 if (codegenNode.isBlock) {
12711 // except set custom directives.
12712 for (let i = 0; i < node.props.length; i++) {
12713 const p = node.props[i];
12714 if (p.type === 7 /* DIRECTIVE */) {
12715 constantCache.set(node, 0 /* NOT_CONSTANT */);
12716 return 0 /* NOT_CONSTANT */;
12717 }
12718 }
12719 context.removeHelper(OPEN_BLOCK);
12720 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
12721 codegenNode.isBlock = false;
12722 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
12723 }
12724 constantCache.set(node, returnType);
12725 return returnType;
12726 }
12727 else {
12728 constantCache.set(node, 0 /* NOT_CONSTANT */);
12729 return 0 /* NOT_CONSTANT */;
12730 }
12731 case 2 /* TEXT */:
12732 case 3 /* COMMENT */:
12733 return 3 /* CAN_STRINGIFY */;
12734 case 9 /* IF */:
12735 case 11 /* FOR */:
12736 case 10 /* IF_BRANCH */:
12737 return 0 /* NOT_CONSTANT */;
12738 case 5 /* INTERPOLATION */:
12739 case 12 /* TEXT_CALL */:
12740 return getConstantType(node.content, context);
12741 case 4 /* SIMPLE_EXPRESSION */:
12742 return node.constType;
12743 case 8 /* COMPOUND_EXPRESSION */:
12744 let returnType = 3 /* CAN_STRINGIFY */;
12745 for (let i = 0; i < node.children.length; i++) {
12746 const child = node.children[i];
12747 if (isString(child) || isSymbol(child)) {
12748 continue;
12749 }
12750 const childType = getConstantType(child, context);
12751 if (childType === 0 /* NOT_CONSTANT */) {
12752 return 0 /* NOT_CONSTANT */;
12753 }
12754 else if (childType < returnType) {
12755 returnType = childType;
12756 }
12757 }
12758 return returnType;
12759 default:
12760 return 0 /* NOT_CONSTANT */;
12761 }
12762}
12763const allowHoistedHelperSet = new Set([
12764 NORMALIZE_CLASS,
12765 NORMALIZE_STYLE,
12766 NORMALIZE_PROPS,
12767 GUARD_REACTIVE_PROPS
12768]);
12769function getConstantTypeOfHelperCall(value, context) {
12770 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
12771 !isString(value.callee) &&
12772 allowHoistedHelperSet.has(value.callee)) {
12773 const arg = value.arguments[0];
12774 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
12775 return getConstantType(arg, context);
12776 }
12777 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
12778 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
12779 return getConstantTypeOfHelperCall(arg, context);
12780 }
12781 }
12782 return 0 /* NOT_CONSTANT */;
12783}
12784function getGeneratedPropsConstantType(node, context) {
12785 let returnType = 3 /* CAN_STRINGIFY */;
12786 const props = getNodeProps(node);
12787 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
12788 const { properties } = props;
12789 for (let i = 0; i < properties.length; i++) {
12790 const { key, value } = properties[i];
12791 const keyType = getConstantType(key, context);
12792 if (keyType === 0 /* NOT_CONSTANT */) {
12793 return keyType;
12794 }
12795 if (keyType < returnType) {
12796 returnType = keyType;
12797 }
12798 let valueType;
12799 if (value.type === 4 /* SIMPLE_EXPRESSION */) {
12800 valueType = getConstantType(value, context);
12801 }
12802 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12803 // some helper calls can be hoisted,
12804 // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12805 // in this case we need to respect the ConstantType of the helper's arguments
12806 valueType = getConstantTypeOfHelperCall(value, context);
12807 }
12808 else {
12809 valueType = 0 /* NOT_CONSTANT */;
12810 }
12811 if (valueType === 0 /* NOT_CONSTANT */) {
12812 return valueType;
12813 }
12814 if (valueType < returnType) {
12815 returnType = valueType;
12816 }
12817 }
12818 }
12819 return returnType;
12820}
12821function getNodeProps(node) {
12822 const codegenNode = node.codegenNode;
12823 if (codegenNode.type === 13 /* VNODE_CALL */) {
12824 return codegenNode.props;
12825 }
12826}
12827function getPatchFlag(node) {
12828 const flag = node.patchFlag;
12829 return flag ? parseInt(flag, 10) : undefined;
12830}
12831
12832function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
12833 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
12834 const context = {
12835 // options
12836 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
12837 prefixIdentifiers,
12838 hoistStatic,
12839 cacheHandlers,
12840 nodeTransforms,
12841 directiveTransforms,
12842 transformHoist,
12843 isBuiltInComponent,
12844 isCustomElement,
12845 expressionPlugins,
12846 scopeId,
12847 slotted,
12848 ssr,
12849 inSSR,
12850 ssrCssVars,
12851 bindingMetadata,
12852 inline,
12853 isTS,
12854 onError,
12855 onWarn,
12856 compatConfig,
12857 // state
12858 root,
12859 helpers: new Map(),
12860 components: new Set(),
12861 directives: new Set(),
12862 hoists: [],
12863 imports: [],
12864 constantCache: new Map(),
12865 temps: 0,
12866 cached: 0,
12867 identifiers: Object.create(null),
12868 scopes: {
12869 vFor: 0,
12870 vSlot: 0,
12871 vPre: 0,
12872 vOnce: 0
12873 },
12874 parent: null,
12875 currentNode: root,
12876 childIndex: 0,
12877 inVOnce: false,
12878 // methods
12879 helper(name) {
12880 const count = context.helpers.get(name) || 0;
12881 context.helpers.set(name, count + 1);
12882 return name;
12883 },
12884 removeHelper(name) {
12885 const count = context.helpers.get(name);
12886 if (count) {
12887 const currentCount = count - 1;
12888 if (!currentCount) {
12889 context.helpers.delete(name);
12890 }
12891 else {
12892 context.helpers.set(name, currentCount);
12893 }
12894 }
12895 },
12896 helperString(name) {
12897 return `_${helperNameMap[context.helper(name)]}`;
12898 },
12899 replaceNode(node) {
12900 /* istanbul ignore if */
12901 {
12902 if (!context.currentNode) {
12903 throw new Error(`Node being replaced is already removed.`);
12904 }
12905 if (!context.parent) {
12906 throw new Error(`Cannot replace root node.`);
12907 }
12908 }
12909 context.parent.children[context.childIndex] = context.currentNode = node;
12910 },
12911 removeNode(node) {
12912 if (!context.parent) {
12913 throw new Error(`Cannot remove root node.`);
12914 }
12915 const list = context.parent.children;
12916 const removalIndex = node
12917 ? list.indexOf(node)
12918 : context.currentNode
12919 ? context.childIndex
12920 : -1;
12921 /* istanbul ignore if */
12922 if (removalIndex < 0) {
12923 throw new Error(`node being removed is not a child of current parent`);
12924 }
12925 if (!node || node === context.currentNode) {
12926 // current node removed
12927 context.currentNode = null;
12928 context.onNodeRemoved();
12929 }
12930 else {
12931 // sibling node removed
12932 if (context.childIndex > removalIndex) {
12933 context.childIndex--;
12934 context.onNodeRemoved();
12935 }
12936 }
12937 context.parent.children.splice(removalIndex, 1);
12938 },
12939 onNodeRemoved: () => { },
12940 addIdentifiers(exp) {
12941 },
12942 removeIdentifiers(exp) {
12943 },
12944 hoist(exp) {
12945 if (isString(exp))
12946 exp = createSimpleExpression(exp);
12947 context.hoists.push(exp);
12948 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
12949 identifier.hoisted = exp;
12950 return identifier;
12951 },
12952 cache(exp, isVNode = false) {
12953 return createCacheExpression(context.cached++, exp, isVNode);
12954 }
12955 };
12956 return context;
12957}
12958function transform(root, options) {
12959 const context = createTransformContext(root, options);
12960 traverseNode(root, context);
12961 if (options.hoistStatic) {
12962 hoistStatic(root, context);
12963 }
12964 if (!options.ssr) {
12965 createRootCodegen(root, context);
12966 }
12967 // finalize meta information
12968 root.helpers = [...context.helpers.keys()];
12969 root.components = [...context.components];
12970 root.directives = [...context.directives];
12971 root.imports = context.imports;
12972 root.hoists = context.hoists;
12973 root.temps = context.temps;
12974 root.cached = context.cached;
12975}
12976function createRootCodegen(root, context) {
12977 const { helper } = context;
12978 const { children } = root;
12979 if (children.length === 1) {
12980 const child = children[0];
12981 // if the single child is an element, turn it into a block.
12982 if (isSingleElementRoot(root, child) && child.codegenNode) {
12983 // single element root is never hoisted so codegenNode will never be
12984 // SimpleExpressionNode
12985 const codegenNode = child.codegenNode;
12986 if (codegenNode.type === 13 /* VNODE_CALL */) {
12987 makeBlock(codegenNode, context);
12988 }
12989 root.codegenNode = codegenNode;
12990 }
12991 else {
12992 // - single <slot/>, IfNode, ForNode: already blocks.
12993 // - single text node: always patched.
12994 // root codegen falls through via genNode()
12995 root.codegenNode = child;
12996 }
12997 }
12998 else if (children.length > 1) {
12999 // root has multiple nodes - return a fragment block.
13000 let patchFlag = 64 /* STABLE_FRAGMENT */;
13001 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
13002 // check if the fragment actually contains a single valid child with
13003 // the rest being comments
13004 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
13005 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
13006 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
13007 }
13008 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);
13009 }
13010 else ;
13011}
13012function traverseChildren(parent, context) {
13013 let i = 0;
13014 const nodeRemoved = () => {
13015 i--;
13016 };
13017 for (; i < parent.children.length; i++) {
13018 const child = parent.children[i];
13019 if (isString(child))
13020 continue;
13021 context.parent = parent;
13022 context.childIndex = i;
13023 context.onNodeRemoved = nodeRemoved;
13024 traverseNode(child, context);
13025 }
13026}
13027function traverseNode(node, context) {
13028 context.currentNode = node;
13029 // apply transform plugins
13030 const { nodeTransforms } = context;
13031 const exitFns = [];
13032 for (let i = 0; i < nodeTransforms.length; i++) {
13033 const onExit = nodeTransforms[i](node, context);
13034 if (onExit) {
13035 if (isArray(onExit)) {
13036 exitFns.push(...onExit);
13037 }
13038 else {
13039 exitFns.push(onExit);
13040 }
13041 }
13042 if (!context.currentNode) {
13043 // node was removed
13044 return;
13045 }
13046 else {
13047 // node may have been replaced
13048 node = context.currentNode;
13049 }
13050 }
13051 switch (node.type) {
13052 case 3 /* COMMENT */:
13053 if (!context.ssr) {
13054 // inject import for the Comment symbol, which is needed for creating
13055 // comment nodes with `createVNode`
13056 context.helper(CREATE_COMMENT);
13057 }
13058 break;
13059 case 5 /* INTERPOLATION */:
13060 // no need to traverse, but we need to inject toString helper
13061 if (!context.ssr) {
13062 context.helper(TO_DISPLAY_STRING);
13063 }
13064 break;
13065 // for container types, further traverse downwards
13066 case 9 /* IF */:
13067 for (let i = 0; i < node.branches.length; i++) {
13068 traverseNode(node.branches[i], context);
13069 }
13070 break;
13071 case 10 /* IF_BRANCH */:
13072 case 11 /* FOR */:
13073 case 1 /* ELEMENT */:
13074 case 0 /* ROOT */:
13075 traverseChildren(node, context);
13076 break;
13077 }
13078 // exit transforms
13079 context.currentNode = node;
13080 let i = exitFns.length;
13081 while (i--) {
13082 exitFns[i]();
13083 }
13084}
13085function createStructuralDirectiveTransform(name, fn) {
13086 const matches = isString(name)
13087 ? (n) => n === name
13088 : (n) => name.test(n);
13089 return (node, context) => {
13090 if (node.type === 1 /* ELEMENT */) {
13091 const { props } = node;
13092 // structural directive transforms are not concerned with slots
13093 // as they are handled separately in vSlot.ts
13094 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
13095 return;
13096 }
13097 const exitFns = [];
13098 for (let i = 0; i < props.length; i++) {
13099 const prop = props[i];
13100 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
13101 // structural directives are removed to avoid infinite recursion
13102 // also we remove them *before* applying so that it can further
13103 // traverse itself in case it moves the node around
13104 props.splice(i, 1);
13105 i--;
13106 const onExit = fn(node, prop, context);
13107 if (onExit)
13108 exitFns.push(onExit);
13109 }
13110 }
13111 return exitFns;
13112 }
13113 };
13114}
13115
13116const PURE_ANNOTATION = `/*#__PURE__*/`;
13117const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
13118function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {
13119 const context = {
13120 mode,
13121 prefixIdentifiers,
13122 sourceMap,
13123 filename,
13124 scopeId,
13125 optimizeImports,
13126 runtimeGlobalName,
13127 runtimeModuleName,
13128 ssrRuntimeModuleName,
13129 ssr,
13130 isTS,
13131 inSSR,
13132 source: ast.loc.source,
13133 code: ``,
13134 column: 1,
13135 line: 1,
13136 offset: 0,
13137 indentLevel: 0,
13138 pure: false,
13139 map: undefined,
13140 helper(key) {
13141 return `_${helperNameMap[key]}`;
13142 },
13143 push(code, node) {
13144 context.code += code;
13145 },
13146 indent() {
13147 newline(++context.indentLevel);
13148 },
13149 deindent(withoutNewLine = false) {
13150 if (withoutNewLine) {
13151 --context.indentLevel;
13152 }
13153 else {
13154 newline(--context.indentLevel);
13155 }
13156 },
13157 newline() {
13158 newline(context.indentLevel);
13159 }
13160 };
13161 function newline(n) {
13162 context.push('\n' + ` `.repeat(n));
13163 }
13164 return context;
13165}
13166function generate(ast, options = {}) {
13167 const context = createCodegenContext(ast, options);
13168 if (options.onContextCreated)
13169 options.onContextCreated(context);
13170 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
13171 const hasHelpers = ast.helpers.length > 0;
13172 const useWithBlock = !prefixIdentifiers && mode !== 'module';
13173 // preambles
13174 // in setup() inline mode, the preamble is generated in a sub context
13175 // and returned separately.
13176 const preambleContext = context;
13177 {
13178 genFunctionPreamble(ast, preambleContext);
13179 }
13180 // enter render function
13181 const functionName = ssr ? `ssrRender` : `render`;
13182 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
13183 const signature = args.join(', ');
13184 {
13185 push(`function ${functionName}(${signature}) {`);
13186 }
13187 indent();
13188 if (useWithBlock) {
13189 push(`with (_ctx) {`);
13190 indent();
13191 // function mode const declarations should be inside with block
13192 // also they should be renamed to avoid collision with user properties
13193 if (hasHelpers) {
13194 push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`);
13195 push(`\n`);
13196 newline();
13197 }
13198 }
13199 // generate asset resolution statements
13200 if (ast.components.length) {
13201 genAssets(ast.components, 'component', context);
13202 if (ast.directives.length || ast.temps > 0) {
13203 newline();
13204 }
13205 }
13206 if (ast.directives.length) {
13207 genAssets(ast.directives, 'directive', context);
13208 if (ast.temps > 0) {
13209 newline();
13210 }
13211 }
13212 if (ast.temps > 0) {
13213 push(`let `);
13214 for (let i = 0; i < ast.temps; i++) {
13215 push(`${i > 0 ? `, ` : ``}_temp${i}`);
13216 }
13217 }
13218 if (ast.components.length || ast.directives.length || ast.temps) {
13219 push(`\n`);
13220 newline();
13221 }
13222 // generate the VNode tree expression
13223 if (!ssr) {
13224 push(`return `);
13225 }
13226 if (ast.codegenNode) {
13227 genNode(ast.codegenNode, context);
13228 }
13229 else {
13230 push(`null`);
13231 }
13232 if (useWithBlock) {
13233 deindent();
13234 push(`}`);
13235 }
13236 deindent();
13237 push(`}`);
13238 return {
13239 ast,
13240 code: context.code,
13241 preamble: ``,
13242 // SourceMapGenerator does have toJSON() method but it's not in the types
13243 map: context.map ? context.map.toJSON() : undefined
13244 };
13245}
13246function genFunctionPreamble(ast, context) {
13247 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
13248 const VueBinding = runtimeGlobalName;
13249 // Generate const declaration for helpers
13250 // In prefix mode, we place the const declaration at top so it's done
13251 // only once; But if we not prefixing, we place the declaration inside the
13252 // with block so it doesn't incur the `in` check cost for every helper access.
13253 if (ast.helpers.length > 0) {
13254 {
13255 // "with" mode.
13256 // save Vue in a separate variable to avoid collision
13257 push(`const _Vue = ${VueBinding}\n`);
13258 // in "with" mode, helpers are declared inside the with block to avoid
13259 // has check cost, but hoists are lifted out of the function - we need
13260 // to provide the helper here.
13261 if (ast.hoists.length) {
13262 const staticHelpers = [
13263 CREATE_VNODE,
13264 CREATE_ELEMENT_VNODE,
13265 CREATE_COMMENT,
13266 CREATE_TEXT,
13267 CREATE_STATIC
13268 ]
13269 .filter(helper => ast.helpers.includes(helper))
13270 .map(aliasHelper)
13271 .join(', ');
13272 push(`const { ${staticHelpers} } = _Vue\n`);
13273 }
13274 }
13275 }
13276 genHoists(ast.hoists, context);
13277 newline();
13278 push(`return `);
13279}
13280function genAssets(assets, type, { helper, push, newline, isTS }) {
13281 const resolver = helper(type === 'component'
13282 ? RESOLVE_COMPONENT
13283 : RESOLVE_DIRECTIVE);
13284 for (let i = 0; i < assets.length; i++) {
13285 let id = assets[i];
13286 // potential component implicit self-reference inferred from SFC filename
13287 const maybeSelfReference = id.endsWith('__self');
13288 if (maybeSelfReference) {
13289 id = id.slice(0, -6);
13290 }
13291 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
13292 if (i < assets.length - 1) {
13293 newline();
13294 }
13295 }
13296}
13297function genHoists(hoists, context) {
13298 if (!hoists.length) {
13299 return;
13300 }
13301 context.pure = true;
13302 const { push, newline, helper, scopeId, mode } = context;
13303 newline();
13304 for (let i = 0; i < hoists.length; i++) {
13305 const exp = hoists[i];
13306 if (exp) {
13307 push(`const _hoisted_${i + 1} = ${``}`);
13308 genNode(exp, context);
13309 newline();
13310 }
13311 }
13312 context.pure = false;
13313}
13314function isText$1(n) {
13315 return (isString(n) ||
13316 n.type === 4 /* SIMPLE_EXPRESSION */ ||
13317 n.type === 2 /* TEXT */ ||
13318 n.type === 5 /* INTERPOLATION */ ||
13319 n.type === 8 /* COMPOUND_EXPRESSION */);
13320}
13321function genNodeListAsArray(nodes, context) {
13322 const multilines = nodes.length > 3 ||
13323 (nodes.some(n => isArray(n) || !isText$1(n)));
13324 context.push(`[`);
13325 multilines && context.indent();
13326 genNodeList(nodes, context, multilines);
13327 multilines && context.deindent();
13328 context.push(`]`);
13329}
13330function genNodeList(nodes, context, multilines = false, comma = true) {
13331 const { push, newline } = context;
13332 for (let i = 0; i < nodes.length; i++) {
13333 const node = nodes[i];
13334 if (isString(node)) {
13335 push(node);
13336 }
13337 else if (isArray(node)) {
13338 genNodeListAsArray(node, context);
13339 }
13340 else {
13341 genNode(node, context);
13342 }
13343 if (i < nodes.length - 1) {
13344 if (multilines) {
13345 comma && push(',');
13346 newline();
13347 }
13348 else {
13349 comma && push(', ');
13350 }
13351 }
13352 }
13353}
13354function genNode(node, context) {
13355 if (isString(node)) {
13356 context.push(node);
13357 return;
13358 }
13359 if (isSymbol(node)) {
13360 context.push(context.helper(node));
13361 return;
13362 }
13363 switch (node.type) {
13364 case 1 /* ELEMENT */:
13365 case 9 /* IF */:
13366 case 11 /* FOR */:
13367 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
13368 `Apply appropriate transforms first.`);
13369 genNode(node.codegenNode, context);
13370 break;
13371 case 2 /* TEXT */:
13372 genText(node, context);
13373 break;
13374 case 4 /* SIMPLE_EXPRESSION */:
13375 genExpression(node, context);
13376 break;
13377 case 5 /* INTERPOLATION */:
13378 genInterpolation(node, context);
13379 break;
13380 case 12 /* TEXT_CALL */:
13381 genNode(node.codegenNode, context);
13382 break;
13383 case 8 /* COMPOUND_EXPRESSION */:
13384 genCompoundExpression(node, context);
13385 break;
13386 case 3 /* COMMENT */:
13387 genComment(node, context);
13388 break;
13389 case 13 /* VNODE_CALL */:
13390 genVNodeCall(node, context);
13391 break;
13392 case 14 /* JS_CALL_EXPRESSION */:
13393 genCallExpression(node, context);
13394 break;
13395 case 15 /* JS_OBJECT_EXPRESSION */:
13396 genObjectExpression(node, context);
13397 break;
13398 case 17 /* JS_ARRAY_EXPRESSION */:
13399 genArrayExpression(node, context);
13400 break;
13401 case 18 /* JS_FUNCTION_EXPRESSION */:
13402 genFunctionExpression(node, context);
13403 break;
13404 case 19 /* JS_CONDITIONAL_EXPRESSION */:
13405 genConditionalExpression(node, context);
13406 break;
13407 case 20 /* JS_CACHE_EXPRESSION */:
13408 genCacheExpression(node, context);
13409 break;
13410 case 21 /* JS_BLOCK_STATEMENT */:
13411 genNodeList(node.body, context, true, false);
13412 break;
13413 // SSR only types
13414 case 22 /* JS_TEMPLATE_LITERAL */:
13415 break;
13416 case 23 /* JS_IF_STATEMENT */:
13417 break;
13418 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
13419 break;
13420 case 25 /* JS_SEQUENCE_EXPRESSION */:
13421 break;
13422 case 26 /* JS_RETURN_STATEMENT */:
13423 break;
13424 /* istanbul ignore next */
13425 case 10 /* IF_BRANCH */:
13426 // noop
13427 break;
13428 default:
13429 {
13430 assert(false, `unhandled codegen node type: ${node.type}`);
13431 // make sure we exhaust all possible types
13432 const exhaustiveCheck = node;
13433 return exhaustiveCheck;
13434 }
13435 }
13436}
13437function genText(node, context) {
13438 context.push(JSON.stringify(node.content), node);
13439}
13440function genExpression(node, context) {
13441 const { content, isStatic } = node;
13442 context.push(isStatic ? JSON.stringify(content) : content, node);
13443}
13444function genInterpolation(node, context) {
13445 const { push, helper, pure } = context;
13446 if (pure)
13447 push(PURE_ANNOTATION);
13448 push(`${helper(TO_DISPLAY_STRING)}(`);
13449 genNode(node.content, context);
13450 push(`)`);
13451}
13452function genCompoundExpression(node, context) {
13453 for (let i = 0; i < node.children.length; i++) {
13454 const child = node.children[i];
13455 if (isString(child)) {
13456 context.push(child);
13457 }
13458 else {
13459 genNode(child, context);
13460 }
13461 }
13462}
13463function genExpressionAsPropertyKey(node, context) {
13464 const { push } = context;
13465 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
13466 push(`[`);
13467 genCompoundExpression(node, context);
13468 push(`]`);
13469 }
13470 else if (node.isStatic) {
13471 // only quote keys if necessary
13472 const text = isSimpleIdentifier(node.content)
13473 ? node.content
13474 : JSON.stringify(node.content);
13475 push(text, node);
13476 }
13477 else {
13478 push(`[${node.content}]`, node);
13479 }
13480}
13481function genComment(node, context) {
13482 const { push, helper, pure } = context;
13483 if (pure) {
13484 push(PURE_ANNOTATION);
13485 }
13486 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
13487}
13488function genVNodeCall(node, context) {
13489 const { push, helper, pure } = context;
13490 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
13491 if (directives) {
13492 push(helper(WITH_DIRECTIVES) + `(`);
13493 }
13494 if (isBlock) {
13495 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
13496 }
13497 if (pure) {
13498 push(PURE_ANNOTATION);
13499 }
13500 const callHelper = isBlock
13501 ? getVNodeBlockHelper(context.inSSR, isComponent)
13502 : getVNodeHelper(context.inSSR, isComponent);
13503 push(helper(callHelper) + `(`, node);
13504 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
13505 push(`)`);
13506 if (isBlock) {
13507 push(`)`);
13508 }
13509 if (directives) {
13510 push(`, `);
13511 genNode(directives, context);
13512 push(`)`);
13513 }
13514}
13515function genNullableArgs(args) {
13516 let i = args.length;
13517 while (i--) {
13518 if (args[i] != null)
13519 break;
13520 }
13521 return args.slice(0, i + 1).map(arg => arg || `null`);
13522}
13523// JavaScript
13524function genCallExpression(node, context) {
13525 const { push, helper, pure } = context;
13526 const callee = isString(node.callee) ? node.callee : helper(node.callee);
13527 if (pure) {
13528 push(PURE_ANNOTATION);
13529 }
13530 push(callee + `(`, node);
13531 genNodeList(node.arguments, context);
13532 push(`)`);
13533}
13534function genObjectExpression(node, context) {
13535 const { push, indent, deindent, newline } = context;
13536 const { properties } = node;
13537 if (!properties.length) {
13538 push(`{}`, node);
13539 return;
13540 }
13541 const multilines = properties.length > 1 ||
13542 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
13543 push(multilines ? `{` : `{ `);
13544 multilines && indent();
13545 for (let i = 0; i < properties.length; i++) {
13546 const { key, value } = properties[i];
13547 // key
13548 genExpressionAsPropertyKey(key, context);
13549 push(`: `);
13550 // value
13551 genNode(value, context);
13552 if (i < properties.length - 1) {
13553 // will only reach this if it's multilines
13554 push(`,`);
13555 newline();
13556 }
13557 }
13558 multilines && deindent();
13559 push(multilines ? `}` : ` }`);
13560}
13561function genArrayExpression(node, context) {
13562 genNodeListAsArray(node.elements, context);
13563}
13564function genFunctionExpression(node, context) {
13565 const { push, indent, deindent } = context;
13566 const { params, returns, body, newline, isSlot } = node;
13567 if (isSlot) {
13568 // wrap slot functions with owner context
13569 push(`_${helperNameMap[WITH_CTX]}(`);
13570 }
13571 push(`(`, node);
13572 if (isArray(params)) {
13573 genNodeList(params, context);
13574 }
13575 else if (params) {
13576 genNode(params, context);
13577 }
13578 push(`) => `);
13579 if (newline || body) {
13580 push(`{`);
13581 indent();
13582 }
13583 if (returns) {
13584 if (newline) {
13585 push(`return `);
13586 }
13587 if (isArray(returns)) {
13588 genNodeListAsArray(returns, context);
13589 }
13590 else {
13591 genNode(returns, context);
13592 }
13593 }
13594 else if (body) {
13595 genNode(body, context);
13596 }
13597 if (newline || body) {
13598 deindent();
13599 push(`}`);
13600 }
13601 if (isSlot) {
13602 push(`)`);
13603 }
13604}
13605function genConditionalExpression(node, context) {
13606 const { test, consequent, alternate, newline: needNewline } = node;
13607 const { push, indent, deindent, newline } = context;
13608 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
13609 const needsParens = !isSimpleIdentifier(test.content);
13610 needsParens && push(`(`);
13611 genExpression(test, context);
13612 needsParens && push(`)`);
13613 }
13614 else {
13615 push(`(`);
13616 genNode(test, context);
13617 push(`)`);
13618 }
13619 needNewline && indent();
13620 context.indentLevel++;
13621 needNewline || push(` `);
13622 push(`? `);
13623 genNode(consequent, context);
13624 context.indentLevel--;
13625 needNewline && newline();
13626 needNewline || push(` `);
13627 push(`: `);
13628 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
13629 if (!isNested) {
13630 context.indentLevel++;
13631 }
13632 genNode(alternate, context);
13633 if (!isNested) {
13634 context.indentLevel--;
13635 }
13636 needNewline && deindent(true /* without newline */);
13637}
13638function genCacheExpression(node, context) {
13639 const { push, helper, indent, deindent, newline } = context;
13640 push(`_cache[${node.index}] || (`);
13641 if (node.isVNode) {
13642 indent();
13643 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
13644 newline();
13645 }
13646 push(`_cache[${node.index}] = `);
13647 genNode(node.value, context);
13648 if (node.isVNode) {
13649 push(`,`);
13650 newline();
13651 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
13652 newline();
13653 push(`_cache[${node.index}]`);
13654 deindent();
13655 }
13656 push(`)`);
13657}
13658
13659// these keywords should not appear inside expressions, but operators like
13660// typeof, instanceof and in are allowed
13661const prohibitedKeywordRE = new RegExp('\\b' +
13662 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
13663 'super,throw,while,yield,delete,export,import,return,switch,default,' +
13664 'extends,finally,continue,debugger,function,arguments,typeof,void')
13665 .split(',')
13666 .join('\\b|\\b') +
13667 '\\b');
13668// strip strings in expressions
13669const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
13670/**
13671 * Validate a non-prefixed expression.
13672 * This is only called when using the in-browser runtime compiler since it
13673 * doesn't prefix expressions.
13674 */
13675function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
13676 const exp = node.content;
13677 // empty expressions are validated per-directive since some directives
13678 // do allow empty expressions.
13679 if (!exp.trim()) {
13680 return;
13681 }
13682 try {
13683 new Function(asRawStatements
13684 ? ` ${exp} `
13685 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
13686 }
13687 catch (e) {
13688 let message = e.message;
13689 const keywordMatch = exp
13690 .replace(stripStringRE, '')
13691 .match(prohibitedKeywordRE);
13692 if (keywordMatch) {
13693 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
13694 }
13695 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
13696 }
13697}
13698
13699const transformExpression = (node, context) => {
13700 if (node.type === 5 /* INTERPOLATION */) {
13701 node.content = processExpression(node.content, context);
13702 }
13703 else if (node.type === 1 /* ELEMENT */) {
13704 // handle directives on element
13705 for (let i = 0; i < node.props.length; i++) {
13706 const dir = node.props[i];
13707 // do not process for v-on & v-for since they are special handled
13708 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
13709 const exp = dir.exp;
13710 const arg = dir.arg;
13711 // do not process exp if this is v-on:arg - we need special handling
13712 // for wrapping inline statements.
13713 if (exp &&
13714 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
13715 !(dir.name === 'on' && arg)) {
13716 dir.exp = processExpression(exp, context,
13717 // slot args must be processed as function params
13718 dir.name === 'slot');
13719 }
13720 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
13721 dir.arg = processExpression(arg, context);
13722 }
13723 }
13724 }
13725 }
13726};
13727// Important: since this function uses Node.js only dependencies, it should
13728// always be used with a leading !true check so that it can be
13729// tree-shaken from the browser build.
13730function processExpression(node, context,
13731// some expressions like v-slot props & v-for aliases should be parsed as
13732// function params
13733asParams = false,
13734// v-on handler values may contain multiple statements
13735asRawStatements = false, localVars = Object.create(context.identifiers)) {
13736 {
13737 {
13738 // simple in-browser validation (same logic in 2.x)
13739 validateBrowserExpression(node, context, asParams, asRawStatements);
13740 }
13741 return node;
13742 }
13743}
13744
13745const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
13746 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
13747 // #1587: We need to dynamically increment the key based on the current
13748 // node's sibling nodes, since chained v-if/else branches are
13749 // rendered at the same depth
13750 const siblings = context.parent.children;
13751 let i = siblings.indexOf(ifNode);
13752 let key = 0;
13753 while (i-- >= 0) {
13754 const sibling = siblings[i];
13755 if (sibling && sibling.type === 9 /* IF */) {
13756 key += sibling.branches.length;
13757 }
13758 }
13759 // Exit callback. Complete the codegenNode when all children have been
13760 // transformed.
13761 return () => {
13762 if (isRoot) {
13763 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
13764 }
13765 else {
13766 // attach this branch's codegen node to the v-if root.
13767 const parentCondition = getParentCondition(ifNode.codegenNode);
13768 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
13769 }
13770 };
13771 });
13772});
13773// target-agnostic transform used for both Client and SSR
13774function processIf(node, dir, context, processCodegen) {
13775 if (dir.name !== 'else' &&
13776 (!dir.exp || !dir.exp.content.trim())) {
13777 const loc = dir.exp ? dir.exp.loc : node.loc;
13778 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));
13779 dir.exp = createSimpleExpression(`true`, false, loc);
13780 }
13781 if (dir.exp) {
13782 validateBrowserExpression(dir.exp, context);
13783 }
13784 if (dir.name === 'if') {
13785 const branch = createIfBranch(node, dir);
13786 const ifNode = {
13787 type: 9 /* IF */,
13788 loc: node.loc,
13789 branches: [branch]
13790 };
13791 context.replaceNode(ifNode);
13792 if (processCodegen) {
13793 return processCodegen(ifNode, branch, true);
13794 }
13795 }
13796 else {
13797 // locate the adjacent v-if
13798 const siblings = context.parent.children;
13799 const comments = [];
13800 let i = siblings.indexOf(node);
13801 while (i-- >= -1) {
13802 const sibling = siblings[i];
13803 if (sibling && sibling.type === 3 /* COMMENT */) {
13804 context.removeNode(sibling);
13805 comments.unshift(sibling);
13806 continue;
13807 }
13808 if (sibling &&
13809 sibling.type === 2 /* TEXT */ &&
13810 !sibling.content.trim().length) {
13811 context.removeNode(sibling);
13812 continue;
13813 }
13814 if (sibling && sibling.type === 9 /* IF */) {
13815 // Check if v-else was followed by v-else-if
13816 if (dir.name === 'else-if' &&
13817 sibling.branches[sibling.branches.length - 1].condition === undefined) {
13818 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13819 }
13820 // move the node to the if node's branches
13821 context.removeNode();
13822 const branch = createIfBranch(node, dir);
13823 if (comments.length &&
13824 // #3619 ignore comments if the v-if is direct child of <transition>
13825 !(context.parent &&
13826 context.parent.type === 1 /* ELEMENT */ &&
13827 isBuiltInType(context.parent.tag, 'transition'))) {
13828 branch.children = [...comments, ...branch.children];
13829 }
13830 // check if user is forcing same key on different branches
13831 {
13832 const key = branch.userKey;
13833 if (key) {
13834 sibling.branches.forEach(({ userKey }) => {
13835 if (isSameKey(userKey, key)) {
13836 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
13837 }
13838 });
13839 }
13840 }
13841 sibling.branches.push(branch);
13842 const onExit = processCodegen && processCodegen(sibling, branch, false);
13843 // since the branch was removed, it will not be traversed.
13844 // make sure to traverse here.
13845 traverseNode(branch, context);
13846 // call on exit
13847 if (onExit)
13848 onExit();
13849 // make sure to reset currentNode after traversal to indicate this
13850 // node has been removed.
13851 context.currentNode = null;
13852 }
13853 else {
13854 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13855 }
13856 break;
13857 }
13858 }
13859}
13860function createIfBranch(node, dir) {
13861 const isTemplateIf = node.tagType === 3 /* TEMPLATE */;
13862 return {
13863 type: 10 /* IF_BRANCH */,
13864 loc: node.loc,
13865 condition: dir.name === 'else' ? undefined : dir.exp,
13866 children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
13867 userKey: findProp(node, `key`),
13868 isTemplateIf
13869 };
13870}
13871function createCodegenNodeForBranch(branch, keyIndex, context) {
13872 if (branch.condition) {
13873 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
13874 // make sure to pass in asBlock: true so that the comment node call
13875 // closes the current block.
13876 createCallExpression(context.helper(CREATE_COMMENT), [
13877 '"v-if"' ,
13878 'true'
13879 ]));
13880 }
13881 else {
13882 return createChildrenCodegenNode(branch, keyIndex, context);
13883 }
13884}
13885function createChildrenCodegenNode(branch, keyIndex, context) {
13886 const { helper } = context;
13887 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
13888 const { children } = branch;
13889 const firstChild = children[0];
13890 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
13891 if (needFragmentWrapper) {
13892 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
13893 // optimize away nested fragments when child is a ForNode
13894 const vnodeCall = firstChild.codegenNode;
13895 injectProp(vnodeCall, keyProperty, context);
13896 return vnodeCall;
13897 }
13898 else {
13899 let patchFlag = 64 /* STABLE_FRAGMENT */;
13900 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
13901 // check if the fragment actually contains a single valid child with
13902 // the rest being comments
13903 if (!branch.isTemplateIf &&
13904 children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
13905 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
13906 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
13907 }
13908 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);
13909 }
13910 }
13911 else {
13912 const ret = firstChild.codegenNode;
13913 const vnodeCall = getMemoedVNodeCall(ret);
13914 // Change createVNode to createBlock.
13915 if (vnodeCall.type === 13 /* VNODE_CALL */) {
13916 makeBlock(vnodeCall, context);
13917 }
13918 // inject branch key
13919 injectProp(vnodeCall, keyProperty, context);
13920 return ret;
13921 }
13922}
13923function isSameKey(a, b) {
13924 if (!a || a.type !== b.type) {
13925 return false;
13926 }
13927 if (a.type === 6 /* ATTRIBUTE */) {
13928 if (a.value.content !== b.value.content) {
13929 return false;
13930 }
13931 }
13932 else {
13933 // directive
13934 const exp = a.exp;
13935 const branchExp = b.exp;
13936 if (exp.type !== branchExp.type) {
13937 return false;
13938 }
13939 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
13940 exp.isStatic !== branchExp.isStatic ||
13941 exp.content !== branchExp.content) {
13942 return false;
13943 }
13944 }
13945 return true;
13946}
13947function getParentCondition(node) {
13948 while (true) {
13949 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13950 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13951 node = node.alternate;
13952 }
13953 else {
13954 return node;
13955 }
13956 }
13957 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
13958 node = node.value;
13959 }
13960 }
13961}
13962
13963const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
13964 const { helper, removeHelper } = context;
13965 return processFor(node, dir, context, forNode => {
13966 // create the loop render function expression now, and add the
13967 // iterator on exit after all children have been traversed
13968 const renderExp = createCallExpression(helper(RENDER_LIST), [
13969 forNode.source
13970 ]);
13971 const isTemplate = isTemplateNode(node);
13972 const memo = findDir(node, 'memo');
13973 const keyProp = findProp(node, `key`);
13974 const keyExp = keyProp &&
13975 (keyProp.type === 6 /* ATTRIBUTE */
13976 ? createSimpleExpression(keyProp.value.content, true)
13977 : keyProp.exp);
13978 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
13979 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
13980 forNode.source.constType > 0 /* NOT_CONSTANT */;
13981 const fragmentFlag = isStableFragment
13982 ? 64 /* STABLE_FRAGMENT */
13983 : keyProp
13984 ? 128 /* KEYED_FRAGMENT */
13985 : 256 /* UNKEYED_FRAGMENT */;
13986 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
13987 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
13988 return () => {
13989 // finish the codegen now that all children have been traversed
13990 let childBlock;
13991 const { children } = forNode;
13992 // check <template v-for> key placement
13993 if (isTemplate) {
13994 node.children.some(c => {
13995 if (c.type === 1 /* ELEMENT */) {
13996 const key = findProp(c, 'key');
13997 if (key) {
13998 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
13999 return true;
14000 }
14001 }
14002 });
14003 }
14004 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
14005 const slotOutlet = isSlotOutlet(node)
14006 ? node
14007 : isTemplate &&
14008 node.children.length === 1 &&
14009 isSlotOutlet(node.children[0])
14010 ? node.children[0] // api-extractor somehow fails to infer this
14011 : null;
14012 if (slotOutlet) {
14013 // <slot v-for="..."> or <template v-for="..."><slot/></template>
14014 childBlock = slotOutlet.codegenNode;
14015 if (isTemplate && keyProperty) {
14016 // <template v-for="..." :key="..."><slot/></template>
14017 // we need to inject the key to the renderSlot() call.
14018 // the props for renderSlot is passed as the 3rd argument.
14019 injectProp(childBlock, keyProperty, context);
14020 }
14021 }
14022 else if (needFragmentWrapper) {
14023 // <template v-for="..."> with text or multi-elements
14024 // should generate a fragment block for each loop
14025 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
14026 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
14027 ), undefined, undefined, true, undefined, false /* isComponent */);
14028 }
14029 else {
14030 // Normal element v-for. Directly use the child's codegenNode
14031 // but mark it as a block.
14032 childBlock = children[0]
14033 .codegenNode;
14034 if (isTemplate && keyProperty) {
14035 injectProp(childBlock, keyProperty, context);
14036 }
14037 if (childBlock.isBlock !== !isStableFragment) {
14038 if (childBlock.isBlock) {
14039 // switch from block to vnode
14040 removeHelper(OPEN_BLOCK);
14041 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14042 }
14043 else {
14044 // switch from vnode to block
14045 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14046 }
14047 }
14048 childBlock.isBlock = !isStableFragment;
14049 if (childBlock.isBlock) {
14050 helper(OPEN_BLOCK);
14051 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14052 }
14053 else {
14054 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14055 }
14056 }
14057 if (memo) {
14058 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
14059 createSimpleExpression(`_cached`)
14060 ]));
14061 loop.body = createBlockStatement([
14062 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
14063 createCompoundExpression([
14064 `if (_cached`,
14065 ...(keyExp ? [` && _cached.key === `, keyExp] : []),
14066 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
14067 ]),
14068 createCompoundExpression([`const _item = `, childBlock]),
14069 createSimpleExpression(`_item.memo = _memo`),
14070 createSimpleExpression(`return _item`)
14071 ]);
14072 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
14073 }
14074 else {
14075 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
14076 }
14077 };
14078 });
14079});
14080// target-agnostic transform used for both Client and SSR
14081function processFor(node, dir, context, processCodegen) {
14082 if (!dir.exp) {
14083 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
14084 return;
14085 }
14086 const parseResult = parseForExpression(
14087 // can only be simple expression because vFor transform is applied
14088 // before expression transform.
14089 dir.exp, context);
14090 if (!parseResult) {
14091 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
14092 return;
14093 }
14094 const { addIdentifiers, removeIdentifiers, scopes } = context;
14095 const { source, value, key, index } = parseResult;
14096 const forNode = {
14097 type: 11 /* FOR */,
14098 loc: dir.loc,
14099 source,
14100 valueAlias: value,
14101 keyAlias: key,
14102 objectIndexAlias: index,
14103 parseResult,
14104 children: isTemplateNode(node) ? node.children : [node]
14105 };
14106 context.replaceNode(forNode);
14107 // bookkeeping
14108 scopes.vFor++;
14109 const onExit = processCodegen && processCodegen(forNode);
14110 return () => {
14111 scopes.vFor--;
14112 if (onExit)
14113 onExit();
14114 };
14115}
14116const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
14117// This regex doesn't cover the case if key or index aliases have destructuring,
14118// but those do not make sense in the first place, so this works in practice.
14119const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
14120const stripParensRE = /^\(|\)$/g;
14121function parseForExpression(input, context) {
14122 const loc = input.loc;
14123 const exp = input.content;
14124 const inMatch = exp.match(forAliasRE);
14125 if (!inMatch)
14126 return;
14127 const [, LHS, RHS] = inMatch;
14128 const result = {
14129 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
14130 value: undefined,
14131 key: undefined,
14132 index: undefined
14133 };
14134 {
14135 validateBrowserExpression(result.source, context);
14136 }
14137 let valueContent = LHS.trim().replace(stripParensRE, '').trim();
14138 const trimmedOffset = LHS.indexOf(valueContent);
14139 const iteratorMatch = valueContent.match(forIteratorRE);
14140 if (iteratorMatch) {
14141 valueContent = valueContent.replace(forIteratorRE, '').trim();
14142 const keyContent = iteratorMatch[1].trim();
14143 let keyOffset;
14144 if (keyContent) {
14145 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
14146 result.key = createAliasExpression(loc, keyContent, keyOffset);
14147 {
14148 validateBrowserExpression(result.key, context, true);
14149 }
14150 }
14151 if (iteratorMatch[2]) {
14152 const indexContent = iteratorMatch[2].trim();
14153 if (indexContent) {
14154 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
14155 ? keyOffset + keyContent.length
14156 : trimmedOffset + valueContent.length));
14157 {
14158 validateBrowserExpression(result.index, context, true);
14159 }
14160 }
14161 }
14162 }
14163 if (valueContent) {
14164 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
14165 {
14166 validateBrowserExpression(result.value, context, true);
14167 }
14168 }
14169 return result;
14170}
14171function createAliasExpression(range, content, offset) {
14172 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
14173}
14174function createForLoopParams({ value, key, index }, memoArgs = []) {
14175 return createParamsList([value, key, index, ...memoArgs]);
14176}
14177function createParamsList(args) {
14178 let i = args.length;
14179 while (i--) {
14180 if (args[i])
14181 break;
14182 }
14183 return args
14184 .slice(0, i + 1)
14185 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
14186}
14187
14188const defaultFallback = createSimpleExpression(`undefined`, false);
14189// A NodeTransform that:
14190// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
14191// by transformExpression. This is only applied in non-browser builds with
14192// { prefixIdentifiers: true }.
14193// 2. Track v-slot depths so that we know a slot is inside another slot.
14194// Note the exit callback is executed before buildSlots() on the same node,
14195// so only nested slots see positive numbers.
14196const trackSlotScopes = (node, context) => {
14197 if (node.type === 1 /* ELEMENT */ &&
14198 (node.tagType === 1 /* COMPONENT */ ||
14199 node.tagType === 3 /* TEMPLATE */)) {
14200 // We are only checking non-empty v-slot here
14201 // since we only care about slots that introduce scope variables.
14202 const vSlot = findDir(node, 'slot');
14203 if (vSlot) {
14204 vSlot.exp;
14205 context.scopes.vSlot++;
14206 return () => {
14207 context.scopes.vSlot--;
14208 };
14209 }
14210 }
14211};
14212const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
14213// Instead of being a DirectiveTransform, v-slot processing is called during
14214// transformElement to build the slots object for a component.
14215function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
14216 context.helper(WITH_CTX);
14217 const { children, loc } = node;
14218 const slotsProperties = [];
14219 const dynamicSlots = [];
14220 // If the slot is inside a v-for or another v-slot, force it to be dynamic
14221 // since it likely uses a scope variable.
14222 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
14223 // 1. Check for slot with slotProps on component itself.
14224 // <Comp v-slot="{ prop }"/>
14225 const onComponentSlot = findDir(node, 'slot', true);
14226 if (onComponentSlot) {
14227 const { arg, exp } = onComponentSlot;
14228 if (arg && !isStaticExp(arg)) {
14229 hasDynamicSlots = true;
14230 }
14231 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
14232 }
14233 // 2. Iterate through children and check for template slots
14234 // <template v-slot:foo="{ prop }">
14235 let hasTemplateSlots = false;
14236 let hasNamedDefaultSlot = false;
14237 const implicitDefaultChildren = [];
14238 const seenSlotNames = new Set();
14239 for (let i = 0; i < children.length; i++) {
14240 const slotElement = children[i];
14241 let slotDir;
14242 if (!isTemplateNode(slotElement) ||
14243 !(slotDir = findDir(slotElement, 'slot', true))) {
14244 // not a <template v-slot>, skip.
14245 if (slotElement.type !== 3 /* COMMENT */) {
14246 implicitDefaultChildren.push(slotElement);
14247 }
14248 continue;
14249 }
14250 if (onComponentSlot) {
14251 // already has on-component slot - this is incorrect usage.
14252 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
14253 break;
14254 }
14255 hasTemplateSlots = true;
14256 const { children: slotChildren, loc: slotLoc } = slotElement;
14257 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
14258 // check if name is dynamic.
14259 let staticSlotName;
14260 if (isStaticExp(slotName)) {
14261 staticSlotName = slotName ? slotName.content : `default`;
14262 }
14263 else {
14264 hasDynamicSlots = true;
14265 }
14266 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
14267 // check if this slot is conditional (v-if/v-for)
14268 let vIf;
14269 let vElse;
14270 let vFor;
14271 if ((vIf = findDir(slotElement, 'if'))) {
14272 hasDynamicSlots = true;
14273 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
14274 }
14275 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
14276 // find adjacent v-if
14277 let j = i;
14278 let prev;
14279 while (j--) {
14280 prev = children[j];
14281 if (prev.type !== 3 /* COMMENT */) {
14282 break;
14283 }
14284 }
14285 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
14286 // remove node
14287 children.splice(i, 1);
14288 i--;
14289 // attach this slot to previous conditional
14290 let conditional = dynamicSlots[dynamicSlots.length - 1];
14291 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
14292 conditional = conditional.alternate;
14293 }
14294 conditional.alternate = vElse.exp
14295 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
14296 : buildDynamicSlot(slotName, slotFunction);
14297 }
14298 else {
14299 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
14300 }
14301 }
14302 else if ((vFor = findDir(slotElement, 'for'))) {
14303 hasDynamicSlots = true;
14304 const parseResult = vFor.parseResult ||
14305 parseForExpression(vFor.exp, context);
14306 if (parseResult) {
14307 // Render the dynamic slots as an array and add it to the createSlot()
14308 // args. The runtime knows how to handle it appropriately.
14309 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
14310 parseResult.source,
14311 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
14312 ]));
14313 }
14314 else {
14315 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
14316 }
14317 }
14318 else {
14319 // check duplicate static names
14320 if (staticSlotName) {
14321 if (seenSlotNames.has(staticSlotName)) {
14322 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
14323 continue;
14324 }
14325 seenSlotNames.add(staticSlotName);
14326 if (staticSlotName === 'default') {
14327 hasNamedDefaultSlot = true;
14328 }
14329 }
14330 slotsProperties.push(createObjectProperty(slotName, slotFunction));
14331 }
14332 }
14333 if (!onComponentSlot) {
14334 const buildDefaultSlotProperty = (props, children) => {
14335 const fn = buildSlotFn(props, children, loc);
14336 return createObjectProperty(`default`, fn);
14337 };
14338 if (!hasTemplateSlots) {
14339 // implicit default slot (on component)
14340 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
14341 }
14342 else if (implicitDefaultChildren.length &&
14343 // #3766
14344 // with whitespace: 'preserve', whitespaces between slots will end up in
14345 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
14346 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
14347 // implicit default slot (mixed with named slots)
14348 if (hasNamedDefaultSlot) {
14349 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
14350 }
14351 else {
14352 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
14353 }
14354 }
14355 }
14356 const slotFlag = hasDynamicSlots
14357 ? 2 /* DYNAMIC */
14358 : hasForwardedSlots(node.children)
14359 ? 3 /* FORWARDED */
14360 : 1 /* STABLE */;
14361 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
14362 // 2 = compiled but dynamic = can skip normalization, but must run diff
14363 // 1 = compiled and static = can skip normalization AND diff as optimized
14364 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
14365 if (dynamicSlots.length) {
14366 slots = createCallExpression(context.helper(CREATE_SLOTS), [
14367 slots,
14368 createArrayExpression(dynamicSlots)
14369 ]);
14370 }
14371 return {
14372 slots,
14373 hasDynamicSlots
14374 };
14375}
14376function buildDynamicSlot(name, fn) {
14377 return createObjectExpression([
14378 createObjectProperty(`name`, name),
14379 createObjectProperty(`fn`, fn)
14380 ]);
14381}
14382function hasForwardedSlots(children) {
14383 for (let i = 0; i < children.length; i++) {
14384 const child = children[i];
14385 switch (child.type) {
14386 case 1 /* ELEMENT */:
14387 if (child.tagType === 2 /* SLOT */ ||
14388 hasForwardedSlots(child.children)) {
14389 return true;
14390 }
14391 break;
14392 case 9 /* IF */:
14393 if (hasForwardedSlots(child.branches))
14394 return true;
14395 break;
14396 case 10 /* IF_BRANCH */:
14397 case 11 /* FOR */:
14398 if (hasForwardedSlots(child.children))
14399 return true;
14400 break;
14401 }
14402 }
14403 return false;
14404}
14405function isNonWhitespaceContent(node) {
14406 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
14407 return true;
14408 return node.type === 2 /* TEXT */
14409 ? !!node.content.trim()
14410 : isNonWhitespaceContent(node.content);
14411}
14412
14413// some directive transforms (e.g. v-model) may return a symbol for runtime
14414// import, which should be used instead of a resolveDirective call.
14415const directiveImportMap = new WeakMap();
14416// generate a JavaScript AST for this element's codegen
14417const transformElement = (node, context) => {
14418 // perform the work on exit, after all child expressions have been
14419 // processed and merged.
14420 return function postTransformElement() {
14421 node = context.currentNode;
14422 if (!(node.type === 1 /* ELEMENT */ &&
14423 (node.tagType === 0 /* ELEMENT */ ||
14424 node.tagType === 1 /* COMPONENT */))) {
14425 return;
14426 }
14427 const { tag, props } = node;
14428 const isComponent = node.tagType === 1 /* COMPONENT */;
14429 // The goal of the transform is to create a codegenNode implementing the
14430 // VNodeCall interface.
14431 let vnodeTag = isComponent
14432 ? resolveComponentType(node, context)
14433 : `"${tag}"`;
14434 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
14435 let vnodeProps;
14436 let vnodeChildren;
14437 let vnodePatchFlag;
14438 let patchFlag = 0;
14439 let vnodeDynamicProps;
14440 let dynamicPropNames;
14441 let vnodeDirectives;
14442 let shouldUseBlock =
14443 // dynamic component may resolve to plain elements
14444 isDynamicComponent ||
14445 vnodeTag === TELEPORT ||
14446 vnodeTag === SUSPENSE ||
14447 (!isComponent &&
14448 // <svg> and <foreignObject> must be forced into blocks so that block
14449 // updates inside get proper isSVG flag at runtime. (#639, #643)
14450 // This is technically web-specific, but splitting the logic out of core
14451 // leads to too much unnecessary complexity.
14452 (tag === 'svg' || tag === 'foreignObject'));
14453 // props
14454 if (props.length > 0) {
14455 const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
14456 vnodeProps = propsBuildResult.props;
14457 patchFlag = propsBuildResult.patchFlag;
14458 dynamicPropNames = propsBuildResult.dynamicPropNames;
14459 const directives = propsBuildResult.directives;
14460 vnodeDirectives =
14461 directives && directives.length
14462 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14463 : undefined;
14464 if (propsBuildResult.shouldUseBlock) {
14465 shouldUseBlock = true;
14466 }
14467 }
14468 // children
14469 if (node.children.length > 0) {
14470 if (vnodeTag === KEEP_ALIVE) {
14471 // Although a built-in component, we compile KeepAlive with raw children
14472 // instead of slot functions so that it can be used inside Transition
14473 // or other Transition-wrapping HOCs.
14474 // To ensure correct updates with block optimizations, we need to:
14475 // 1. Force keep-alive into a block. This avoids its children being
14476 // collected by a parent block.
14477 shouldUseBlock = true;
14478 // 2. Force keep-alive to always be updated, since it uses raw children.
14479 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14480 if (node.children.length > 1) {
14481 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
14482 start: node.children[0].loc.start,
14483 end: node.children[node.children.length - 1].loc.end,
14484 source: ''
14485 }));
14486 }
14487 }
14488 const shouldBuildAsSlots = isComponent &&
14489 // Teleport is not a real component and has dedicated runtime handling
14490 vnodeTag !== TELEPORT &&
14491 // explained above.
14492 vnodeTag !== KEEP_ALIVE;
14493 if (shouldBuildAsSlots) {
14494 const { slots, hasDynamicSlots } = buildSlots(node, context);
14495 vnodeChildren = slots;
14496 if (hasDynamicSlots) {
14497 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14498 }
14499 }
14500 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
14501 const child = node.children[0];
14502 const type = child.type;
14503 // check for dynamic text children
14504 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
14505 type === 8 /* COMPOUND_EXPRESSION */;
14506 if (hasDynamicTextChild &&
14507 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
14508 patchFlag |= 1 /* TEXT */;
14509 }
14510 // pass directly if the only child is a text node
14511 // (plain / interpolation / expression)
14512 if (hasDynamicTextChild || type === 2 /* TEXT */) {
14513 vnodeChildren = child;
14514 }
14515 else {
14516 vnodeChildren = node.children;
14517 }
14518 }
14519 else {
14520 vnodeChildren = node.children;
14521 }
14522 }
14523 // patchFlag & dynamicPropNames
14524 if (patchFlag !== 0) {
14525 {
14526 if (patchFlag < 0) {
14527 // special flags (negative and mutually exclusive)
14528 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
14529 }
14530 else {
14531 // bitwise flags
14532 const flagNames = Object.keys(PatchFlagNames)
14533 .map(Number)
14534 .filter(n => n > 0 && patchFlag & n)
14535 .map(n => PatchFlagNames[n])
14536 .join(`, `);
14537 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
14538 }
14539 }
14540 if (dynamicPropNames && dynamicPropNames.length) {
14541 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
14542 }
14543 }
14544 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
14545 };
14546};
14547function resolveComponentType(node, context, ssr = false) {
14548 let { tag } = node;
14549 // 1. dynamic component
14550 const isExplicitDynamic = isComponentTag(tag);
14551 const isProp = findProp(node, 'is');
14552 if (isProp) {
14553 if (isExplicitDynamic ||
14554 (false )) {
14555 const exp = isProp.type === 6 /* ATTRIBUTE */
14556 ? isProp.value && createSimpleExpression(isProp.value.content, true)
14557 : isProp.exp;
14558 if (exp) {
14559 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14560 exp
14561 ]);
14562 }
14563 }
14564 else if (isProp.type === 6 /* ATTRIBUTE */ &&
14565 isProp.value.content.startsWith('vue:')) {
14566 // <button is="vue:xxx">
14567 // if not <component>, only is value that starts with "vue:" will be
14568 // treated as component by the parse phase and reach here, unless it's
14569 // compat mode where all is values are considered components
14570 tag = isProp.value.content.slice(4);
14571 }
14572 }
14573 // 1.5 v-is (TODO: Deprecate)
14574 const isDir = !isExplicitDynamic && findDir(node, 'is');
14575 if (isDir && isDir.exp) {
14576 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14577 isDir.exp
14578 ]);
14579 }
14580 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
14581 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
14582 if (builtIn) {
14583 // built-ins are simply fallthroughs / have special handling during ssr
14584 // so we don't need to import their runtime equivalents
14585 if (!ssr)
14586 context.helper(builtIn);
14587 return builtIn;
14588 }
14589 // 5. user component (resolve)
14590 context.helper(RESOLVE_COMPONENT);
14591 context.components.add(tag);
14592 return toValidAssetId(tag, `component`);
14593}
14594function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
14595 const { tag, loc: elementLoc, children } = node;
14596 let properties = [];
14597 const mergeArgs = [];
14598 const runtimeDirectives = [];
14599 const hasChildren = children.length > 0;
14600 let shouldUseBlock = false;
14601 // patchFlag analysis
14602 let patchFlag = 0;
14603 let hasRef = false;
14604 let hasClassBinding = false;
14605 let hasStyleBinding = false;
14606 let hasHydrationEventBinding = false;
14607 let hasDynamicKeys = false;
14608 let hasVnodeHook = false;
14609 const dynamicPropNames = [];
14610 const analyzePatchFlag = ({ key, value }) => {
14611 if (isStaticExp(key)) {
14612 const name = key.content;
14613 const isEventHandler = isOn(name);
14614 if (isEventHandler &&
14615 (!isComponent || isDynamicComponent) &&
14616 // omit the flag for click handlers because hydration gives click
14617 // dedicated fast path.
14618 name.toLowerCase() !== 'onclick' &&
14619 // omit v-model handlers
14620 name !== 'onUpdate:modelValue' &&
14621 // omit onVnodeXXX hooks
14622 !isReservedProp(name)) {
14623 hasHydrationEventBinding = true;
14624 }
14625 if (isEventHandler && isReservedProp(name)) {
14626 hasVnodeHook = true;
14627 }
14628 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
14629 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
14630 value.type === 8 /* COMPOUND_EXPRESSION */) &&
14631 getConstantType(value, context) > 0)) {
14632 // skip if the prop is a cached handler or has constant value
14633 return;
14634 }
14635 if (name === 'ref') {
14636 hasRef = true;
14637 }
14638 else if (name === 'class') {
14639 hasClassBinding = true;
14640 }
14641 else if (name === 'style') {
14642 hasStyleBinding = true;
14643 }
14644 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
14645 dynamicPropNames.push(name);
14646 }
14647 // treat the dynamic class and style binding of the component as dynamic props
14648 if (isComponent &&
14649 (name === 'class' || name === 'style') &&
14650 !dynamicPropNames.includes(name)) {
14651 dynamicPropNames.push(name);
14652 }
14653 }
14654 else {
14655 hasDynamicKeys = true;
14656 }
14657 };
14658 for (let i = 0; i < props.length; i++) {
14659 // static attribute
14660 const prop = props[i];
14661 if (prop.type === 6 /* ATTRIBUTE */) {
14662 const { loc, name, value } = prop;
14663 let isStatic = true;
14664 if (name === 'ref') {
14665 hasRef = true;
14666 if (context.scopes.vFor > 0) {
14667 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14668 }
14669 }
14670 // skip is on <component>, or is="vue:xxx"
14671 if (name === 'is' &&
14672 (isComponentTag(tag) ||
14673 (value && value.content.startsWith('vue:')) ||
14674 (false ))) {
14675 continue;
14676 }
14677 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14678 }
14679 else {
14680 // directives
14681 const { name, arg, exp, loc } = prop;
14682 const isVBind = name === 'bind';
14683 const isVOn = name === 'on';
14684 // skip v-slot - it is handled by its dedicated transform.
14685 if (name === 'slot') {
14686 if (!isComponent) {
14687 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));
14688 }
14689 continue;
14690 }
14691 // skip v-once/v-memo - they are handled by dedicated transforms.
14692 if (name === 'once' || name === 'memo') {
14693 continue;
14694 }
14695 // skip v-is and :is on <component>
14696 if (name === 'is' ||
14697 (isVBind &&
14698 isStaticArgOf(arg, 'is') &&
14699 (isComponentTag(tag) ||
14700 (false )))) {
14701 continue;
14702 }
14703 // skip v-on in SSR compilation
14704 if (isVOn && ssr) {
14705 continue;
14706 }
14707 if (
14708 // #938: elements with dynamic keys should be forced into blocks
14709 (isVBind && isStaticArgOf(arg, 'key')) ||
14710 // inline before-update hooks need to force block so that it is invoked
14711 // before children
14712 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14713 shouldUseBlock = true;
14714 }
14715 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14716 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14717 }
14718 // special case for v-bind and v-on with no argument
14719 if (!arg && (isVBind || isVOn)) {
14720 hasDynamicKeys = true;
14721 if (exp) {
14722 if (properties.length) {
14723 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14724 properties = [];
14725 }
14726 if (isVBind) {
14727 mergeArgs.push(exp);
14728 }
14729 else {
14730 // v-on="obj" -> toHandlers(obj)
14731 mergeArgs.push({
14732 type: 14 /* JS_CALL_EXPRESSION */,
14733 loc,
14734 callee: context.helper(TO_HANDLERS),
14735 arguments: [exp]
14736 });
14737 }
14738 }
14739 else {
14740 context.onError(createCompilerError(isVBind
14741 ? 34 /* X_V_BIND_NO_EXPRESSION */
14742 : 35 /* X_V_ON_NO_EXPRESSION */, loc));
14743 }
14744 continue;
14745 }
14746 const directiveTransform = context.directiveTransforms[name];
14747 if (directiveTransform) {
14748 // has built-in directive transform.
14749 const { props, needRuntime } = directiveTransform(prop, node, context);
14750 !ssr && props.forEach(analyzePatchFlag);
14751 properties.push(...props);
14752 if (needRuntime) {
14753 runtimeDirectives.push(prop);
14754 if (isSymbol(needRuntime)) {
14755 directiveImportMap.set(prop, needRuntime);
14756 }
14757 }
14758 }
14759 else if (!isBuiltInDirective(name)) {
14760 // no built-in transform, this is a user custom directive.
14761 runtimeDirectives.push(prop);
14762 // custom dirs may use beforeUpdate so they need to force blocks
14763 // to ensure before-update gets called before children update
14764 if (hasChildren) {
14765 shouldUseBlock = true;
14766 }
14767 }
14768 }
14769 }
14770 let propsExpression = undefined;
14771 // has v-bind="object" or v-on="object", wrap with mergeProps
14772 if (mergeArgs.length) {
14773 if (properties.length) {
14774 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14775 }
14776 if (mergeArgs.length > 1) {
14777 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
14778 }
14779 else {
14780 // single v-bind with nothing else - no need for a mergeProps call
14781 propsExpression = mergeArgs[0];
14782 }
14783 }
14784 else if (properties.length) {
14785 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
14786 }
14787 // patchFlag analysis
14788 if (hasDynamicKeys) {
14789 patchFlag |= 16 /* FULL_PROPS */;
14790 }
14791 else {
14792 if (hasClassBinding && !isComponent) {
14793 patchFlag |= 2 /* CLASS */;
14794 }
14795 if (hasStyleBinding && !isComponent) {
14796 patchFlag |= 4 /* STYLE */;
14797 }
14798 if (dynamicPropNames.length) {
14799 patchFlag |= 8 /* PROPS */;
14800 }
14801 if (hasHydrationEventBinding) {
14802 patchFlag |= 32 /* HYDRATE_EVENTS */;
14803 }
14804 }
14805 if (!shouldUseBlock &&
14806 (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14807 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14808 patchFlag |= 512 /* NEED_PATCH */;
14809 }
14810 // pre-normalize props, SSR is skipped for now
14811 if (!context.inSSR && propsExpression) {
14812 switch (propsExpression.type) {
14813 case 15 /* JS_OBJECT_EXPRESSION */:
14814 // means that there is no v-bind,
14815 // but still need to deal with dynamic key binding
14816 let classKeyIndex = -1;
14817 let styleKeyIndex = -1;
14818 let hasDynamicKey = false;
14819 for (let i = 0; i < propsExpression.properties.length; i++) {
14820 const key = propsExpression.properties[i].key;
14821 if (isStaticExp(key)) {
14822 if (key.content === 'class') {
14823 classKeyIndex = i;
14824 }
14825 else if (key.content === 'style') {
14826 styleKeyIndex = i;
14827 }
14828 }
14829 else if (!key.isHandlerKey) {
14830 hasDynamicKey = true;
14831 }
14832 }
14833 const classProp = propsExpression.properties[classKeyIndex];
14834 const styleProp = propsExpression.properties[styleKeyIndex];
14835 // no dynamic key
14836 if (!hasDynamicKey) {
14837 if (classProp && !isStaticExp(classProp.value)) {
14838 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
14839 }
14840 if (styleProp &&
14841 // the static style is compiled into an object,
14842 // so use `hasStyleBinding` to ensure that it is a dynamic style binding
14843 (hasStyleBinding ||
14844 (styleProp.value.type === 4 /* SIMPLE_EXPRESSION */ &&
14845 styleProp.value.content.trim()[0] === `[`) ||
14846 // v-bind:style and style both exist,
14847 // v-bind:style with static literal object
14848 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
14849 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
14850 }
14851 }
14852 else {
14853 // dynamic key binding, wrap with `normalizeProps`
14854 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
14855 }
14856 break;
14857 case 14 /* JS_CALL_EXPRESSION */:
14858 // mergeProps call, do nothing
14859 break;
14860 default:
14861 // single v-bind
14862 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
14863 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
14864 propsExpression
14865 ])
14866 ]);
14867 break;
14868 }
14869 }
14870 return {
14871 props: propsExpression,
14872 directives: runtimeDirectives,
14873 patchFlag,
14874 dynamicPropNames,
14875 shouldUseBlock
14876 };
14877}
14878// Dedupe props in an object literal.
14879// Literal duplicated attributes would have been warned during the parse phase,
14880// however, it's possible to encounter duplicated `onXXX` handlers with different
14881// modifiers. We also need to merge static and dynamic class / style attributes.
14882// - onXXX handlers / style: merge into array
14883// - class: merge into single expression with concatenation
14884function dedupeProperties(properties) {
14885 const knownProps = new Map();
14886 const deduped = [];
14887 for (let i = 0; i < properties.length; i++) {
14888 const prop = properties[i];
14889 // dynamic keys are always allowed
14890 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
14891 deduped.push(prop);
14892 continue;
14893 }
14894 const name = prop.key.content;
14895 const existing = knownProps.get(name);
14896 if (existing) {
14897 if (name === 'style' || name === 'class' || isOn(name)) {
14898 mergeAsArray$1(existing, prop);
14899 }
14900 // unexpected duplicate, should have emitted error during parse
14901 }
14902 else {
14903 knownProps.set(name, prop);
14904 deduped.push(prop);
14905 }
14906 }
14907 return deduped;
14908}
14909function mergeAsArray$1(existing, incoming) {
14910 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
14911 existing.value.elements.push(incoming.value);
14912 }
14913 else {
14914 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
14915 }
14916}
14917function buildDirectiveArgs(dir, context) {
14918 const dirArgs = [];
14919 const runtime = directiveImportMap.get(dir);
14920 if (runtime) {
14921 // built-in directive with runtime
14922 dirArgs.push(context.helperString(runtime));
14923 }
14924 else {
14925 {
14926 // inject statement for resolving directive
14927 context.helper(RESOLVE_DIRECTIVE);
14928 context.directives.add(dir.name);
14929 dirArgs.push(toValidAssetId(dir.name, `directive`));
14930 }
14931 }
14932 const { loc } = dir;
14933 if (dir.exp)
14934 dirArgs.push(dir.exp);
14935 if (dir.arg) {
14936 if (!dir.exp) {
14937 dirArgs.push(`void 0`);
14938 }
14939 dirArgs.push(dir.arg);
14940 }
14941 if (Object.keys(dir.modifiers).length) {
14942 if (!dir.arg) {
14943 if (!dir.exp) {
14944 dirArgs.push(`void 0`);
14945 }
14946 dirArgs.push(`void 0`);
14947 }
14948 const trueExpression = createSimpleExpression(`true`, false, loc);
14949 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
14950 }
14951 return createArrayExpression(dirArgs, dir.loc);
14952}
14953function stringifyDynamicPropNames(props) {
14954 let propsNamesString = `[`;
14955 for (let i = 0, l = props.length; i < l; i++) {
14956 propsNamesString += JSON.stringify(props[i]);
14957 if (i < l - 1)
14958 propsNamesString += ', ';
14959 }
14960 return propsNamesString + `]`;
14961}
14962function isComponentTag(tag) {
14963 return tag === 'component' || tag === 'Component';
14964}
14965
14966const transformSlotOutlet = (node, context) => {
14967 if (isSlotOutlet(node)) {
14968 const { children, loc } = node;
14969 const { slotName, slotProps } = processSlotOutlet(node, context);
14970 const slotArgs = [
14971 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
14972 slotName,
14973 '{}',
14974 'undefined',
14975 'true'
14976 ];
14977 let expectedLen = 2;
14978 if (slotProps) {
14979 slotArgs[2] = slotProps;
14980 expectedLen = 3;
14981 }
14982 if (children.length) {
14983 slotArgs[3] = createFunctionExpression([], children, false, false, loc);
14984 expectedLen = 4;
14985 }
14986 if (context.scopeId && !context.slotted) {
14987 expectedLen = 5;
14988 }
14989 slotArgs.splice(expectedLen); // remove unused arguments
14990 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
14991 }
14992};
14993function processSlotOutlet(node, context) {
14994 let slotName = `"default"`;
14995 let slotProps = undefined;
14996 const nonNameProps = [];
14997 for (let i = 0; i < node.props.length; i++) {
14998 const p = node.props[i];
14999 if (p.type === 6 /* ATTRIBUTE */) {
15000 if (p.value) {
15001 if (p.name === 'name') {
15002 slotName = JSON.stringify(p.value.content);
15003 }
15004 else {
15005 p.name = camelize(p.name);
15006 nonNameProps.push(p);
15007 }
15008 }
15009 }
15010 else {
15011 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
15012 if (p.exp)
15013 slotName = p.exp;
15014 }
15015 else {
15016 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
15017 p.arg.content = camelize(p.arg.content);
15018 }
15019 nonNameProps.push(p);
15020 }
15021 }
15022 }
15023 if (nonNameProps.length > 0) {
15024 const { props, directives } = buildProps(node, context, nonNameProps, false, false);
15025 slotProps = props;
15026 if (directives.length) {
15027 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
15028 }
15029 }
15030 return {
15031 slotName,
15032 slotProps
15033 };
15034}
15035
15036const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
15037const transformOn = (dir, node, context, augmentor) => {
15038 const { loc, modifiers, arg } = dir;
15039 if (!dir.exp && !modifiers.length) {
15040 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));
15041 }
15042 let eventName;
15043 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15044 if (arg.isStatic) {
15045 let rawName = arg.content;
15046 // TODO deprecate @vnodeXXX usage
15047 if (rawName.startsWith('vue:')) {
15048 rawName = `vnode-${rawName.slice(4)}`;
15049 }
15050 // for all event listeners, auto convert it to camelCase. See issue #2249
15051 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
15052 }
15053 else {
15054 // #2388
15055 eventName = createCompoundExpression([
15056 `${context.helperString(TO_HANDLER_KEY)}(`,
15057 arg,
15058 `)`
15059 ]);
15060 }
15061 }
15062 else {
15063 // already a compound expression.
15064 eventName = arg;
15065 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
15066 eventName.children.push(`)`);
15067 }
15068 // handler processing
15069 let exp = dir.exp;
15070 if (exp && !exp.content.trim()) {
15071 exp = undefined;
15072 }
15073 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
15074 if (exp) {
15075 const isMemberExp = isMemberExpression(exp.content);
15076 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
15077 const hasMultipleStatements = exp.content.includes(`;`);
15078 {
15079 validateBrowserExpression(exp, context, false, hasMultipleStatements);
15080 }
15081 if (isInlineStatement || (shouldCache && isMemberExp)) {
15082 // wrap inline statement in a function expression
15083 exp = createCompoundExpression([
15084 `${isInlineStatement
15085 ? `$event`
15086 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
15087 exp,
15088 hasMultipleStatements ? `}` : `)`
15089 ]);
15090 }
15091 }
15092 let ret = {
15093 props: [
15094 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
15095 ]
15096 };
15097 // apply extended compiler augmentor
15098 if (augmentor) {
15099 ret = augmentor(ret);
15100 }
15101 if (shouldCache) {
15102 // cache handlers so that it's always the same handler being passed down.
15103 // this avoids unnecessary re-renders when users use inline handlers on
15104 // components.
15105 ret.props[0].value = context.cache(ret.props[0].value);
15106 }
15107 // mark the key as handler for props normalization check
15108 ret.props.forEach(p => (p.key.isHandlerKey = true));
15109 return ret;
15110};
15111
15112// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
15113// codegen for the entire props object. This transform here is only for v-bind
15114// *with* args.
15115const transformBind = (dir, _node, context) => {
15116 const { exp, modifiers, loc } = dir;
15117 const arg = dir.arg;
15118 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
15119 arg.children.unshift(`(`);
15120 arg.children.push(`) || ""`);
15121 }
15122 else if (!arg.isStatic) {
15123 arg.content = `${arg.content} || ""`;
15124 }
15125 // .sync is replaced by v-model:arg
15126 if (modifiers.includes('camel')) {
15127 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15128 if (arg.isStatic) {
15129 arg.content = camelize(arg.content);
15130 }
15131 else {
15132 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
15133 }
15134 }
15135 else {
15136 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
15137 arg.children.push(`)`);
15138 }
15139 }
15140 if (!context.inSSR) {
15141 if (modifiers.includes('prop')) {
15142 injectPrefix(arg, '.');
15143 }
15144 if (modifiers.includes('attr')) {
15145 injectPrefix(arg, '^');
15146 }
15147 }
15148 if (!exp ||
15149 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
15150 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));
15151 return {
15152 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
15153 };
15154 }
15155 return {
15156 props: [createObjectProperty(arg, exp)]
15157 };
15158};
15159const injectPrefix = (arg, prefix) => {
15160 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15161 if (arg.isStatic) {
15162 arg.content = prefix + arg.content;
15163 }
15164 else {
15165 arg.content = `\`${prefix}\${${arg.content}}\``;
15166 }
15167 }
15168 else {
15169 arg.children.unshift(`'${prefix}' + (`);
15170 arg.children.push(`)`);
15171 }
15172};
15173
15174// Merge adjacent text nodes and expressions into a single expression
15175// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
15176const transformText = (node, context) => {
15177 if (node.type === 0 /* ROOT */ ||
15178 node.type === 1 /* ELEMENT */ ||
15179 node.type === 11 /* FOR */ ||
15180 node.type === 10 /* IF_BRANCH */) {
15181 // perform the transform on node exit so that all expressions have already
15182 // been processed.
15183 return () => {
15184 const children = node.children;
15185 let currentContainer = undefined;
15186 let hasText = false;
15187 for (let i = 0; i < children.length; i++) {
15188 const child = children[i];
15189 if (isText(child)) {
15190 hasText = true;
15191 for (let j = i + 1; j < children.length; j++) {
15192 const next = children[j];
15193 if (isText(next)) {
15194 if (!currentContainer) {
15195 currentContainer = children[i] = createCompoundExpression([child], child.loc);
15196 }
15197 // merge adjacent text node into current
15198 currentContainer.children.push(` + `, next);
15199 children.splice(j, 1);
15200 j--;
15201 }
15202 else {
15203 currentContainer = undefined;
15204 break;
15205 }
15206 }
15207 }
15208 }
15209 if (!hasText ||
15210 // if this is a plain element with a single text child, leave it
15211 // as-is since the runtime has dedicated fast path for this by directly
15212 // setting textContent of the element.
15213 // for component root it's always normalized anyway.
15214 (children.length === 1 &&
15215 (node.type === 0 /* ROOT */ ||
15216 (node.type === 1 /* ELEMENT */ &&
15217 node.tagType === 0 /* ELEMENT */ &&
15218 // #3756
15219 // custom directives can potentially add DOM elements arbitrarily,
15220 // we need to avoid setting textContent of the element at runtime
15221 // to avoid accidentally overwriting the DOM elements added
15222 // by the user through custom directives.
15223 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
15224 !context.directiveTransforms[p.name]) &&
15225 // in compat mode, <template> tags with no special directives
15226 // will be rendered as a fragment so its children must be
15227 // converted into vnodes.
15228 !(false ))))) {
15229 return;
15230 }
15231 // pre-convert text nodes into createTextVNode(text) calls to avoid
15232 // runtime normalization.
15233 for (let i = 0; i < children.length; i++) {
15234 const child = children[i];
15235 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
15236 const callArgs = [];
15237 // createTextVNode defaults to single whitespace, so if it is a
15238 // single space the code could be an empty call to save bytes.
15239 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
15240 callArgs.push(child);
15241 }
15242 // mark dynamic text with flag so it gets patched inside a block
15243 if (!context.ssr &&
15244 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
15245 callArgs.push(1 /* TEXT */ +
15246 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
15247 }
15248 children[i] = {
15249 type: 12 /* TEXT_CALL */,
15250 content: child,
15251 loc: child.loc,
15252 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
15253 };
15254 }
15255 }
15256 };
15257 }
15258};
15259
15260const seen = new WeakSet();
15261const transformOnce = (node, context) => {
15262 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
15263 if (seen.has(node) || context.inVOnce) {
15264 return;
15265 }
15266 seen.add(node);
15267 context.inVOnce = true;
15268 context.helper(SET_BLOCK_TRACKING);
15269 return () => {
15270 context.inVOnce = false;
15271 const cur = context.currentNode;
15272 if (cur.codegenNode) {
15273 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
15274 }
15275 };
15276 }
15277};
15278
15279const transformModel = (dir, node, context) => {
15280 const { exp, arg } = dir;
15281 if (!exp) {
15282 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
15283 return createTransformProps();
15284 }
15285 const rawExp = exp.loc.source;
15286 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
15287 // im SFC <script setup> inline mode, the exp may have been transformed into
15288 // _unref(exp)
15289 context.bindingMetadata[rawExp];
15290 const maybeRef = !true /* SETUP_CONST */;
15291 if (!expString.trim() ||
15292 (!isMemberExpression(expString) && !maybeRef)) {
15293 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
15294 return createTransformProps();
15295 }
15296 const propName = arg ? arg : createSimpleExpression('modelValue', true);
15297 const eventName = arg
15298 ? isStaticExp(arg)
15299 ? `onUpdate:${arg.content}`
15300 : createCompoundExpression(['"onUpdate:" + ', arg])
15301 : `onUpdate:modelValue`;
15302 let assignmentExp;
15303 const eventArg = context.isTS ? `($event: any)` : `$event`;
15304 {
15305 assignmentExp = createCompoundExpression([
15306 `${eventArg} => ((`,
15307 exp,
15308 `) = $event)`
15309 ]);
15310 }
15311 const props = [
15312 // modelValue: foo
15313 createObjectProperty(propName, dir.exp),
15314 // "onUpdate:modelValue": $event => (foo = $event)
15315 createObjectProperty(eventName, assignmentExp)
15316 ];
15317 // modelModifiers: { foo: true, "bar-baz": true }
15318 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
15319 const modifiers = dir.modifiers
15320 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
15321 .join(`, `);
15322 const modifiersKey = arg
15323 ? isStaticExp(arg)
15324 ? `${arg.content}Modifiers`
15325 : createCompoundExpression([arg, ' + "Modifiers"'])
15326 : `modelModifiers`;
15327 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
15328 }
15329 return createTransformProps(props);
15330};
15331function createTransformProps(props = []) {
15332 return { props };
15333}
15334
15335const seen$1 = new WeakSet();
15336const transformMemo = (node, context) => {
15337 if (node.type === 1 /* ELEMENT */) {
15338 const dir = findDir(node, 'memo');
15339 if (!dir || seen$1.has(node)) {
15340 return;
15341 }
15342 seen$1.add(node);
15343 return () => {
15344 const codegenNode = node.codegenNode ||
15345 context.currentNode.codegenNode;
15346 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
15347 // non-component sub tree should be turned into a block
15348 if (node.tagType !== 1 /* COMPONENT */) {
15349 makeBlock(codegenNode, context);
15350 }
15351 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
15352 dir.exp,
15353 createFunctionExpression(undefined, codegenNode),
15354 `_cache`,
15355 String(context.cached++)
15356 ]);
15357 }
15358 };
15359 }
15360};
15361
15362function getBaseTransformPreset(prefixIdentifiers) {
15363 return [
15364 [
15365 transformOnce,
15366 transformIf,
15367 transformMemo,
15368 transformFor,
15369 ...([]),
15370 ...([transformExpression]
15371 ),
15372 transformSlotOutlet,
15373 transformElement,
15374 trackSlotScopes,
15375 transformText
15376 ],
15377 {
15378 on: transformOn,
15379 bind: transformBind,
15380 model: transformModel
15381 }
15382 ];
15383}
15384// we name it `baseCompile` so that higher order compilers like
15385// @vue/compiler-dom can export `compile` while re-exporting everything else.
15386function baseCompile(template, options = {}) {
15387 const onError = options.onError || defaultOnError;
15388 const isModuleMode = options.mode === 'module';
15389 /* istanbul ignore if */
15390 {
15391 if (options.prefixIdentifiers === true) {
15392 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));
15393 }
15394 else if (isModuleMode) {
15395 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));
15396 }
15397 }
15398 const prefixIdentifiers = !true ;
15399 if (options.cacheHandlers) {
15400 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
15401 }
15402 if (options.scopeId && !isModuleMode) {
15403 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));
15404 }
15405 const ast = isString(template) ? baseParse(template, options) : template;
15406 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
15407 transform(ast, extend({}, options, {
15408 prefixIdentifiers,
15409 nodeTransforms: [
15410 ...nodeTransforms,
15411 ...(options.nodeTransforms || []) // user transforms
15412 ],
15413 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
15414 )
15415 }));
15416 return generate(ast, extend({}, options, {
15417 prefixIdentifiers
15418 }));
15419}
15420
15421const noopDirectiveTransform = () => ({ props: [] });
15422
15423const V_MODEL_RADIO = Symbol(`vModelRadio` );
15424const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
15425const V_MODEL_TEXT = Symbol(`vModelText` );
15426const V_MODEL_SELECT = Symbol(`vModelSelect` );
15427const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
15428const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
15429const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
15430const V_SHOW = Symbol(`vShow` );
15431const TRANSITION$1 = Symbol(`Transition` );
15432const TRANSITION_GROUP = Symbol(`TransitionGroup` );
15433registerRuntimeHelpers({
15434 [V_MODEL_RADIO]: `vModelRadio`,
15435 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
15436 [V_MODEL_TEXT]: `vModelText`,
15437 [V_MODEL_SELECT]: `vModelSelect`,
15438 [V_MODEL_DYNAMIC]: `vModelDynamic`,
15439 [V_ON_WITH_MODIFIERS]: `withModifiers`,
15440 [V_ON_WITH_KEYS]: `withKeys`,
15441 [V_SHOW]: `vShow`,
15442 [TRANSITION$1]: `Transition`,
15443 [TRANSITION_GROUP]: `TransitionGroup`
15444});
15445
15446/* eslint-disable no-restricted-globals */
15447let decoder;
15448function decodeHtmlBrowser(raw, asAttr = false) {
15449 if (!decoder) {
15450 decoder = document.createElement('div');
15451 }
15452 if (asAttr) {
15453 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
15454 return decoder.children[0].getAttribute('foo');
15455 }
15456 else {
15457 decoder.innerHTML = raw;
15458 return decoder.textContent;
15459 }
15460}
15461
15462const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
15463const parserOptions = {
15464 isVoidTag,
15465 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
15466 isPreTag: tag => tag === 'pre',
15467 decodeEntities: decodeHtmlBrowser ,
15468 isBuiltInComponent: (tag) => {
15469 if (isBuiltInType(tag, `Transition`)) {
15470 return TRANSITION$1;
15471 }
15472 else if (isBuiltInType(tag, `TransitionGroup`)) {
15473 return TRANSITION_GROUP;
15474 }
15475 },
15476 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
15477 getNamespace(tag, parent) {
15478 let ns = parent ? parent.ns : 0 /* HTML */;
15479 if (parent && ns === 2 /* MATH_ML */) {
15480 if (parent.tag === 'annotation-xml') {
15481 if (tag === 'svg') {
15482 return 1 /* SVG */;
15483 }
15484 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
15485 a.name === 'encoding' &&
15486 a.value != null &&
15487 (a.value.content === 'text/html' ||
15488 a.value.content === 'application/xhtml+xml'))) {
15489 ns = 0 /* HTML */;
15490 }
15491 }
15492 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
15493 tag !== 'mglyph' &&
15494 tag !== 'malignmark') {
15495 ns = 0 /* HTML */;
15496 }
15497 }
15498 else if (parent && ns === 1 /* SVG */) {
15499 if (parent.tag === 'foreignObject' ||
15500 parent.tag === 'desc' ||
15501 parent.tag === 'title') {
15502 ns = 0 /* HTML */;
15503 }
15504 }
15505 if (ns === 0 /* HTML */) {
15506 if (tag === 'svg') {
15507 return 1 /* SVG */;
15508 }
15509 if (tag === 'math') {
15510 return 2 /* MATH_ML */;
15511 }
15512 }
15513 return ns;
15514 },
15515 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
15516 getTextMode({ tag, ns }) {
15517 if (ns === 0 /* HTML */) {
15518 if (tag === 'textarea' || tag === 'title') {
15519 return 1 /* RCDATA */;
15520 }
15521 if (isRawTextContainer(tag)) {
15522 return 2 /* RAWTEXT */;
15523 }
15524 }
15525 return 0 /* DATA */;
15526 }
15527};
15528
15529// Parse inline CSS strings for static style attributes into an object.
15530// This is a NodeTransform since it works on the static `style` attribute and
15531// converts it into a dynamic equivalent:
15532// style="color: red" -> :style='{ "color": "red" }'
15533// It is then processed by `transformElement` and included in the generated
15534// props.
15535const transformStyle = node => {
15536 if (node.type === 1 /* ELEMENT */) {
15537 node.props.forEach((p, i) => {
15538 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
15539 // replace p with an expression node
15540 node.props[i] = {
15541 type: 7 /* DIRECTIVE */,
15542 name: `bind`,
15543 arg: createSimpleExpression(`style`, true, p.loc),
15544 exp: parseInlineCSS(p.value.content, p.loc),
15545 modifiers: [],
15546 loc: p.loc
15547 };
15548 }
15549 });
15550 }
15551};
15552const parseInlineCSS = (cssText, loc) => {
15553 const normalized = parseStringStyle(cssText);
15554 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
15555};
15556
15557function createDOMCompilerError(code, loc) {
15558 return createCompilerError(code, loc, DOMErrorMessages );
15559}
15560const DOMErrorMessages = {
15561 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
15562 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
15563 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
15564 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
15565 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
15566 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
15567 [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
15568 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
15569 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
15570 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
15571 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
15572};
15573
15574const transformVHtml = (dir, node, context) => {
15575 const { exp, loc } = dir;
15576 if (!exp) {
15577 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));
15578 }
15579 if (node.children.length) {
15580 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));
15581 node.children.length = 0;
15582 }
15583 return {
15584 props: [
15585 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
15586 ]
15587 };
15588};
15589
15590const transformVText = (dir, node, context) => {
15591 const { exp, loc } = dir;
15592 if (!exp) {
15593 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));
15594 }
15595 if (node.children.length) {
15596 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));
15597 node.children.length = 0;
15598 }
15599 return {
15600 props: [
15601 createObjectProperty(createSimpleExpression(`textContent`, true), exp
15602 ? getConstantType(exp, context) > 0
15603 ? exp
15604 : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
15605 : createSimpleExpression('', true))
15606 ]
15607 };
15608};
15609
15610const transformModel$1 = (dir, node, context) => {
15611 const baseResult = transformModel(dir, node, context);
15612 // base transform has errors OR component v-model (only need props)
15613 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
15614 return baseResult;
15615 }
15616 if (dir.arg) {
15617 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
15618 }
15619 function checkDuplicatedValue() {
15620 const value = findProp(node, 'value');
15621 if (value) {
15622 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
15623 }
15624 }
15625 const { tag } = node;
15626 const isCustomElement = context.isCustomElement(tag);
15627 if (tag === 'input' ||
15628 tag === 'textarea' ||
15629 tag === 'select' ||
15630 isCustomElement) {
15631 let directiveToUse = V_MODEL_TEXT;
15632 let isInvalidType = false;
15633 if (tag === 'input' || isCustomElement) {
15634 const type = findProp(node, `type`);
15635 if (type) {
15636 if (type.type === 7 /* DIRECTIVE */) {
15637 // :type="foo"
15638 directiveToUse = V_MODEL_DYNAMIC;
15639 }
15640 else if (type.value) {
15641 switch (type.value.content) {
15642 case 'radio':
15643 directiveToUse = V_MODEL_RADIO;
15644 break;
15645 case 'checkbox':
15646 directiveToUse = V_MODEL_CHECKBOX;
15647 break;
15648 case 'file':
15649 isInvalidType = true;
15650 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
15651 break;
15652 default:
15653 // text type
15654 checkDuplicatedValue();
15655 break;
15656 }
15657 }
15658 }
15659 else if (hasDynamicKeyVBind(node)) {
15660 // element has bindings with dynamic keys, which can possibly contain
15661 // "type".
15662 directiveToUse = V_MODEL_DYNAMIC;
15663 }
15664 else {
15665 // text type
15666 checkDuplicatedValue();
15667 }
15668 }
15669 else if (tag === 'select') {
15670 directiveToUse = V_MODEL_SELECT;
15671 }
15672 else {
15673 // textarea
15674 checkDuplicatedValue();
15675 }
15676 // inject runtime directive
15677 // by returning the helper symbol via needRuntime
15678 // the import will replaced a resolveDirective call.
15679 if (!isInvalidType) {
15680 baseResult.needRuntime = context.helper(directiveToUse);
15681 }
15682 }
15683 else {
15684 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
15685 }
15686 // native vmodel doesn't need the `modelValue` props since they are also
15687 // passed to the runtime as `binding.value`. removing it reduces code size.
15688 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
15689 p.key.content === 'modelValue'));
15690 return baseResult;
15691};
15692
15693const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
15694const isNonKeyModifier = /*#__PURE__*/ makeMap(
15695// event propagation management
15696`stop,prevent,self,` +
15697 // system modifiers + exact
15698 `ctrl,shift,alt,meta,exact,` +
15699 // mouse
15700 `middle`);
15701// left & right could be mouse or key modifiers based on event type
15702const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
15703const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
15704const resolveModifiers = (key, modifiers, context, loc) => {
15705 const keyModifiers = [];
15706 const nonKeyModifiers = [];
15707 const eventOptionModifiers = [];
15708 for (let i = 0; i < modifiers.length; i++) {
15709 const modifier = modifiers[i];
15710 if (isEventOptionModifier(modifier)) {
15711 // eventOptionModifiers: modifiers for addEventListener() options,
15712 // e.g. .passive & .capture
15713 eventOptionModifiers.push(modifier);
15714 }
15715 else {
15716 // runtimeModifiers: modifiers that needs runtime guards
15717 if (maybeKeyModifier(modifier)) {
15718 if (isStaticExp(key)) {
15719 if (isKeyboardEvent(key.content)) {
15720 keyModifiers.push(modifier);
15721 }
15722 else {
15723 nonKeyModifiers.push(modifier);
15724 }
15725 }
15726 else {
15727 keyModifiers.push(modifier);
15728 nonKeyModifiers.push(modifier);
15729 }
15730 }
15731 else {
15732 if (isNonKeyModifier(modifier)) {
15733 nonKeyModifiers.push(modifier);
15734 }
15735 else {
15736 keyModifiers.push(modifier);
15737 }
15738 }
15739 }
15740 }
15741 return {
15742 keyModifiers,
15743 nonKeyModifiers,
15744 eventOptionModifiers
15745 };
15746};
15747const transformClick = (key, event) => {
15748 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
15749 return isStaticClick
15750 ? createSimpleExpression(event, true)
15751 : key.type !== 4 /* SIMPLE_EXPRESSION */
15752 ? createCompoundExpression([
15753 `(`,
15754 key,
15755 `) === "onClick" ? "${event}" : (`,
15756 key,
15757 `)`
15758 ])
15759 : key;
15760};
15761const transformOn$1 = (dir, node, context) => {
15762 return transformOn(dir, node, context, baseResult => {
15763 const { modifiers } = dir;
15764 if (!modifiers.length)
15765 return baseResult;
15766 let { key, value: handlerExp } = baseResult.props[0];
15767 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
15768 // normalize click.right and click.middle since they don't actually fire
15769 if (nonKeyModifiers.includes('right')) {
15770 key = transformClick(key, `onContextmenu`);
15771 }
15772 if (nonKeyModifiers.includes('middle')) {
15773 key = transformClick(key, `onMouseup`);
15774 }
15775 if (nonKeyModifiers.length) {
15776 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
15777 handlerExp,
15778 JSON.stringify(nonKeyModifiers)
15779 ]);
15780 }
15781 if (keyModifiers.length &&
15782 // if event name is dynamic, always wrap with keys guard
15783 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
15784 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
15785 handlerExp,
15786 JSON.stringify(keyModifiers)
15787 ]);
15788 }
15789 if (eventOptionModifiers.length) {
15790 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
15791 key = isStaticExp(key)
15792 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
15793 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
15794 }
15795 return {
15796 props: [createObjectProperty(key, handlerExp)]
15797 };
15798 });
15799};
15800
15801const transformShow = (dir, node, context) => {
15802 const { exp, loc } = dir;
15803 if (!exp) {
15804 context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc));
15805 }
15806 return {
15807 props: [],
15808 needRuntime: context.helper(V_SHOW)
15809 };
15810};
15811
15812const transformTransition = (node, context) => {
15813 if (node.type === 1 /* ELEMENT */ &&
15814 node.tagType === 1 /* COMPONENT */) {
15815 const component = context.isBuiltInComponent(node.tag);
15816 if (component === TRANSITION$1) {
15817 return () => {
15818 if (!node.children.length) {
15819 return;
15820 }
15821 // warn multiple transition children
15822 if (hasMultipleChildren(node)) {
15823 context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
15824 start: node.children[0].loc.start,
15825 end: node.children[node.children.length - 1].loc.end,
15826 source: ''
15827 }));
15828 }
15829 // check if it's s single child w/ v-show
15830 // if yes, inject "persisted: true" to the transition props
15831 const child = node.children[0];
15832 if (child.type === 1 /* ELEMENT */) {
15833 for (const p of child.props) {
15834 if (p.type === 7 /* DIRECTIVE */ && p.name === 'show') {
15835 node.props.push({
15836 type: 6 /* ATTRIBUTE */,
15837 name: 'persisted',
15838 value: undefined,
15839 loc: node.loc
15840 });
15841 }
15842 }
15843 }
15844 };
15845 }
15846 }
15847};
15848function hasMultipleChildren(node) {
15849 // #1352 filter out potential comment nodes.
15850 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ &&
15851 !(c.type === 2 /* TEXT */ && !c.content.trim())));
15852 const child = children[0];
15853 return (children.length !== 1 ||
15854 child.type === 11 /* FOR */ ||
15855 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
15856}
15857
15858const ignoreSideEffectTags = (node, context) => {
15859 if (node.type === 1 /* ELEMENT */ &&
15860 node.tagType === 0 /* ELEMENT */ &&
15861 (node.tag === 'script' || node.tag === 'style')) {
15862 context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
15863 context.removeNode();
15864 }
15865};
15866
15867const DOMNodeTransforms = [
15868 transformStyle,
15869 ...([transformTransition] )
15870];
15871const DOMDirectiveTransforms = {
15872 cloak: noopDirectiveTransform,
15873 html: transformVHtml,
15874 text: transformVText,
15875 model: transformModel$1,
15876 on: transformOn$1,
15877 show: transformShow
15878};
15879function compile$1(template, options = {}) {
15880 return baseCompile(template, extend({}, parserOptions, options, {
15881 nodeTransforms: [
15882 // ignore <script> and <tag>
15883 // this is not put inside DOMNodeTransforms because that list is used
15884 // by compiler-ssr to generate vnode fallback branches
15885 ignoreSideEffectTags,
15886 ...DOMNodeTransforms,
15887 ...(options.nodeTransforms || [])
15888 ],
15889 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
15890 transformHoist: null
15891 }));
15892}
15893
15894// This entry is the "full-build" that includes both the runtime
15895{
15896 initDev();
15897}
15898const compileCache = Object.create(null);
15899function compileToFunction(template, options) {
15900 if (!isString(template)) {
15901 if (template.nodeType) {
15902 template = template.innerHTML;
15903 }
15904 else {
15905 warn$1(`invalid template option: `, template);
15906 return NOOP;
15907 }
15908 }
15909 const key = template;
15910 const cached = compileCache[key];
15911 if (cached) {
15912 return cached;
15913 }
15914 if (template[0] === '#') {
15915 const el = document.querySelector(template);
15916 if (!el) {
15917 warn$1(`Template element not found or is empty: ${template}`);
15918 }
15919 // __UNSAFE__
15920 // Reason: potential execution of JS expressions in in-DOM template.
15921 // The user must make sure the in-DOM template is trusted. If it's rendered
15922 // by the server, the template should not contain any user data.
15923 template = el ? el.innerHTML : ``;
15924 }
15925 const { code } = compile$1(template, extend({
15926 hoistStatic: true,
15927 onError: onError ,
15928 onWarn: e => onError(e, true)
15929 }, options));
15930 function onError(err, asWarning = false) {
15931 const message = asWarning
15932 ? err.message
15933 : `Template compilation error: ${err.message}`;
15934 const codeFrame = err.loc &&
15935 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
15936 warn$1(codeFrame ? `${message}\n${codeFrame}` : message);
15937 }
15938 // The wildcard import results in a huge object with every export
15939 // with keys that cannot be mangled, and can be quite heavy size-wise.
15940 // In the global build we know `Vue` is available globally so we can avoid
15941 // the wildcard object.
15942 const render = (new Function('Vue', code)(runtimeDom));
15943 render._rc = true;
15944 return (compileCache[key] = render);
15945}
15946registerRuntimeCompiler(compileToFunction);
15947
15948export { BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compileToFunction as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createElementBlock, createBaseVNode as createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isShallow, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId };