UNPKG

562 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 const lines = source.split(/\r?\n/);
54 let count = 0;
55 const res = [];
56 for (let i = 0; i < lines.length; i++) {
57 count += lines[i].length + 1;
58 if (count >= start) {
59 for (let j = i - range; j <= i + range || end > count; j++) {
60 if (j < 0 || j >= lines.length)
61 continue;
62 const line = j + 1;
63 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
64 const lineLength = lines[j].length;
65 if (j === i) {
66 // push underline
67 const pad = start - (count - lineLength) + 1;
68 const length = Math.max(1, end > count ? lineLength - pad : end - start);
69 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
70 }
71 else if (j > i) {
72 if (end > count) {
73 const length = Math.max(Math.min(end - count, lineLength), 1);
74 res.push(` | ` + '^'.repeat(length));
75 }
76 count += lineLength + 1;
77 }
78 }
79 break;
80 }
81 }
82 return res.join('\n');
83}
84
85/**
86 * On the client we only need to offer special cases for boolean attributes that
87 * have different names from their corresponding dom properties:
88 * - itemscope -> N/A
89 * - allowfullscreen -> allowFullscreen
90 * - formnovalidate -> formNoValidate
91 * - ismap -> isMap
92 * - nomodule -> noModule
93 * - novalidate -> noValidate
94 * - readonly -> readOnly
95 */
96const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
97const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
98
99function normalizeStyle(value) {
100 if (isArray(value)) {
101 const res = {};
102 for (let i = 0; i < value.length; i++) {
103 const item = value[i];
104 const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item);
105 if (normalized) {
106 for (const key in normalized) {
107 res[key] = normalized[key];
108 }
109 }
110 }
111 return res;
112 }
113 else if (isObject(value)) {
114 return value;
115 }
116}
117const listDelimiterRE = /;(?![^(]*\))/g;
118const propertyDelimiterRE = /:(.+)/;
119function parseStringStyle(cssText) {
120 const ret = {};
121 cssText.split(listDelimiterRE).forEach(item => {
122 if (item) {
123 const tmp = item.split(propertyDelimiterRE);
124 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
125 }
126 });
127 return ret;
128}
129function normalizeClass(value) {
130 let res = '';
131 if (isString(value)) {
132 res = value;
133 }
134 else if (isArray(value)) {
135 for (let i = 0; i < value.length; i++) {
136 const normalized = normalizeClass(value[i]);
137 if (normalized) {
138 res += normalized + ' ';
139 }
140 }
141 }
142 else if (isObject(value)) {
143 for (const name in value) {
144 if (value[name]) {
145 res += name + ' ';
146 }
147 }
148 }
149 return res.trim();
150}
151
152// These tag configs are shared between compiler-dom and runtime-dom, so they
153// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
154const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
155 'header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,' +
156 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
157 'data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,' +
158 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
159 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
160 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
161 'option,output,progress,select,textarea,details,dialog,menu,' +
162 'summary,template,blockquote,iframe,tfoot';
163// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
164const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
165 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
166 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
167 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
168 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
169 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
170 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
171 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
172 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
173 'text,textPath,title,tspan,unknown,use,view';
174const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
175const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
176const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
177const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
178
179function looseCompareArrays(a, b) {
180 if (a.length !== b.length)
181 return false;
182 let equal = true;
183 for (let i = 0; equal && i < a.length; i++) {
184 equal = looseEqual(a[i], b[i]);
185 }
186 return equal;
187}
188function looseEqual(a, b) {
189 if (a === b)
190 return true;
191 let aValidType = isDate(a);
192 let bValidType = isDate(b);
193 if (aValidType || bValidType) {
194 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
195 }
196 aValidType = isArray(a);
197 bValidType = isArray(b);
198 if (aValidType || bValidType) {
199 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
200 }
201 aValidType = isObject(a);
202 bValidType = isObject(b);
203 if (aValidType || bValidType) {
204 /* istanbul ignore if: this if will probably never be called */
205 if (!aValidType || !bValidType) {
206 return false;
207 }
208 const aKeysCount = Object.keys(a).length;
209 const bKeysCount = Object.keys(b).length;
210 if (aKeysCount !== bKeysCount) {
211 return false;
212 }
213 for (const key in a) {
214 const aHasKey = a.hasOwnProperty(key);
215 const bHasKey = b.hasOwnProperty(key);
216 if ((aHasKey && !bHasKey) ||
217 (!aHasKey && bHasKey) ||
218 !looseEqual(a[key], b[key])) {
219 return false;
220 }
221 }
222 }
223 return String(a) === String(b);
224}
225function looseIndexOf(arr, val) {
226 return arr.findIndex(item => looseEqual(item, val));
227}
228
229/**
230 * For converting {{ interpolation }} values to displayed strings.
231 * @private
232 */
233const toDisplayString = (val) => {
234 return val == null
235 ? ''
236 : isObject(val)
237 ? JSON.stringify(val, replacer, 2)
238 : String(val);
239};
240const replacer = (_key, val) => {
241 if (isMap(val)) {
242 return {
243 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
244 entries[`${key} =>`] = val;
245 return entries;
246 }, {})
247 };
248 }
249 else if (isSet(val)) {
250 return {
251 [`Set(${val.size})`]: [...val.values()]
252 };
253 }
254 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
255 return String(val);
256 }
257 return val;
258};
259
260const EMPTY_OBJ = Object.freeze({})
261 ;
262const EMPTY_ARR = Object.freeze([]) ;
263const NOOP = () => { };
264/**
265 * Always return false.
266 */
267const NO = () => false;
268const onRE = /^on[^a-z]/;
269const isOn = (key) => onRE.test(key);
270const isModelListener = (key) => key.startsWith('onUpdate:');
271const extend = Object.assign;
272const remove = (arr, el) => {
273 const i = arr.indexOf(el);
274 if (i > -1) {
275 arr.splice(i, 1);
276 }
277};
278const hasOwnProperty = Object.prototype.hasOwnProperty;
279const hasOwn = (val, key) => hasOwnProperty.call(val, key);
280const isArray = Array.isArray;
281const isMap = (val) => toTypeString(val) === '[object Map]';
282const isSet = (val) => toTypeString(val) === '[object Set]';
283const isDate = (val) => val instanceof Date;
284const isFunction = (val) => typeof val === 'function';
285const isString = (val) => typeof val === 'string';
286const isSymbol = (val) => typeof val === 'symbol';
287const isObject = (val) => val !== null && typeof val === 'object';
288const isPromise = (val) => {
289 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
290};
291const objectToString = Object.prototype.toString;
292const toTypeString = (value) => objectToString.call(value);
293const toRawType = (value) => {
294 // extract "RawType" from strings like "[object RawType]"
295 return toTypeString(value).slice(8, -1);
296};
297const isPlainObject = (val) => toTypeString(val) === '[object Object]';
298const isIntegerKey = (key) => isString(key) &&
299 key !== 'NaN' &&
300 key[0] !== '-' &&
301 '' + parseInt(key, 10) === key;
302const isReservedProp = /*#__PURE__*/ makeMap(
303// the leading comma is intentional so empty string "" is also included
304',key,ref,' +
305 'onVnodeBeforeMount,onVnodeMounted,' +
306 'onVnodeBeforeUpdate,onVnodeUpdated,' +
307 'onVnodeBeforeUnmount,onVnodeUnmounted');
308const cacheStringFunction = (fn) => {
309 const cache = Object.create(null);
310 return ((str) => {
311 const hit = cache[str];
312 return hit || (cache[str] = fn(str));
313 });
314};
315const camelizeRE = /-(\w)/g;
316/**
317 * @private
318 */
319const camelize = cacheStringFunction((str) => {
320 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
321});
322const hyphenateRE = /\B([A-Z])/g;
323/**
324 * @private
325 */
326const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
327/**
328 * @private
329 */
330const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
331/**
332 * @private
333 */
334const toHandlerKey = cacheStringFunction((str) => (str ? `on${capitalize(str)}` : ``));
335// compare whether a value has changed, accounting for NaN.
336const hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue);
337const invokeArrayFns = (fns, arg) => {
338 for (let i = 0; i < fns.length; i++) {
339 fns[i](arg);
340 }
341};
342const def = (obj, key, value) => {
343 Object.defineProperty(obj, key, {
344 configurable: true,
345 enumerable: false,
346 value
347 });
348};
349const toNumber = (val) => {
350 const n = parseFloat(val);
351 return isNaN(n) ? val : n;
352};
353let _globalThis;
354const getGlobalThis = () => {
355 return (_globalThis ||
356 (_globalThis =
357 typeof globalThis !== 'undefined'
358 ? globalThis
359 : typeof self !== 'undefined'
360 ? self
361 : typeof window !== 'undefined'
362 ? window
363 : typeof global !== 'undefined'
364 ? global
365 : {}));
366};
367
368const targetMap = new WeakMap();
369const effectStack = [];
370let activeEffect;
371const ITERATE_KEY = Symbol('iterate' );
372const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
373function isEffect(fn) {
374 return fn && fn._isEffect === true;
375}
376function effect(fn, options = EMPTY_OBJ) {
377 if (isEffect(fn)) {
378 fn = fn.raw;
379 }
380 const effect = createReactiveEffect(fn, options);
381 if (!options.lazy) {
382 effect();
383 }
384 return effect;
385}
386function stop(effect) {
387 if (effect.active) {
388 cleanup(effect);
389 if (effect.options.onStop) {
390 effect.options.onStop();
391 }
392 effect.active = false;
393 }
394}
395let uid = 0;
396function createReactiveEffect(fn, options) {
397 const effect = function reactiveEffect() {
398 if (!effect.active) {
399 return fn();
400 }
401 if (!effectStack.includes(effect)) {
402 cleanup(effect);
403 try {
404 enableTracking();
405 effectStack.push(effect);
406 activeEffect = effect;
407 return fn();
408 }
409 finally {
410 effectStack.pop();
411 resetTracking();
412 activeEffect = effectStack[effectStack.length - 1];
413 }
414 }
415 };
416 effect.id = uid++;
417 effect.allowRecurse = !!options.allowRecurse;
418 effect._isEffect = true;
419 effect.active = true;
420 effect.raw = fn;
421 effect.deps = [];
422 effect.options = options;
423 return effect;
424}
425function cleanup(effect) {
426 const { deps } = effect;
427 if (deps.length) {
428 for (let i = 0; i < deps.length; i++) {
429 deps[i].delete(effect);
430 }
431 deps.length = 0;
432 }
433}
434let shouldTrack = true;
435const trackStack = [];
436function pauseTracking() {
437 trackStack.push(shouldTrack);
438 shouldTrack = false;
439}
440function enableTracking() {
441 trackStack.push(shouldTrack);
442 shouldTrack = true;
443}
444function resetTracking() {
445 const last = trackStack.pop();
446 shouldTrack = last === undefined ? true : last;
447}
448function track(target, type, key) {
449 if (!shouldTrack || activeEffect === undefined) {
450 return;
451 }
452 let depsMap = targetMap.get(target);
453 if (!depsMap) {
454 targetMap.set(target, (depsMap = new Map()));
455 }
456 let dep = depsMap.get(key);
457 if (!dep) {
458 depsMap.set(key, (dep = new Set()));
459 }
460 if (!dep.has(activeEffect)) {
461 dep.add(activeEffect);
462 activeEffect.deps.push(dep);
463 if (activeEffect.options.onTrack) {
464 activeEffect.options.onTrack({
465 effect: activeEffect,
466 target,
467 type,
468 key
469 });
470 }
471 }
472}
473function trigger(target, type, key, newValue, oldValue, oldTarget) {
474 const depsMap = targetMap.get(target);
475 if (!depsMap) {
476 // never been tracked
477 return;
478 }
479 const effects = new Set();
480 const add = (effectsToAdd) => {
481 if (effectsToAdd) {
482 effectsToAdd.forEach(effect => {
483 if (effect !== activeEffect || effect.allowRecurse) {
484 effects.add(effect);
485 }
486 });
487 }
488 };
489 if (type === "clear" /* CLEAR */) {
490 // collection being cleared
491 // trigger all effects for target
492 depsMap.forEach(add);
493 }
494 else if (key === 'length' && isArray(target)) {
495 depsMap.forEach((dep, key) => {
496 if (key === 'length' || key >= newValue) {
497 add(dep);
498 }
499 });
500 }
501 else {
502 // schedule runs for SET | ADD | DELETE
503 if (key !== void 0) {
504 add(depsMap.get(key));
505 }
506 // also run for iteration key on ADD | DELETE | Map.SET
507 switch (type) {
508 case "add" /* ADD */:
509 if (!isArray(target)) {
510 add(depsMap.get(ITERATE_KEY));
511 if (isMap(target)) {
512 add(depsMap.get(MAP_KEY_ITERATE_KEY));
513 }
514 }
515 else if (isIntegerKey(key)) {
516 // new index added to array -> length changes
517 add(depsMap.get('length'));
518 }
519 break;
520 case "delete" /* DELETE */:
521 if (!isArray(target)) {
522 add(depsMap.get(ITERATE_KEY));
523 if (isMap(target)) {
524 add(depsMap.get(MAP_KEY_ITERATE_KEY));
525 }
526 }
527 break;
528 case "set" /* SET */:
529 if (isMap(target)) {
530 add(depsMap.get(ITERATE_KEY));
531 }
532 break;
533 }
534 }
535 const run = (effect) => {
536 if (effect.options.onTrigger) {
537 effect.options.onTrigger({
538 effect,
539 target,
540 key,
541 type,
542 newValue,
543 oldValue,
544 oldTarget
545 });
546 }
547 if (effect.options.scheduler) {
548 effect.options.scheduler(effect);
549 }
550 else {
551 effect();
552 }
553 };
554 effects.forEach(run);
555}
556
557const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
558const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
559 .map(key => Symbol[key])
560 .filter(isSymbol));
561const get = /*#__PURE__*/ createGetter();
562const shallowGet = /*#__PURE__*/ createGetter(false, true);
563const readonlyGet = /*#__PURE__*/ createGetter(true);
564const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
565const arrayInstrumentations = {};
566['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
567 const method = Array.prototype[key];
568 arrayInstrumentations[key] = function (...args) {
569 const arr = toRaw(this);
570 for (let i = 0, l = this.length; i < l; i++) {
571 track(arr, "get" /* GET */, i + '');
572 }
573 // we run the method using the original args first (which may be reactive)
574 const res = method.apply(arr, args);
575 if (res === -1 || res === false) {
576 // if that didn't work, run it again using raw values.
577 return method.apply(arr, args.map(toRaw));
578 }
579 else {
580 return res;
581 }
582 };
583});
584['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
585 const method = Array.prototype[key];
586 arrayInstrumentations[key] = function (...args) {
587 pauseTracking();
588 const res = method.apply(this, args);
589 resetTracking();
590 return res;
591 };
592});
593function createGetter(isReadonly = false, shallow = false) {
594 return function get(target, key, receiver) {
595 if (key === "__v_isReactive" /* IS_REACTIVE */) {
596 return !isReadonly;
597 }
598 else if (key === "__v_isReadonly" /* IS_READONLY */) {
599 return isReadonly;
600 }
601 else if (key === "__v_raw" /* RAW */ &&
602 receiver ===
603 (isReadonly
604 ? shallow
605 ? shallowReadonlyMap
606 : readonlyMap
607 : shallow
608 ? shallowReactiveMap
609 : reactiveMap).get(target)) {
610 return target;
611 }
612 const targetIsArray = isArray(target);
613 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
614 return Reflect.get(arrayInstrumentations, key, receiver);
615 }
616 const res = Reflect.get(target, key, receiver);
617 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
618 return res;
619 }
620 if (!isReadonly) {
621 track(target, "get" /* GET */, key);
622 }
623 if (shallow) {
624 return res;
625 }
626 if (isRef(res)) {
627 // ref unwrapping - does not apply for Array + integer key.
628 const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
629 return shouldUnwrap ? res.value : res;
630 }
631 if (isObject(res)) {
632 // Convert returned value into a proxy as well. we do the isObject check
633 // here to avoid invalid value warning. Also need to lazy access readonly
634 // and reactive here to avoid circular dependency.
635 return isReadonly ? readonly(res) : reactive(res);
636 }
637 return res;
638 };
639}
640const set = /*#__PURE__*/ createSetter();
641const shallowSet = /*#__PURE__*/ createSetter(true);
642function createSetter(shallow = false) {
643 return function set(target, key, value, receiver) {
644 let oldValue = target[key];
645 if (!shallow) {
646 value = toRaw(value);
647 oldValue = toRaw(oldValue);
648 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
649 oldValue.value = value;
650 return true;
651 }
652 }
653 const hadKey = isArray(target) && isIntegerKey(key)
654 ? Number(key) < target.length
655 : hasOwn(target, key);
656 const result = Reflect.set(target, key, value, receiver);
657 // don't trigger if target is something up in the prototype chain of original
658 if (target === toRaw(receiver)) {
659 if (!hadKey) {
660 trigger(target, "add" /* ADD */, key, value);
661 }
662 else if (hasChanged(value, oldValue)) {
663 trigger(target, "set" /* SET */, key, value, oldValue);
664 }
665 }
666 return result;
667 };
668}
669function deleteProperty(target, key) {
670 const hadKey = hasOwn(target, key);
671 const oldValue = target[key];
672 const result = Reflect.deleteProperty(target, key);
673 if (result && hadKey) {
674 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
675 }
676 return result;
677}
678function has(target, key) {
679 const result = Reflect.has(target, key);
680 if (!isSymbol(key) || !builtInSymbols.has(key)) {
681 track(target, "has" /* HAS */, key);
682 }
683 return result;
684}
685function ownKeys(target) {
686 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
687 return Reflect.ownKeys(target);
688}
689const mutableHandlers = {
690 get,
691 set,
692 deleteProperty,
693 has,
694 ownKeys
695};
696const readonlyHandlers = {
697 get: readonlyGet,
698 set(target, key) {
699 {
700 console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
701 }
702 return true;
703 },
704 deleteProperty(target, key) {
705 {
706 console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
707 }
708 return true;
709 }
710};
711const shallowReactiveHandlers = extend({}, mutableHandlers, {
712 get: shallowGet,
713 set: shallowSet
714});
715// Props handlers are special in the sense that it should not unwrap top-level
716// refs (in order to allow refs to be explicitly passed down), but should
717// retain the reactivity of the normal readonly object.
718const shallowReadonlyHandlers = extend({}, readonlyHandlers, {
719 get: shallowReadonlyGet
720});
721
722const toReactive = (value) => isObject(value) ? reactive(value) : value;
723const toReadonly = (value) => isObject(value) ? readonly(value) : value;
724const toShallow = (value) => value;
725const getProto = (v) => Reflect.getPrototypeOf(v);
726function get$1(target, key, isReadonly = false, isShallow = false) {
727 // #1772: readonly(reactive(Map)) should return readonly + reactive version
728 // of the value
729 target = target["__v_raw" /* RAW */];
730 const rawTarget = toRaw(target);
731 const rawKey = toRaw(key);
732 if (key !== rawKey) {
733 !isReadonly && track(rawTarget, "get" /* GET */, key);
734 }
735 !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
736 const { has } = getProto(rawTarget);
737 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
738 if (has.call(rawTarget, key)) {
739 return wrap(target.get(key));
740 }
741 else if (has.call(rawTarget, rawKey)) {
742 return wrap(target.get(rawKey));
743 }
744 else if (target !== rawTarget) {
745 // #3602 readonly(reactive(Map))
746 // ensure that the nested reactive `Map` can do tracking for itself
747 target.get(key);
748 }
749}
750function has$1(key, isReadonly = false) {
751 const target = this["__v_raw" /* RAW */];
752 const rawTarget = toRaw(target);
753 const rawKey = toRaw(key);
754 if (key !== rawKey) {
755 !isReadonly && track(rawTarget, "has" /* HAS */, key);
756 }
757 !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
758 return key === rawKey
759 ? target.has(key)
760 : target.has(key) || target.has(rawKey);
761}
762function size(target, isReadonly = false) {
763 target = target["__v_raw" /* RAW */];
764 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
765 return Reflect.get(target, 'size', target);
766}
767function add(value) {
768 value = toRaw(value);
769 const target = toRaw(this);
770 const proto = getProto(target);
771 const hadKey = proto.has.call(target, value);
772 if (!hadKey) {
773 target.add(value);
774 trigger(target, "add" /* ADD */, value, value);
775 }
776 return this;
777}
778function set$1(key, value) {
779 value = toRaw(value);
780 const target = toRaw(this);
781 const { has, get } = getProto(target);
782 let hadKey = has.call(target, key);
783 if (!hadKey) {
784 key = toRaw(key);
785 hadKey = has.call(target, key);
786 }
787 else {
788 checkIdentityKeys(target, has, key);
789 }
790 const oldValue = get.call(target, key);
791 target.set(key, value);
792 if (!hadKey) {
793 trigger(target, "add" /* ADD */, key, value);
794 }
795 else if (hasChanged(value, oldValue)) {
796 trigger(target, "set" /* SET */, key, value, oldValue);
797 }
798 return this;
799}
800function deleteEntry(key) {
801 const target = toRaw(this);
802 const { has, get } = getProto(target);
803 let hadKey = has.call(target, key);
804 if (!hadKey) {
805 key = toRaw(key);
806 hadKey = has.call(target, key);
807 }
808 else {
809 checkIdentityKeys(target, has, key);
810 }
811 const oldValue = get ? get.call(target, key) : undefined;
812 // forward the operation before queueing reactions
813 const result = target.delete(key);
814 if (hadKey) {
815 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
816 }
817 return result;
818}
819function clear() {
820 const target = toRaw(this);
821 const hadItems = target.size !== 0;
822 const oldTarget = isMap(target)
823 ? new Map(target)
824 : new Set(target)
825 ;
826 // forward the operation before queueing reactions
827 const result = target.clear();
828 if (hadItems) {
829 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
830 }
831 return result;
832}
833function createForEach(isReadonly, isShallow) {
834 return function forEach(callback, thisArg) {
835 const observed = this;
836 const target = observed["__v_raw" /* RAW */];
837 const rawTarget = toRaw(target);
838 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
839 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
840 return target.forEach((value, key) => {
841 // important: make sure the callback is
842 // 1. invoked with the reactive map as `this` and 3rd arg
843 // 2. the value received should be a corresponding reactive/readonly.
844 return callback.call(thisArg, wrap(value), wrap(key), observed);
845 });
846 };
847}
848function createIterableMethod(method, isReadonly, isShallow) {
849 return function (...args) {
850 const target = this["__v_raw" /* RAW */];
851 const rawTarget = toRaw(target);
852 const targetIsMap = isMap(rawTarget);
853 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
854 const isKeyOnly = method === 'keys' && targetIsMap;
855 const innerIterator = target[method](...args);
856 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
857 !isReadonly &&
858 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
859 // return a wrapped iterator which returns observed versions of the
860 // values emitted from the real iterator
861 return {
862 // iterator protocol
863 next() {
864 const { value, done } = innerIterator.next();
865 return done
866 ? { value, done }
867 : {
868 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
869 done
870 };
871 },
872 // iterable protocol
873 [Symbol.iterator]() {
874 return this;
875 }
876 };
877 };
878}
879function createReadonlyMethod(type) {
880 return function (...args) {
881 {
882 const key = args[0] ? `on key "${args[0]}" ` : ``;
883 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
884 }
885 return type === "delete" /* DELETE */ ? false : this;
886 };
887}
888const mutableInstrumentations = {
889 get(key) {
890 return get$1(this, key);
891 },
892 get size() {
893 return size(this);
894 },
895 has: has$1,
896 add,
897 set: set$1,
898 delete: deleteEntry,
899 clear,
900 forEach: createForEach(false, false)
901};
902const shallowInstrumentations = {
903 get(key) {
904 return get$1(this, key, false, true);
905 },
906 get size() {
907 return size(this);
908 },
909 has: has$1,
910 add,
911 set: set$1,
912 delete: deleteEntry,
913 clear,
914 forEach: createForEach(false, true)
915};
916const readonlyInstrumentations = {
917 get(key) {
918 return get$1(this, key, true);
919 },
920 get size() {
921 return size(this, true);
922 },
923 has(key) {
924 return has$1.call(this, key, true);
925 },
926 add: createReadonlyMethod("add" /* ADD */),
927 set: createReadonlyMethod("set" /* SET */),
928 delete: createReadonlyMethod("delete" /* DELETE */),
929 clear: createReadonlyMethod("clear" /* CLEAR */),
930 forEach: createForEach(true, false)
931};
932const shallowReadonlyInstrumentations = {
933 get(key) {
934 return get$1(this, key, true, true);
935 },
936 get size() {
937 return size(this, true);
938 },
939 has(key) {
940 return has$1.call(this, key, true);
941 },
942 add: createReadonlyMethod("add" /* ADD */),
943 set: createReadonlyMethod("set" /* SET */),
944 delete: createReadonlyMethod("delete" /* DELETE */),
945 clear: createReadonlyMethod("clear" /* CLEAR */),
946 forEach: createForEach(true, true)
947};
948const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
949iteratorMethods.forEach(method => {
950 mutableInstrumentations[method] = createIterableMethod(method, false, false);
951 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
952 shallowInstrumentations[method] = createIterableMethod(method, false, true);
953 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
954});
955function createInstrumentationGetter(isReadonly, shallow) {
956 const instrumentations = shallow
957 ? isReadonly
958 ? shallowReadonlyInstrumentations
959 : shallowInstrumentations
960 : isReadonly
961 ? readonlyInstrumentations
962 : mutableInstrumentations;
963 return (target, key, receiver) => {
964 if (key === "__v_isReactive" /* IS_REACTIVE */) {
965 return !isReadonly;
966 }
967 else if (key === "__v_isReadonly" /* IS_READONLY */) {
968 return isReadonly;
969 }
970 else if (key === "__v_raw" /* RAW */) {
971 return target;
972 }
973 return Reflect.get(hasOwn(instrumentations, key) && key in target
974 ? instrumentations
975 : target, key, receiver);
976 };
977}
978const mutableCollectionHandlers = {
979 get: createInstrumentationGetter(false, false)
980};
981const shallowCollectionHandlers = {
982 get: createInstrumentationGetter(false, true)
983};
984const readonlyCollectionHandlers = {
985 get: createInstrumentationGetter(true, false)
986};
987const shallowReadonlyCollectionHandlers = {
988 get: createInstrumentationGetter(true, true)
989};
990function checkIdentityKeys(target, has, key) {
991 const rawKey = toRaw(key);
992 if (rawKey !== key && has.call(target, rawKey)) {
993 const type = toRawType(target);
994 console.warn(`Reactive ${type} contains both the raw and reactive ` +
995 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
996 `which can lead to inconsistencies. ` +
997 `Avoid differentiating between the raw and reactive versions ` +
998 `of an object and only use the reactive version if possible.`);
999 }
1000}
1001
1002const reactiveMap = new WeakMap();
1003const shallowReactiveMap = new WeakMap();
1004const readonlyMap = new WeakMap();
1005const shallowReadonlyMap = new WeakMap();
1006function targetTypeMap(rawType) {
1007 switch (rawType) {
1008 case 'Object':
1009 case 'Array':
1010 return 1 /* COMMON */;
1011 case 'Map':
1012 case 'Set':
1013 case 'WeakMap':
1014 case 'WeakSet':
1015 return 2 /* COLLECTION */;
1016 default:
1017 return 0 /* INVALID */;
1018 }
1019}
1020function getTargetType(value) {
1021 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1022 ? 0 /* INVALID */
1023 : targetTypeMap(toRawType(value));
1024}
1025function reactive(target) {
1026 // if trying to observe a readonly proxy, return the readonly version.
1027 if (target && target["__v_isReadonly" /* IS_READONLY */]) {
1028 return target;
1029 }
1030 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1031}
1032/**
1033 * Return a shallowly-reactive copy of the original object, where only the root
1034 * level properties are reactive. It also does not auto-unwrap refs (even at the
1035 * root level).
1036 */
1037function shallowReactive(target) {
1038 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1039}
1040/**
1041 * Creates a readonly copy of the original object. Note the returned copy is not
1042 * made reactive, but `readonly` can be called on an already reactive object.
1043 */
1044function readonly(target) {
1045 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1046}
1047/**
1048 * Returns a reactive-copy of the original object, where only the root level
1049 * properties are readonly, and does NOT unwrap refs nor recursively convert
1050 * returned properties.
1051 * This is used for creating the props proxy object for stateful components.
1052 */
1053function shallowReadonly(target) {
1054 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1055}
1056function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1057 if (!isObject(target)) {
1058 {
1059 console.warn(`value cannot be made reactive: ${String(target)}`);
1060 }
1061 return target;
1062 }
1063 // target is already a Proxy, return it.
1064 // exception: calling readonly() on a reactive object
1065 if (target["__v_raw" /* RAW */] &&
1066 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1067 return target;
1068 }
1069 // target already has corresponding Proxy
1070 const existingProxy = proxyMap.get(target);
1071 if (existingProxy) {
1072 return existingProxy;
1073 }
1074 // only a whitelist of value types can be observed.
1075 const targetType = getTargetType(target);
1076 if (targetType === 0 /* INVALID */) {
1077 return target;
1078 }
1079 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1080 proxyMap.set(target, proxy);
1081 return proxy;
1082}
1083function isReactive(value) {
1084 if (isReadonly(value)) {
1085 return isReactive(value["__v_raw" /* RAW */]);
1086 }
1087 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1088}
1089function isReadonly(value) {
1090 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1091}
1092function isProxy(value) {
1093 return isReactive(value) || isReadonly(value);
1094}
1095function toRaw(observed) {
1096 return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed);
1097}
1098function markRaw(value) {
1099 def(value, "__v_skip" /* SKIP */, true);
1100 return value;
1101}
1102
1103const convert = (val) => isObject(val) ? reactive(val) : val;
1104function isRef(r) {
1105 return Boolean(r && r.__v_isRef === true);
1106}
1107function ref(value) {
1108 return createRef(value);
1109}
1110function shallowRef(value) {
1111 return createRef(value, true);
1112}
1113class RefImpl {
1114 constructor(_rawValue, _shallow = false) {
1115 this._rawValue = _rawValue;
1116 this._shallow = _shallow;
1117 this.__v_isRef = true;
1118 this._value = _shallow ? _rawValue : convert(_rawValue);
1119 }
1120 get value() {
1121 track(toRaw(this), "get" /* GET */, 'value');
1122 return this._value;
1123 }
1124 set value(newVal) {
1125 if (hasChanged(toRaw(newVal), this._rawValue)) {
1126 this._rawValue = newVal;
1127 this._value = this._shallow ? newVal : convert(newVal);
1128 trigger(toRaw(this), "set" /* SET */, 'value', newVal);
1129 }
1130 }
1131}
1132function createRef(rawValue, shallow = false) {
1133 if (isRef(rawValue)) {
1134 return rawValue;
1135 }
1136 return new RefImpl(rawValue, shallow);
1137}
1138function triggerRef(ref) {
1139 trigger(toRaw(ref), "set" /* SET */, 'value', ref.value );
1140}
1141function unref(ref) {
1142 return isRef(ref) ? ref.value : ref;
1143}
1144const shallowUnwrapHandlers = {
1145 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1146 set: (target, key, value, receiver) => {
1147 const oldValue = target[key];
1148 if (isRef(oldValue) && !isRef(value)) {
1149 oldValue.value = value;
1150 return true;
1151 }
1152 else {
1153 return Reflect.set(target, key, value, receiver);
1154 }
1155 }
1156};
1157function proxyRefs(objectWithRefs) {
1158 return isReactive(objectWithRefs)
1159 ? objectWithRefs
1160 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1161}
1162class CustomRefImpl {
1163 constructor(factory) {
1164 this.__v_isRef = true;
1165 const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value'));
1166 this._get = get;
1167 this._set = set;
1168 }
1169 get value() {
1170 return this._get();
1171 }
1172 set value(newVal) {
1173 this._set(newVal);
1174 }
1175}
1176function customRef(factory) {
1177 return new CustomRefImpl(factory);
1178}
1179function toRefs(object) {
1180 if (!isProxy(object)) {
1181 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1182 }
1183 const ret = isArray(object) ? new Array(object.length) : {};
1184 for (const key in object) {
1185 ret[key] = toRef(object, key);
1186 }
1187 return ret;
1188}
1189class ObjectRefImpl {
1190 constructor(_object, _key) {
1191 this._object = _object;
1192 this._key = _key;
1193 this.__v_isRef = true;
1194 }
1195 get value() {
1196 return this._object[this._key];
1197 }
1198 set value(newVal) {
1199 this._object[this._key] = newVal;
1200 }
1201}
1202function toRef(object, key) {
1203 return isRef(object[key])
1204 ? object[key]
1205 : new ObjectRefImpl(object, key);
1206}
1207
1208class ComputedRefImpl {
1209 constructor(getter, _setter, isReadonly) {
1210 this._setter = _setter;
1211 this._dirty = true;
1212 this.__v_isRef = true;
1213 this.effect = effect(getter, {
1214 lazy: true,
1215 scheduler: () => {
1216 if (!this._dirty) {
1217 this._dirty = true;
1218 trigger(toRaw(this), "set" /* SET */, 'value');
1219 }
1220 }
1221 });
1222 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1223 }
1224 get value() {
1225 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1226 const self = toRaw(this);
1227 if (self._dirty) {
1228 self._value = this.effect();
1229 self._dirty = false;
1230 }
1231 track(self, "get" /* GET */, 'value');
1232 return self._value;
1233 }
1234 set value(newValue) {
1235 this._setter(newValue);
1236 }
1237}
1238function computed(getterOrOptions) {
1239 let getter;
1240 let setter;
1241 if (isFunction(getterOrOptions)) {
1242 getter = getterOrOptions;
1243 setter = () => {
1244 console.warn('Write operation failed: computed value is readonly');
1245 }
1246 ;
1247 }
1248 else {
1249 getter = getterOrOptions.get;
1250 setter = getterOrOptions.set;
1251 }
1252 return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);
1253}
1254
1255const stack = [];
1256function pushWarningContext(vnode) {
1257 stack.push(vnode);
1258}
1259function popWarningContext() {
1260 stack.pop();
1261}
1262function warn(msg, ...args) {
1263 // avoid props formatting or warn handler tracking deps that might be mutated
1264 // during patch, leading to infinite recursion.
1265 pauseTracking();
1266 const instance = stack.length ? stack[stack.length - 1].component : null;
1267 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1268 const trace = getComponentTrace();
1269 if (appWarnHandler) {
1270 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1271 msg + args.join(''),
1272 instance && instance.proxy,
1273 trace
1274 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1275 .join('\n'),
1276 trace
1277 ]);
1278 }
1279 else {
1280 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1281 /* istanbul ignore if */
1282 if (trace.length &&
1283 // avoid spamming console during tests
1284 !false) {
1285 warnArgs.push(`\n`, ...formatTrace(trace));
1286 }
1287 console.warn(...warnArgs);
1288 }
1289 resetTracking();
1290}
1291function getComponentTrace() {
1292 let currentVNode = stack[stack.length - 1];
1293 if (!currentVNode) {
1294 return [];
1295 }
1296 // we can't just use the stack because it will be incomplete during updates
1297 // that did not start from the root. Re-construct the parent chain using
1298 // instance parent pointers.
1299 const normalizedStack = [];
1300 while (currentVNode) {
1301 const last = normalizedStack[0];
1302 if (last && last.vnode === currentVNode) {
1303 last.recurseCount++;
1304 }
1305 else {
1306 normalizedStack.push({
1307 vnode: currentVNode,
1308 recurseCount: 0
1309 });
1310 }
1311 const parentInstance = currentVNode.component && currentVNode.component.parent;
1312 currentVNode = parentInstance && parentInstance.vnode;
1313 }
1314 return normalizedStack;
1315}
1316/* istanbul ignore next */
1317function formatTrace(trace) {
1318 const logs = [];
1319 trace.forEach((entry, i) => {
1320 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1321 });
1322 return logs;
1323}
1324function formatTraceEntry({ vnode, recurseCount }) {
1325 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1326 const isRoot = vnode.component ? vnode.component.parent == null : false;
1327 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1328 const close = `>` + postfix;
1329 return vnode.props
1330 ? [open, ...formatProps(vnode.props), close]
1331 : [open + close];
1332}
1333/* istanbul ignore next */
1334function formatProps(props) {
1335 const res = [];
1336 const keys = Object.keys(props);
1337 keys.slice(0, 3).forEach(key => {
1338 res.push(...formatProp(key, props[key]));
1339 });
1340 if (keys.length > 3) {
1341 res.push(` ...`);
1342 }
1343 return res;
1344}
1345/* istanbul ignore next */
1346function formatProp(key, value, raw) {
1347 if (isString(value)) {
1348 value = JSON.stringify(value);
1349 return raw ? value : [`${key}=${value}`];
1350 }
1351 else if (typeof value === 'number' ||
1352 typeof value === 'boolean' ||
1353 value == null) {
1354 return raw ? value : [`${key}=${value}`];
1355 }
1356 else if (isRef(value)) {
1357 value = formatProp(key, toRaw(value.value), true);
1358 return raw ? value : [`${key}=Ref<`, value, `>`];
1359 }
1360 else if (isFunction(value)) {
1361 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1362 }
1363 else {
1364 value = toRaw(value);
1365 return raw ? value : [`${key}=`, value];
1366 }
1367}
1368
1369const ErrorTypeStrings = {
1370 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1371 ["c" /* CREATED */]: 'created hook',
1372 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1373 ["m" /* MOUNTED */]: 'mounted hook',
1374 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1375 ["u" /* UPDATED */]: 'updated',
1376 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1377 ["um" /* UNMOUNTED */]: 'unmounted hook',
1378 ["a" /* ACTIVATED */]: 'activated hook',
1379 ["da" /* DEACTIVATED */]: 'deactivated hook',
1380 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1381 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1382 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1383 [0 /* SETUP_FUNCTION */]: 'setup function',
1384 [1 /* RENDER_FUNCTION */]: 'render function',
1385 [2 /* WATCH_GETTER */]: 'watcher getter',
1386 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1387 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1388 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1389 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1390 [7 /* VNODE_HOOK */]: 'vnode hook',
1391 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1392 [9 /* TRANSITION_HOOK */]: 'transition hook',
1393 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1394 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1395 [12 /* FUNCTION_REF */]: 'ref function',
1396 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1397 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1398 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
1399};
1400function callWithErrorHandling(fn, instance, type, args) {
1401 let res;
1402 try {
1403 res = args ? fn(...args) : fn();
1404 }
1405 catch (err) {
1406 handleError(err, instance, type);
1407 }
1408 return res;
1409}
1410function callWithAsyncErrorHandling(fn, instance, type, args) {
1411 if (isFunction(fn)) {
1412 const res = callWithErrorHandling(fn, instance, type, args);
1413 if (res && isPromise(res)) {
1414 res.catch(err => {
1415 handleError(err, instance, type);
1416 });
1417 }
1418 return res;
1419 }
1420 const values = [];
1421 for (let i = 0; i < fn.length; i++) {
1422 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1423 }
1424 return values;
1425}
1426function handleError(err, instance, type, throwInDev = true) {
1427 const contextVNode = instance ? instance.vnode : null;
1428 if (instance) {
1429 let cur = instance.parent;
1430 // the exposed instance is the render proxy to keep it consistent with 2.x
1431 const exposedInstance = instance.proxy;
1432 // in production the hook receives only the error code
1433 const errorInfo = ErrorTypeStrings[type] ;
1434 while (cur) {
1435 const errorCapturedHooks = cur.ec;
1436 if (errorCapturedHooks) {
1437 for (let i = 0; i < errorCapturedHooks.length; i++) {
1438 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1439 return;
1440 }
1441 }
1442 }
1443 cur = cur.parent;
1444 }
1445 // app-level handling
1446 const appErrorHandler = instance.appContext.config.errorHandler;
1447 if (appErrorHandler) {
1448 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1449 return;
1450 }
1451 }
1452 logError(err, type, contextVNode, throwInDev);
1453}
1454function logError(err, type, contextVNode, throwInDev = true) {
1455 {
1456 const info = ErrorTypeStrings[type];
1457 if (contextVNode) {
1458 pushWarningContext(contextVNode);
1459 }
1460 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1461 if (contextVNode) {
1462 popWarningContext();
1463 }
1464 // crash in dev by default so it's more noticeable
1465 if (throwInDev) {
1466 throw err;
1467 }
1468 else {
1469 console.error(err);
1470 }
1471 }
1472}
1473
1474let isFlushing = false;
1475let isFlushPending = false;
1476const queue = [];
1477let flushIndex = 0;
1478const pendingPreFlushCbs = [];
1479let activePreFlushCbs = null;
1480let preFlushIndex = 0;
1481const pendingPostFlushCbs = [];
1482let activePostFlushCbs = null;
1483let postFlushIndex = 0;
1484const resolvedPromise = Promise.resolve();
1485let currentFlushPromise = null;
1486let currentPreFlushParentJob = null;
1487const RECURSION_LIMIT = 100;
1488function nextTick(fn) {
1489 const p = currentFlushPromise || resolvedPromise;
1490 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1491}
1492// #2768
1493// Use binary-search to find a suitable position in the queue,
1494// so that the queue maintains the increasing order of job's id,
1495// which can prevent the job from being skipped and also can avoid repeated patching.
1496function findInsertionIndex(job) {
1497 // the start index should be `flushIndex + 1`
1498 let start = flushIndex + 1;
1499 let end = queue.length;
1500 const jobId = getId(job);
1501 while (start < end) {
1502 const middle = (start + end) >>> 1;
1503 const middleJobId = getId(queue[middle]);
1504 middleJobId < jobId ? (start = middle + 1) : (end = middle);
1505 }
1506 return start;
1507}
1508function queueJob(job) {
1509 // the dedupe search uses the startIndex argument of Array.includes()
1510 // by default the search index includes the current job that is being run
1511 // so it cannot recursively trigger itself again.
1512 // if the job is a watch() callback, the search will start with a +1 index to
1513 // allow it recursively trigger itself - it is the user's responsibility to
1514 // ensure it doesn't end up in an infinite loop.
1515 if ((!queue.length ||
1516 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1517 job !== currentPreFlushParentJob) {
1518 const pos = findInsertionIndex(job);
1519 if (pos > -1) {
1520 queue.splice(pos, 0, job);
1521 }
1522 else {
1523 queue.push(job);
1524 }
1525 queueFlush();
1526 }
1527}
1528function queueFlush() {
1529 if (!isFlushing && !isFlushPending) {
1530 isFlushPending = true;
1531 currentFlushPromise = resolvedPromise.then(flushJobs);
1532 }
1533}
1534function invalidateJob(job) {
1535 const i = queue.indexOf(job);
1536 if (i > flushIndex) {
1537 queue.splice(i, 1);
1538 }
1539}
1540function queueCb(cb, activeQueue, pendingQueue, index) {
1541 if (!isArray(cb)) {
1542 if (!activeQueue ||
1543 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1544 pendingQueue.push(cb);
1545 }
1546 }
1547 else {
1548 // if cb is an array, it is a component lifecycle hook which can only be
1549 // triggered by a job, which is already deduped in the main queue, so
1550 // we can skip duplicate check here to improve perf
1551 pendingQueue.push(...cb);
1552 }
1553 queueFlush();
1554}
1555function queuePreFlushCb(cb) {
1556 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1557}
1558function queuePostFlushCb(cb) {
1559 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1560}
1561function flushPreFlushCbs(seen, parentJob = null) {
1562 if (pendingPreFlushCbs.length) {
1563 currentPreFlushParentJob = parentJob;
1564 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1565 pendingPreFlushCbs.length = 0;
1566 {
1567 seen = seen || new Map();
1568 }
1569 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1570 if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) {
1571 continue;
1572 }
1573 activePreFlushCbs[preFlushIndex]();
1574 }
1575 activePreFlushCbs = null;
1576 preFlushIndex = 0;
1577 currentPreFlushParentJob = null;
1578 // recursively flush until it drains
1579 flushPreFlushCbs(seen, parentJob);
1580 }
1581}
1582function flushPostFlushCbs(seen) {
1583 if (pendingPostFlushCbs.length) {
1584 const deduped = [...new Set(pendingPostFlushCbs)];
1585 pendingPostFlushCbs.length = 0;
1586 // #1947 already has active queue, nested flushPostFlushCbs call
1587 if (activePostFlushCbs) {
1588 activePostFlushCbs.push(...deduped);
1589 return;
1590 }
1591 activePostFlushCbs = deduped;
1592 {
1593 seen = seen || new Map();
1594 }
1595 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1596 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1597 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
1598 continue;
1599 }
1600 activePostFlushCbs[postFlushIndex]();
1601 }
1602 activePostFlushCbs = null;
1603 postFlushIndex = 0;
1604 }
1605}
1606const getId = (job) => job.id == null ? Infinity : job.id;
1607function flushJobs(seen) {
1608 isFlushPending = false;
1609 isFlushing = true;
1610 {
1611 seen = seen || new Map();
1612 }
1613 flushPreFlushCbs(seen);
1614 // Sort queue before flush.
1615 // This ensures that:
1616 // 1. Components are updated from parent to child. (because parent is always
1617 // created before the child so its render effect will have smaller
1618 // priority number)
1619 // 2. If a component is unmounted during a parent component's update,
1620 // its update can be skipped.
1621 queue.sort((a, b) => getId(a) - getId(b));
1622 try {
1623 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1624 const job = queue[flushIndex];
1625 if (job && job.active !== false) {
1626 if (true && checkRecursiveUpdates(seen, job)) {
1627 continue;
1628 }
1629 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1630 }
1631 }
1632 }
1633 finally {
1634 flushIndex = 0;
1635 queue.length = 0;
1636 flushPostFlushCbs(seen);
1637 isFlushing = false;
1638 currentFlushPromise = null;
1639 // some postFlushCb queued jobs!
1640 // keep flushing until it drains.
1641 if (queue.length ||
1642 pendingPreFlushCbs.length ||
1643 pendingPostFlushCbs.length) {
1644 flushJobs(seen);
1645 }
1646 }
1647}
1648function checkRecursiveUpdates(seen, fn) {
1649 if (!seen.has(fn)) {
1650 seen.set(fn, 1);
1651 }
1652 else {
1653 const count = seen.get(fn);
1654 if (count > RECURSION_LIMIT) {
1655 const instance = fn.ownerInstance;
1656 const componentName = instance && getComponentName(instance.type);
1657 warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
1658 `This means you have a reactive effect that is mutating its own ` +
1659 `dependencies and thus recursively triggering itself. Possible sources ` +
1660 `include component template, render function, updated hook or ` +
1661 `watcher source function.`);
1662 return true;
1663 }
1664 else {
1665 seen.set(fn, count + 1);
1666 }
1667 }
1668}
1669
1670/* eslint-disable no-restricted-globals */
1671let isHmrUpdating = false;
1672const hmrDirtyComponents = new Set();
1673// Expose the HMR runtime on the global object
1674// This makes it entirely tree-shakable without polluting the exports and makes
1675// it easier to be used in toolings like vue-loader
1676// Note: for a component to be eligible for HMR it also needs the __hmrId option
1677// to be set so that its instances can be registered / removed.
1678{
1679 const globalObject = typeof global !== 'undefined'
1680 ? global
1681 : typeof self !== 'undefined'
1682 ? self
1683 : typeof window !== 'undefined'
1684 ? window
1685 : {};
1686 globalObject.__VUE_HMR_RUNTIME__ = {
1687 createRecord: tryWrap(createRecord),
1688 rerender: tryWrap(rerender),
1689 reload: tryWrap(reload)
1690 };
1691}
1692const map = new Map();
1693function registerHMR(instance) {
1694 const id = instance.type.__hmrId;
1695 let record = map.get(id);
1696 if (!record) {
1697 createRecord(id, instance.type);
1698 record = map.get(id);
1699 }
1700 record.instances.add(instance);
1701}
1702function unregisterHMR(instance) {
1703 map.get(instance.type.__hmrId).instances.delete(instance);
1704}
1705function createRecord(id, component) {
1706 if (!component) {
1707 warn(`HMR API usage is out of date.\n` +
1708 `Please upgrade vue-loader/vite/rollup-plugin-vue or other relevant ` +
1709 `dependency that handles Vue SFC compilation.`);
1710 component = {};
1711 }
1712 if (map.has(id)) {
1713 return false;
1714 }
1715 map.set(id, {
1716 component: isClassComponent(component) ? component.__vccOpts : component,
1717 instances: new Set()
1718 });
1719 return true;
1720}
1721function rerender(id, newRender) {
1722 const record = map.get(id);
1723 if (!record)
1724 return;
1725 if (newRender)
1726 record.component.render = newRender;
1727 // Array.from creates a snapshot which avoids the set being mutated during
1728 // updates
1729 Array.from(record.instances).forEach(instance => {
1730 if (newRender) {
1731 instance.render = newRender;
1732 }
1733 instance.renderCache = [];
1734 // this flag forces child components with slot content to update
1735 isHmrUpdating = true;
1736 instance.update();
1737 isHmrUpdating = false;
1738 });
1739}
1740function reload(id, newComp) {
1741 const record = map.get(id);
1742 if (!record)
1743 return;
1744 // Array.from creates a snapshot which avoids the set being mutated during
1745 // updates
1746 const { component, instances } = record;
1747 if (!hmrDirtyComponents.has(component)) {
1748 // 1. Update existing comp definition to match new one
1749 newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp;
1750 extend(component, newComp);
1751 for (const key in component) {
1752 if (key !== '__file' && !(key in newComp)) {
1753 delete component[key];
1754 }
1755 }
1756 // 2. Mark component dirty. This forces the renderer to replace the component
1757 // on patch.
1758 hmrDirtyComponents.add(component);
1759 // 3. Make sure to unmark the component after the reload.
1760 queuePostFlushCb(() => {
1761 hmrDirtyComponents.delete(component);
1762 });
1763 }
1764 Array.from(instances).forEach(instance => {
1765 if (instance.parent) {
1766 // 4. Force the parent instance to re-render. This will cause all updated
1767 // components to be unmounted and re-mounted. Queue the update so that we
1768 // don't end up forcing the same parent to re-render multiple times.
1769 queueJob(instance.parent.update);
1770 }
1771 else if (instance.appContext.reload) {
1772 // root instance mounted via createApp() has a reload method
1773 instance.appContext.reload();
1774 }
1775 else if (typeof window !== 'undefined') {
1776 // root instance inside tree created via raw render(). Force reload.
1777 window.location.reload();
1778 }
1779 else {
1780 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
1781 }
1782 });
1783}
1784function tryWrap(fn) {
1785 return (id, arg) => {
1786 try {
1787 return fn(id, arg);
1788 }
1789 catch (e) {
1790 console.error(e);
1791 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
1792 `Full reload required.`);
1793 }
1794 };
1795}
1796
1797let devtools;
1798function setDevtoolsHook(hook) {
1799 devtools = hook;
1800}
1801function devtoolsInitApp(app, version) {
1802 // TODO queue if devtools is undefined
1803 if (!devtools)
1804 return;
1805 devtools.emit("app:init" /* APP_INIT */, app, version, {
1806 Fragment,
1807 Text,
1808 Comment: Comment$1,
1809 Static
1810 });
1811}
1812function devtoolsUnmountApp(app) {
1813 if (!devtools)
1814 return;
1815 devtools.emit("app:unmount" /* APP_UNMOUNT */, app);
1816}
1817const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
1818const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
1819const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
1820function createDevtoolsComponentHook(hook) {
1821 return (component) => {
1822 if (!devtools)
1823 return;
1824 devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
1825 };
1826}
1827const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
1828const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
1829function createDevtoolsPerformanceHook(hook) {
1830 return (component, type, time) => {
1831 if (!devtools)
1832 return;
1833 devtools.emit(hook, component.appContext.app, component.uid, component, type, time);
1834 };
1835}
1836function devtoolsComponentEmit(component, event, params) {
1837 if (!devtools)
1838 return;
1839 devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
1840}
1841
1842const deprecationData = {
1843 ["GLOBAL_MOUNT" /* GLOBAL_MOUNT */]: {
1844 message: `The global app bootstrapping API has changed: vm.$mount() and the "el" ` +
1845 `option have been removed. Use createApp(RootComponent).mount() instead.`,
1846 link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance`
1847 },
1848 ["GLOBAL_MOUNT_CONTAINER" /* GLOBAL_MOUNT_CONTAINER */]: {
1849 message: `Vue detected directives on the mount container. ` +
1850 `In Vue 3, the container is no longer considered part of the template ` +
1851 `and will not be processed/replaced.`,
1852 link: `https://v3.vuejs.org/guide/migration/mount-changes.html`
1853 },
1854 ["GLOBAL_EXTEND" /* GLOBAL_EXTEND */]: {
1855 message: `Vue.extend() has been removed in Vue 3. ` +
1856 `Use defineComponent() instead.`,
1857 link: `https://v3.vuejs.org/api/global-api.html#definecomponent`
1858 },
1859 ["GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */]: {
1860 message: `Vue.prototype is no longer available in Vue 3. ` +
1861 `Use app.config.globalProperties instead.`,
1862 link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties`
1863 },
1864 ["GLOBAL_SET" /* GLOBAL_SET */]: {
1865 message: `Vue.set() has been removed as it is no longer needed in Vue 3. ` +
1866 `Simply use native JavaScript mutations.`
1867 },
1868 ["GLOBAL_DELETE" /* GLOBAL_DELETE */]: {
1869 message: `Vue.delete() has been removed as it is no longer needed in Vue 3. ` +
1870 `Simply use native JavaScript mutations.`
1871 },
1872 ["GLOBAL_OBSERVABLE" /* GLOBAL_OBSERVABLE */]: {
1873 message: `Vue.observable() has been removed. ` +
1874 `Use \`import { reactive } from "vue"\` from Composition API instead.`,
1875 link: `https://v3.vuejs.org/api/basic-reactivity.html`
1876 },
1877 ["GLOBAL_PRIVATE_UTIL" /* GLOBAL_PRIVATE_UTIL */]: {
1878 message: `Vue.util has been removed. Please refactor to avoid its usage ` +
1879 `since it was an internal API even in Vue 2.`
1880 },
1881 ["CONFIG_SILENT" /* CONFIG_SILENT */]: {
1882 message: `config.silent has been removed because it is not good practice to ` +
1883 `intentionally suppress warnings. You can use your browser console's ` +
1884 `filter features to focus on relevant messages.`
1885 },
1886 ["CONFIG_DEVTOOLS" /* CONFIG_DEVTOOLS */]: {
1887 message: `config.devtools has been removed. To enable devtools for ` +
1888 `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`,
1889 link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags`
1890 },
1891 ["CONFIG_KEY_CODES" /* CONFIG_KEY_CODES */]: {
1892 message: `config.keyCodes has been removed. ` +
1893 `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`,
1894 link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
1895 },
1896 ["CONFIG_PRODUCTION_TIP" /* CONFIG_PRODUCTION_TIP */]: {
1897 message: `config.productionTip has been removed.`,
1898 link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed`
1899 },
1900 ["CONFIG_IGNORED_ELEMENTS" /* CONFIG_IGNORED_ELEMENTS */]: {
1901 message: () => {
1902 let msg = `config.ignoredElements has been removed.`;
1903 if (isRuntimeOnly()) {
1904 msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.`;
1905 }
1906 else {
1907 msg += ` Use config.isCustomElement instead.`;
1908 }
1909 return msg;
1910 },
1911 link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement`
1912 },
1913 ["CONFIG_WHITESPACE" /* CONFIG_WHITESPACE */]: {
1914 // this warning is only relevant in the full build when using runtime
1915 // compilation, so it's put in the runtime compatConfig list.
1916 message: `Vue 3 compiler's whitespace option will default to "condense" instead of ` +
1917 `"preserve". To suppress this warning, provide an explicit value for ` +
1918 `\`config.compilerOptions.whitespace\`.`
1919 },
1920 ["CONFIG_OPTION_MERGE_STRATS" /* CONFIG_OPTION_MERGE_STRATS */]: {
1921 message: `config.optionMergeStrategies no longer exposes internal strategies. ` +
1922 `Use custom merge functions instead.`
1923 },
1924 ["INSTANCE_SET" /* INSTANCE_SET */]: {
1925 message: `vm.$set() has been removed as it is no longer needed in Vue 3. ` +
1926 `Simply use native JavaScript mutations.`
1927 },
1928 ["INSTANCE_DELETE" /* INSTANCE_DELETE */]: {
1929 message: `vm.$delete() has been removed as it is no longer needed in Vue 3. ` +
1930 `Simply use native JavaScript mutations.`
1931 },
1932 ["INSTANCE_DESTROY" /* INSTANCE_DESTROY */]: {
1933 message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
1934 link: `https://v3.vuejs.org/api/application-api.html#unmount`
1935 },
1936 ["INSTANCE_EVENT_EMITTER" /* INSTANCE_EVENT_EMITTER */]: {
1937 message: `vm.$on/$once/$off() have been removed. ` +
1938 `Use an external event emitter library instead.`,
1939 link: `https://v3.vuejs.org/guide/migration/events-api.html`
1940 },
1941 ["INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */]: {
1942 message: event => `"${event}" lifecycle events are no longer supported. From templates, ` +
1943 `use the "vnode" prefix instead of "hook:". For example, @${event} ` +
1944 `should be changed to @vnode-${event.slice(5)}. ` +
1945 `From JavaScript, use Composition API to dynamically register lifecycle ` +
1946 `hooks.`,
1947 link: `https://v3.vuejs.org/guide/migration/vnode-lifecycle-events.html`
1948 },
1949 ["INSTANCE_CHILDREN" /* INSTANCE_CHILDREN */]: {
1950 message: `vm.$children has been removed. Consider refactoring your logic ` +
1951 `to avoid relying on direct access to child components.`,
1952 link: `https://v3.vuejs.org/guide/migration/children.html`
1953 },
1954 ["INSTANCE_LISTENERS" /* INSTANCE_LISTENERS */]: {
1955 message: `vm.$listeners has been removed. In Vue 3, parent v-on listeners are ` +
1956 `included in vm.$attrs and it is no longer necessary to separately use ` +
1957 `v-on="$listeners" if you are already using v-bind="$attrs". ` +
1958 `(Note: the Vue 3 behavior only applies if this compat config is disabled)`,
1959 link: `https://v3.vuejs.org/guide/migration/listeners-removed.html`
1960 },
1961 ["INSTANCE_SCOPED_SLOTS" /* INSTANCE_SCOPED_SLOTS */]: {
1962 message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`,
1963 link: `https://v3.vuejs.org/guide/migration/slots-unification.html`
1964 },
1965 ["INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */]: {
1966 message: componentName => `Component <${componentName ||
1967 'Anonymous'}> has \`inheritAttrs: false\` but is ` +
1968 `relying on class/style fallthrough from parent. In Vue 3, class/style ` +
1969 `are now included in $attrs and will no longer fallthrough when ` +
1970 `inheritAttrs is false. If you are already using v-bind="$attrs" on ` +
1971 `component root it should render the same end result. ` +
1972 `If you are binding $attrs to a non-root element and expecting ` +
1973 `class/style to fallthrough on root, you will need to now manually bind ` +
1974 `them on root via :class="$attrs.class".`,
1975 link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html`
1976 },
1977 ["OPTIONS_DATA_FN" /* OPTIONS_DATA_FN */]: {
1978 message: `The "data" option can no longer be a plain object. ` +
1979 `Always use a function.`,
1980 link: `https://v3.vuejs.org/guide/migration/data-option.html`
1981 },
1982 ["OPTIONS_DATA_MERGE" /* OPTIONS_DATA_MERGE */]: {
1983 message: (key) => `Detected conflicting key "${key}" when merging data option values. ` +
1984 `In Vue 3, data keys are merged shallowly and will override one another.`,
1985 link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change`
1986 },
1987 ["OPTIONS_BEFORE_DESTROY" /* OPTIONS_BEFORE_DESTROY */]: {
1988 message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`
1989 },
1990 ["OPTIONS_DESTROYED" /* OPTIONS_DESTROYED */]: {
1991 message: `\`destroyed\` has been renamed to \`unmounted\`.`
1992 },
1993 ["WATCH_ARRAY" /* WATCH_ARRAY */]: {
1994 message: `"watch" option or vm.$watch on an array value will no longer ` +
1995 `trigger on array mutation unless the "deep" option is specified. ` +
1996 `If current usage is intended, you can disable the compat behavior and ` +
1997 `suppress this warning with:` +
1998 `\n\n configureCompat({ ${"WATCH_ARRAY" /* WATCH_ARRAY */}: false })\n`,
1999 link: `https://v3.vuejs.org/guide/migration/watch.html`
2000 },
2001 ["PROPS_DEFAULT_THIS" /* PROPS_DEFAULT_THIS */]: {
2002 message: (key) => `props default value function no longer has access to "this". The compat ` +
2003 `build only offers access to this.$options.` +
2004 `(found in prop "${key}")`,
2005 link: `https://v3.vuejs.org/guide/migration/props-default-this.html`
2006 },
2007 ["CUSTOM_DIR" /* CUSTOM_DIR */]: {
2008 message: (legacyHook, newHook) => `Custom directive hook "${legacyHook}" has been removed. ` +
2009 `Use "${newHook}" instead.`,
2010 link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
2011 },
2012 ["V_FOR_REF" /* V_FOR_REF */]: {
2013 message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
2014 `Consider using function refs or refactor to avoid ref usage altogether.`,
2015 link: `https://v3.vuejs.org/guide/migration/array-refs.html`
2016 },
2017 ["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: {
2018 message: `Using keyCode as v-on modifier is no longer supported. ` +
2019 `Use kebab-case key name modifiers instead.`,
2020 link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
2021 },
2022 ["ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */]: {
2023 message: (name) => `Attribute "${name}" with v-bind value \`false\` will render ` +
2024 `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` +
2025 `use \`null\` or \`undefined\` instead. If the usage is intended, ` +
2026 `you can disable the compat behavior and suppress this warning with:` +
2027 `\n\n configureCompat({ ${"ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */}: false })\n`,
2028 link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
2029 },
2030 ["ATTR_ENUMERATED_COERCION" /* ATTR_ENUMERATED_COERCION */]: {
2031 message: (name, value, coerced) => `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` +
2032 `${value === null ? `be removed` : `render the value as-is`} instead of coercing the value to "${coerced}" in Vue 3. ` +
2033 `Always use explicit "true" or "false" values for enumerated attributes. ` +
2034 `If the usage is intended, ` +
2035 `you can disable the compat behavior and suppress this warning with:` +
2036 `\n\n configureCompat({ ${"ATTR_ENUMERATED_COERCION" /* ATTR_ENUMERATED_COERCION */}: false })\n`,
2037 link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
2038 },
2039 ["TRANSITION_CLASSES" /* TRANSITION_CLASSES */]: {
2040 message: `` // this feature cannot be runtime-detected
2041 },
2042 ["TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */]: {
2043 message: `<TransitionGroup> no longer renders a root <span> element by ` +
2044 `default if no "tag" prop is specified. If you do not rely on the span ` +
2045 `for styling, you can disable the compat behavior and suppress this ` +
2046 `warning with:` +
2047 `\n\n configureCompat({ ${"TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */}: false })\n`,
2048 link: `https://v3.vuejs.org/guide/migration/transition-group.html`
2049 },
2050 ["COMPONENT_ASYNC" /* COMPONENT_ASYNC */]: {
2051 message: (comp) => {
2052 const name = getComponentName(comp);
2053 return (`Async component${name ? ` <${name}>` : `s`} should be explicitly created via \`defineAsyncComponent()\` ` +
2054 `in Vue 3. Plain functions will be treated as functional components in ` +
2055 `non-compat build. If you have already migrated all async component ` +
2056 `usage and intend to use plain functions for functional components, ` +
2057 `you can disable the compat behavior and suppress this ` +
2058 `warning with:` +
2059 `\n\n configureCompat({ ${"COMPONENT_ASYNC" /* COMPONENT_ASYNC */}: false })\n`);
2060 },
2061 link: `https://v3.vuejs.org/guide/migration/async-components.html`
2062 },
2063 ["COMPONENT_FUNCTIONAL" /* COMPONENT_FUNCTIONAL */]: {
2064 message: (comp) => {
2065 const name = getComponentName(comp);
2066 return (`Functional component${name ? ` <${name}>` : `s`} should be defined as a plain function in Vue 3. The "functional" ` +
2067 `option has been removed. NOTE: Before migrating to use plain ` +
2068 `functions for functional components, first make sure that all async ` +
2069 `components usage have been migrated and its compat behavior has ` +
2070 `been disabled.`);
2071 },
2072 link: `https://v3.vuejs.org/guide/migration/functional-components.html`
2073 },
2074 ["COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */]: {
2075 message: (comp) => {
2076 const configMsg = `opt-in to ` +
2077 `Vue 3 behavior on a per-component basis with \`compatConfig: { ${"COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */}: false }\`.`;
2078 if (comp.props && isArray(comp.props)
2079 ? comp.props.includes('modelValue')
2080 : hasOwn(comp.props, 'modelValue')) {
2081 return (`Component delcares "modelValue" prop, which is Vue 3 usage, but ` +
2082 `is running under Vue 2 compat v-model behavior. You can ${configMsg}`);
2083 }
2084 return (`v-model usage on component has changed in Vue 3. Component that expects ` +
2085 `to work with v-model should now use the "modelValue" prop and emit the ` +
2086 `"update:modelValue" event. You can update the usage and then ${configMsg}`);
2087 },
2088 link: `https://v3.vuejs.org/guide/migration/v-model.html`
2089 },
2090 ["RENDER_FUNCTION" /* RENDER_FUNCTION */]: {
2091 message: `Vue 3's render function API has changed. ` +
2092 `You can opt-in to the new API with:` +
2093 `\n\n configureCompat({ ${"RENDER_FUNCTION" /* RENDER_FUNCTION */}: false })\n` +
2094 `\n (This can also be done per-component via the "compatConfig" option.)`,
2095 link: `https://v3.vuejs.org/guide/migration/render-function-api.html`
2096 },
2097 ["FILTERS" /* FILTERS */]: {
2098 message: `filters have been removed in Vue 3. ` +
2099 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
2100 `Use method calls or computed properties instead.`,
2101 link: `https://v3.vuejs.org/guide/migration/filters.html`
2102 },
2103 ["PRIVATE_APIS" /* PRIVATE_APIS */]: {
2104 message: name => `"${name}" is a Vue 2 private API that no longer exists in Vue 3. ` +
2105 `If you are seeing this warning only due to a dependency, you can ` +
2106 `suppress this warning via { PRIVATE_APIS: 'supress-warning' }.`
2107 }
2108};
2109const instanceWarned = Object.create(null);
2110const warnCount = Object.create(null);
2111function warnDeprecation(key, instance, ...args) {
2112 instance = instance || getCurrentInstance();
2113 // check user config
2114 const config = getCompatConfigForKey(key, instance);
2115 if (config === 'suppress-warning') {
2116 return;
2117 }
2118 const dupKey = key + args.join('');
2119 let compId = instance && formatComponentName(instance, instance.type);
2120 if (compId === 'Anonymous' && instance) {
2121 compId = instance.uid;
2122 }
2123 // skip if the same warning is emitted for the same component type
2124 const componentDupKey = dupKey + compId;
2125 if (componentDupKey in instanceWarned) {
2126 return;
2127 }
2128 instanceWarned[componentDupKey] = true;
2129 // same warning, but different component. skip the long message and just
2130 // log the key and count.
2131 if (dupKey in warnCount) {
2132 warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`);
2133 return;
2134 }
2135 warnCount[dupKey] = 0;
2136 const { message, link } = deprecationData[key];
2137 warn(`(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`);
2138 if (!isCompatEnabled(key, instance, true)) {
2139 console.error(`^ The above deprecation's compat behavior is disabled and will likely ` +
2140 `lead to runtime errors.`);
2141 }
2142}
2143const globalCompatConfig = {
2144 MODE: 2
2145};
2146function getCompatConfigForKey(key, instance) {
2147 const instanceConfig = instance && instance.type.compatConfig;
2148 if (instanceConfig && key in instanceConfig) {
2149 return instanceConfig[key];
2150 }
2151 return globalCompatConfig[key];
2152}
2153function isCompatEnabled(key, instance, enableForBuiltIn = false) {
2154 // skip compat for built-in components
2155 if (!enableForBuiltIn && instance && instance.type.__isBuiltIn) {
2156 return false;
2157 }
2158 const rawMode = getCompatConfigForKey('MODE', instance) || 2;
2159 const val = getCompatConfigForKey(key, instance);
2160 const mode = isFunction(rawMode)
2161 ? rawMode(instance && instance.type)
2162 : rawMode;
2163 if (mode === 2) {
2164 return val !== false;
2165 }
2166 else {
2167 return val === true || val === 'suppress-warning';
2168 }
2169}
2170
2171function emit(instance, event, ...rawArgs) {
2172 const props = instance.vnode.props || EMPTY_OBJ;
2173 {
2174 const { emitsOptions, propsOptions: [propsOptions] } = instance;
2175 if (emitsOptions) {
2176 if (!(event in emitsOptions) &&
2177 !(false )) {
2178 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
2179 warn(`Component emitted event "${event}" but it is neither declared in ` +
2180 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
2181 }
2182 }
2183 else {
2184 const validator = emitsOptions[event];
2185 if (isFunction(validator)) {
2186 const isValid = validator(...rawArgs);
2187 if (!isValid) {
2188 warn(`Invalid event arguments: event validation failed for event "${event}".`);
2189 }
2190 }
2191 }
2192 }
2193 }
2194 let args = rawArgs;
2195 const isModelListener = event.startsWith('update:');
2196 // for v-model update:xxx events, apply modifiers on args
2197 const modelArg = isModelListener && event.slice(7);
2198 if (modelArg && modelArg in props) {
2199 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
2200 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
2201 if (trim) {
2202 args = rawArgs.map(a => a.trim());
2203 }
2204 else if (number) {
2205 args = rawArgs.map(toNumber);
2206 }
2207 }
2208 {
2209 devtoolsComponentEmit(instance, event, args);
2210 }
2211 {
2212 const lowerCaseEvent = event.toLowerCase();
2213 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
2214 warn(`Event "${lowerCaseEvent}" is emitted in component ` +
2215 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
2216 `Note that HTML attributes are case-insensitive and you cannot use ` +
2217 `v-on to listen to camelCase events when using in-DOM templates. ` +
2218 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
2219 }
2220 }
2221 let handlerName;
2222 let handler = props[(handlerName = toHandlerKey(event))] ||
2223 // also try camelCase event handler (#2249)
2224 props[(handlerName = toHandlerKey(camelize(event)))];
2225 // for v-model update:xxx events, also trigger kebab-case equivalent
2226 // for props passed via kebab-case
2227 if (!handler && isModelListener) {
2228 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
2229 }
2230 if (handler) {
2231 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2232 }
2233 const onceHandler = props[handlerName + `Once`];
2234 if (onceHandler) {
2235 if (!instance.emitted) {
2236 (instance.emitted = {})[handlerName] = true;
2237 }
2238 else if (instance.emitted[handlerName]) {
2239 return;
2240 }
2241 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
2242 }
2243}
2244function normalizeEmitsOptions(comp, appContext, asMixin = false) {
2245 const cache = appContext.emitsCache;
2246 const cached = cache.get(comp);
2247 if (cached !== undefined) {
2248 return cached;
2249 }
2250 const raw = comp.emits;
2251 let normalized = {};
2252 // apply mixin/extends props
2253 let hasExtends = false;
2254 if (!isFunction(comp)) {
2255 const extendEmits = (raw) => {
2256 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
2257 if (normalizedFromExtend) {
2258 hasExtends = true;
2259 extend(normalized, normalizedFromExtend);
2260 }
2261 };
2262 if (!asMixin && appContext.mixins.length) {
2263 appContext.mixins.forEach(extendEmits);
2264 }
2265 if (comp.extends) {
2266 extendEmits(comp.extends);
2267 }
2268 if (comp.mixins) {
2269 comp.mixins.forEach(extendEmits);
2270 }
2271 }
2272 if (!raw && !hasExtends) {
2273 cache.set(comp, null);
2274 return null;
2275 }
2276 if (isArray(raw)) {
2277 raw.forEach(key => (normalized[key] = null));
2278 }
2279 else {
2280 extend(normalized, raw);
2281 }
2282 cache.set(comp, normalized);
2283 return normalized;
2284}
2285// Check if an incoming prop key is a declared emit event listener.
2286// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
2287// both considered matched listeners.
2288function isEmitListener(options, key) {
2289 if (!options || !isOn(key)) {
2290 return false;
2291 }
2292 key = key.slice(2).replace(/Once$/, '');
2293 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
2294 hasOwn(options, hyphenate(key)) ||
2295 hasOwn(options, key));
2296}
2297
2298/**
2299 * mark the current rendering instance for asset resolution (e.g.
2300 * resolveComponent, resolveDirective) during render
2301 */
2302let currentRenderingInstance = null;
2303let currentScopeId = null;
2304/**
2305 * Note: rendering calls maybe nested. The function returns the parent rendering
2306 * instance if present, which should be restored after the render is done:
2307 *
2308 * ```js
2309 * const prev = setCurrentRenderingInstance(i)
2310 * // ...render
2311 * setCurrentRenderingInstance(prev)
2312 * ```
2313 */
2314function setCurrentRenderingInstance(instance) {
2315 const prev = currentRenderingInstance;
2316 currentRenderingInstance = instance;
2317 currentScopeId = (instance && instance.type.__scopeId) || null;
2318 return prev;
2319}
2320/**
2321 * Set scope id when creating hoisted vnodes.
2322 * @private compiler helper
2323 */
2324function pushScopeId(id) {
2325 currentScopeId = id;
2326}
2327/**
2328 * Technically we no longer need this after 3.0.8 but we need to keep the same
2329 * API for backwards compat w/ code generated by compilers.
2330 * @private
2331 */
2332function popScopeId() {
2333 currentScopeId = null;
2334}
2335/**
2336 * Only for backwards compat
2337 * @private
2338 */
2339const withScopeId = (_id) => withCtx;
2340/**
2341 * Wrap a slot function to memoize current rendering instance
2342 * @private compiler helper
2343 */
2344function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
2345) {
2346 if (!ctx)
2347 return fn;
2348 // already normalized
2349 if (fn._n) {
2350 return fn;
2351 }
2352 const renderFnWithContext = (...args) => {
2353 // If a user calls a compiled slot inside a template expression (#1745), it
2354 // can mess up block tracking, so by default we disable block tracking and
2355 // force bail out when invoking a compiled slot (indicated by the ._d flag).
2356 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
2357 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
2358 if (renderFnWithContext._d) {
2359 setBlockTracking(-1);
2360 }
2361 const prevInstance = setCurrentRenderingInstance(ctx);
2362 const res = fn(...args);
2363 setCurrentRenderingInstance(prevInstance);
2364 if (renderFnWithContext._d) {
2365 setBlockTracking(1);
2366 }
2367 {
2368 devtoolsComponentUpdated(ctx);
2369 }
2370 return res;
2371 };
2372 // mark normalized to avoid duplicated wrapping
2373 renderFnWithContext._n = true;
2374 // mark this as compiled by default
2375 // this is used in vnode.ts -> normalizeChildren() to set the slot
2376 // rendering flag.
2377 renderFnWithContext._c = true;
2378 // disable block tracking by default
2379 renderFnWithContext._d = true;
2380 return renderFnWithContext;
2381}
2382
2383/**
2384 * dev only flag to track whether $attrs was used during render.
2385 * If $attrs was used during render then the warning for failed attrs
2386 * fallthrough can be suppressed.
2387 */
2388let accessedAttrs = false;
2389function markAttrsAccessed() {
2390 accessedAttrs = true;
2391}
2392function renderComponentRoot(instance) {
2393 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
2394 let result;
2395 const prev = setCurrentRenderingInstance(instance);
2396 {
2397 accessedAttrs = false;
2398 }
2399 try {
2400 let fallthroughAttrs;
2401 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
2402 // withProxy is a proxy with a different `has` trap only for
2403 // runtime-compiled render functions using `with` block.
2404 const proxyToUse = withProxy || proxy;
2405 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2406 fallthroughAttrs = attrs;
2407 }
2408 else {
2409 // functional
2410 const render = Component;
2411 // in dev, mark attrs accessed if optional props (attrs === props)
2412 if (true && attrs === props) {
2413 markAttrsAccessed();
2414 }
2415 result = normalizeVNode(render.length > 1
2416 ? render(props, true
2417 ? {
2418 get attrs() {
2419 markAttrsAccessed();
2420 return attrs;
2421 },
2422 slots,
2423 emit
2424 }
2425 : { attrs, slots, emit })
2426 : render(props, null /* we know it doesn't need it */));
2427 fallthroughAttrs = Component.props
2428 ? attrs
2429 : getFunctionalFallthrough(attrs);
2430 }
2431 // attr merging
2432 // in dev mode, comments are preserved, and it's possible for a template
2433 // to have comments along side the root element which makes it a fragment
2434 let root = result;
2435 let setRoot = undefined;
2436 if (true &&
2437 result.patchFlag > 0 &&
2438 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
2439 ;
2440 [root, setRoot] = getChildRoot(result);
2441 }
2442 if (fallthroughAttrs && inheritAttrs !== false) {
2443 const keys = Object.keys(fallthroughAttrs);
2444 const { shapeFlag } = root;
2445 if (keys.length) {
2446 if (shapeFlag & 1 /* ELEMENT */ ||
2447 shapeFlag & 6 /* COMPONENT */) {
2448 if (propsOptions && keys.some(isModelListener)) {
2449 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2450 // prop, it indicates this component expects to handle v-model and
2451 // it should not fallthrough.
2452 // related: #1543, #1643, #1989
2453 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2454 }
2455 root = cloneVNode(root, fallthroughAttrs);
2456 }
2457 else if (true && !accessedAttrs && root.type !== Comment$1) {
2458 const allAttrs = Object.keys(attrs);
2459 const eventAttrs = [];
2460 const extraAttrs = [];
2461 for (let i = 0, l = allAttrs.length; i < l; i++) {
2462 const key = allAttrs[i];
2463 if (isOn(key)) {
2464 // ignore v-model handlers when they fail to fallthrough
2465 if (!isModelListener(key)) {
2466 // remove `on`, lowercase first letter to reflect event casing
2467 // accurately
2468 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2469 }
2470 }
2471 else {
2472 extraAttrs.push(key);
2473 }
2474 }
2475 if (extraAttrs.length) {
2476 warn(`Extraneous non-props attributes (` +
2477 `${extraAttrs.join(', ')}) ` +
2478 `were passed to component but could not be automatically inherited ` +
2479 `because component renders fragment or text root nodes.`);
2480 }
2481 if (eventAttrs.length) {
2482 warn(`Extraneous non-emits event listeners (` +
2483 `${eventAttrs.join(', ')}) ` +
2484 `were passed to component but could not be automatically inherited ` +
2485 `because component renders fragment or text root nodes. ` +
2486 `If the listener is intended to be a component custom event listener only, ` +
2487 `declare it using the "emits" option.`);
2488 }
2489 }
2490 }
2491 }
2492 if (false &&
2493 isCompatEnabled("INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */, instance) &&
2494 vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */ &&
2495 (root.shapeFlag & 1 /* ELEMENT */ ||
2496 root.shapeFlag & 6 /* COMPONENT */)) ;
2497 // inherit directives
2498 if (vnode.dirs) {
2499 if (true && !isElementRoot(root)) {
2500 warn(`Runtime directive used on component with non-element root node. ` +
2501 `The directives will not function as intended.`);
2502 }
2503 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2504 }
2505 // inherit transition data
2506 if (vnode.transition) {
2507 if (true && !isElementRoot(root)) {
2508 warn(`Component inside <Transition> renders non-element root node ` +
2509 `that cannot be animated.`);
2510 }
2511 root.transition = vnode.transition;
2512 }
2513 if (true && setRoot) {
2514 setRoot(root);
2515 }
2516 else {
2517 result = root;
2518 }
2519 }
2520 catch (err) {
2521 blockStack.length = 0;
2522 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2523 result = createVNode(Comment$1);
2524 }
2525 setCurrentRenderingInstance(prev);
2526 return result;
2527}
2528/**
2529 * dev only
2530 * In dev mode, template root level comments are rendered, which turns the
2531 * template into a fragment root, but we need to locate the single element
2532 * root for attrs and scope id processing.
2533 */
2534const getChildRoot = (vnode) => {
2535 const rawChildren = vnode.children;
2536 const dynamicChildren = vnode.dynamicChildren;
2537 const childRoot = filterSingleRoot(rawChildren);
2538 if (!childRoot) {
2539 return [vnode, undefined];
2540 }
2541 const index = rawChildren.indexOf(childRoot);
2542 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2543 const setRoot = (updatedRoot) => {
2544 rawChildren[index] = updatedRoot;
2545 if (dynamicChildren) {
2546 if (dynamicIndex > -1) {
2547 dynamicChildren[dynamicIndex] = updatedRoot;
2548 }
2549 else if (updatedRoot.patchFlag > 0) {
2550 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2551 }
2552 }
2553 };
2554 return [normalizeVNode(childRoot), setRoot];
2555};
2556function filterSingleRoot(children) {
2557 let singleRoot;
2558 for (let i = 0; i < children.length; i++) {
2559 const child = children[i];
2560 if (isVNode(child)) {
2561 // ignore user comment
2562 if (child.type !== Comment$1 || child.children === 'v-if') {
2563 if (singleRoot) {
2564 // has more than 1 non-comment child, return now
2565 return;
2566 }
2567 else {
2568 singleRoot = child;
2569 }
2570 }
2571 }
2572 else {
2573 return;
2574 }
2575 }
2576 return singleRoot;
2577}
2578const getFunctionalFallthrough = (attrs) => {
2579 let res;
2580 for (const key in attrs) {
2581 if (key === 'class' || key === 'style' || isOn(key)) {
2582 (res || (res = {}))[key] = attrs[key];
2583 }
2584 }
2585 return res;
2586};
2587const filterModelListeners = (attrs, props) => {
2588 const res = {};
2589 for (const key in attrs) {
2590 if (!isModelListener(key) || !(key.slice(9) in props)) {
2591 res[key] = attrs[key];
2592 }
2593 }
2594 return res;
2595};
2596const isElementRoot = (vnode) => {
2597 return (vnode.shapeFlag & 6 /* COMPONENT */ ||
2598 vnode.shapeFlag & 1 /* ELEMENT */ ||
2599 vnode.type === Comment$1 // potential v-if branch switch
2600 );
2601};
2602function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2603 const { props: prevProps, children: prevChildren, component } = prevVNode;
2604 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2605 const emits = component.emitsOptions;
2606 // Parent component's render function was hot-updated. Since this may have
2607 // caused the child component's slots content to have changed, we need to
2608 // force the child to update as well.
2609 if ((prevChildren || nextChildren) && isHmrUpdating) {
2610 return true;
2611 }
2612 // force child update for runtime directive or transition on component vnode.
2613 if (nextVNode.dirs || nextVNode.transition) {
2614 return true;
2615 }
2616 if (optimized && patchFlag >= 0) {
2617 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2618 // slot content that references values that might have changed,
2619 // e.g. in a v-for
2620 return true;
2621 }
2622 if (patchFlag & 16 /* FULL_PROPS */) {
2623 if (!prevProps) {
2624 return !!nextProps;
2625 }
2626 // presence of this flag indicates props are always non-null
2627 return hasPropsChanged(prevProps, nextProps, emits);
2628 }
2629 else if (patchFlag & 8 /* PROPS */) {
2630 const dynamicProps = nextVNode.dynamicProps;
2631 for (let i = 0; i < dynamicProps.length; i++) {
2632 const key = dynamicProps[i];
2633 if (nextProps[key] !== prevProps[key] &&
2634 !isEmitListener(emits, key)) {
2635 return true;
2636 }
2637 }
2638 }
2639 }
2640 else {
2641 // this path is only taken by manually written render functions
2642 // so presence of any children leads to a forced update
2643 if (prevChildren || nextChildren) {
2644 if (!nextChildren || !nextChildren.$stable) {
2645 return true;
2646 }
2647 }
2648 if (prevProps === nextProps) {
2649 return false;
2650 }
2651 if (!prevProps) {
2652 return !!nextProps;
2653 }
2654 if (!nextProps) {
2655 return true;
2656 }
2657 return hasPropsChanged(prevProps, nextProps, emits);
2658 }
2659 return false;
2660}
2661function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2662 const nextKeys = Object.keys(nextProps);
2663 if (nextKeys.length !== Object.keys(prevProps).length) {
2664 return true;
2665 }
2666 for (let i = 0; i < nextKeys.length; i++) {
2667 const key = nextKeys[i];
2668 if (nextProps[key] !== prevProps[key] &&
2669 !isEmitListener(emitsOptions, key)) {
2670 return true;
2671 }
2672 }
2673 return false;
2674}
2675function updateHOCHostEl({ vnode, parent }, el // HostNode
2676) {
2677 while (parent && parent.subTree === vnode) {
2678 (vnode = parent.vnode).el = el;
2679 parent = parent.parent;
2680 }
2681}
2682
2683const isSuspense = (type) => type.__isSuspense;
2684// Suspense exposes a component-like API, and is treated like a component
2685// in the compiler, but internally it's a special built-in type that hooks
2686// directly into the renderer.
2687const SuspenseImpl = {
2688 name: 'Suspense',
2689 // In order to make Suspense tree-shakable, we need to avoid importing it
2690 // directly in the renderer. The renderer checks for the __isSuspense flag
2691 // on a vnode's type and calls the `process` method, passing in renderer
2692 // internals.
2693 __isSuspense: true,
2694 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2695 // platform-specific impl passed from renderer
2696 rendererInternals) {
2697 if (n1 == null) {
2698 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2699 }
2700 else {
2701 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2702 }
2703 },
2704 hydrate: hydrateSuspense,
2705 create: createSuspenseBoundary,
2706 normalize: normalizeSuspenseChildren
2707};
2708// Force-casted public typing for h and TSX props inference
2709const Suspense = (SuspenseImpl
2710 );
2711function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2712 const { p: patch, o: { createElement } } = rendererInternals;
2713 const hiddenContainer = createElement('div');
2714 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2715 // start mounting the content subtree in an off-dom container
2716 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2717 // now check if we have encountered any async deps
2718 if (suspense.deps > 0) {
2719 // has async
2720 // mount the fallback tree
2721 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2722 isSVG, slotScopeIds);
2723 setActiveBranch(suspense, vnode.ssFallback);
2724 }
2725 else {
2726 // Suspense has no async deps. Just resolve.
2727 suspense.resolve();
2728 }
2729}
2730function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2731 const suspense = (n2.suspense = n1.suspense);
2732 suspense.vnode = n2;
2733 n2.el = n1.el;
2734 const newBranch = n2.ssContent;
2735 const newFallback = n2.ssFallback;
2736 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2737 if (pendingBranch) {
2738 suspense.pendingBranch = newBranch;
2739 if (isSameVNodeType(newBranch, pendingBranch)) {
2740 // same root type but content may have changed.
2741 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2742 if (suspense.deps <= 0) {
2743 suspense.resolve();
2744 }
2745 else if (isInFallback) {
2746 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2747 isSVG, slotScopeIds, optimized);
2748 setActiveBranch(suspense, newFallback);
2749 }
2750 }
2751 else {
2752 // toggled before pending tree is resolved
2753 suspense.pendingId++;
2754 if (isHydrating) {
2755 // if toggled before hydration is finished, the current DOM tree is
2756 // no longer valid. set it as the active branch so it will be unmounted
2757 // when resolved
2758 suspense.isHydrating = false;
2759 suspense.activeBranch = pendingBranch;
2760 }
2761 else {
2762 unmount(pendingBranch, parentComponent, suspense);
2763 }
2764 // increment pending ID. this is used to invalidate async callbacks
2765 // reset suspense state
2766 suspense.deps = 0;
2767 // discard effects from pending branch
2768 suspense.effects.length = 0;
2769 // discard previous container
2770 suspense.hiddenContainer = createElement('div');
2771 if (isInFallback) {
2772 // already in fallback state
2773 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2774 if (suspense.deps <= 0) {
2775 suspense.resolve();
2776 }
2777 else {
2778 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2779 isSVG, slotScopeIds, optimized);
2780 setActiveBranch(suspense, newFallback);
2781 }
2782 }
2783 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2784 // toggled "back" to current active branch
2785 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2786 // force resolve
2787 suspense.resolve(true);
2788 }
2789 else {
2790 // switched to a 3rd branch
2791 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2792 if (suspense.deps <= 0) {
2793 suspense.resolve();
2794 }
2795 }
2796 }
2797 }
2798 else {
2799 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2800 // root did not change, just normal patch
2801 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2802 setActiveBranch(suspense, newBranch);
2803 }
2804 else {
2805 // root node toggled
2806 // invoke @pending event
2807 const onPending = n2.props && n2.props.onPending;
2808 if (isFunction(onPending)) {
2809 onPending();
2810 }
2811 // mount pending branch in off-dom container
2812 suspense.pendingBranch = newBranch;
2813 suspense.pendingId++;
2814 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2815 if (suspense.deps <= 0) {
2816 // incoming branch has no async deps, resolve now.
2817 suspense.resolve();
2818 }
2819 else {
2820 const { timeout, pendingId } = suspense;
2821 if (timeout > 0) {
2822 setTimeout(() => {
2823 if (suspense.pendingId === pendingId) {
2824 suspense.fallback(newFallback);
2825 }
2826 }, timeout);
2827 }
2828 else if (timeout === 0) {
2829 suspense.fallback(newFallback);
2830 }
2831 }
2832 }
2833 }
2834}
2835let hasWarned = false;
2836function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2837 /* istanbul ignore if */
2838 if (!hasWarned) {
2839 hasWarned = true;
2840 // @ts-ignore `console.info` cannot be null error
2841 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2842 }
2843 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2844 const timeout = toNumber(vnode.props && vnode.props.timeout);
2845 const suspense = {
2846 vnode,
2847 parent,
2848 parentComponent,
2849 isSVG,
2850 container,
2851 hiddenContainer,
2852 anchor,
2853 deps: 0,
2854 pendingId: 0,
2855 timeout: typeof timeout === 'number' ? timeout : -1,
2856 activeBranch: null,
2857 pendingBranch: null,
2858 isInFallback: true,
2859 isHydrating,
2860 isUnmounted: false,
2861 effects: [],
2862 resolve(resume = false) {
2863 {
2864 if (!resume && !suspense.pendingBranch) {
2865 throw new Error(`suspense.resolve() is called without a pending branch.`);
2866 }
2867 if (suspense.isUnmounted) {
2868 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2869 }
2870 }
2871 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2872 if (suspense.isHydrating) {
2873 suspense.isHydrating = false;
2874 }
2875 else if (!resume) {
2876 const delayEnter = activeBranch &&
2877 pendingBranch.transition &&
2878 pendingBranch.transition.mode === 'out-in';
2879 if (delayEnter) {
2880 activeBranch.transition.afterLeave = () => {
2881 if (pendingId === suspense.pendingId) {
2882 move(pendingBranch, container, anchor, 0 /* ENTER */);
2883 }
2884 };
2885 }
2886 // this is initial anchor on mount
2887 let { anchor } = suspense;
2888 // unmount current active tree
2889 if (activeBranch) {
2890 // if the fallback tree was mounted, it may have been moved
2891 // as part of a parent suspense. get the latest anchor for insertion
2892 anchor = next(activeBranch);
2893 unmount(activeBranch, parentComponent, suspense, true);
2894 }
2895 if (!delayEnter) {
2896 // move content from off-dom container to actual container
2897 move(pendingBranch, container, anchor, 0 /* ENTER */);
2898 }
2899 }
2900 setActiveBranch(suspense, pendingBranch);
2901 suspense.pendingBranch = null;
2902 suspense.isInFallback = false;
2903 // flush buffered effects
2904 // check if there is a pending parent suspense
2905 let parent = suspense.parent;
2906 let hasUnresolvedAncestor = false;
2907 while (parent) {
2908 if (parent.pendingBranch) {
2909 // found a pending parent suspense, merge buffered post jobs
2910 // into that parent
2911 parent.effects.push(...effects);
2912 hasUnresolvedAncestor = true;
2913 break;
2914 }
2915 parent = parent.parent;
2916 }
2917 // no pending parent suspense, flush all jobs
2918 if (!hasUnresolvedAncestor) {
2919 queuePostFlushCb(effects);
2920 }
2921 suspense.effects = [];
2922 // invoke @resolve event
2923 const onResolve = vnode.props && vnode.props.onResolve;
2924 if (isFunction(onResolve)) {
2925 onResolve();
2926 }
2927 },
2928 fallback(fallbackVNode) {
2929 if (!suspense.pendingBranch) {
2930 return;
2931 }
2932 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2933 // invoke @fallback event
2934 const onFallback = vnode.props && vnode.props.onFallback;
2935 if (isFunction(onFallback)) {
2936 onFallback();
2937 }
2938 const anchor = next(activeBranch);
2939 const mountFallback = () => {
2940 if (!suspense.isInFallback) {
2941 return;
2942 }
2943 // mount the fallback tree
2944 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2945 isSVG, slotScopeIds, optimized);
2946 setActiveBranch(suspense, fallbackVNode);
2947 };
2948 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
2949 if (delayEnter) {
2950 activeBranch.transition.afterLeave = mountFallback;
2951 }
2952 // unmount current active branch
2953 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
2954 true // shouldRemove
2955 );
2956 suspense.isInFallback = true;
2957 if (!delayEnter) {
2958 mountFallback();
2959 }
2960 },
2961 move(container, anchor, type) {
2962 suspense.activeBranch &&
2963 move(suspense.activeBranch, container, anchor, type);
2964 suspense.container = container;
2965 },
2966 next() {
2967 return suspense.activeBranch && next(suspense.activeBranch);
2968 },
2969 registerDep(instance, setupRenderEffect) {
2970 const isInPendingSuspense = !!suspense.pendingBranch;
2971 if (isInPendingSuspense) {
2972 suspense.deps++;
2973 }
2974 const hydratedEl = instance.vnode.el;
2975 instance
2976 .asyncDep.catch(err => {
2977 handleError(err, instance, 0 /* SETUP_FUNCTION */);
2978 })
2979 .then(asyncSetupResult => {
2980 // retry when the setup() promise resolves.
2981 // component may have been unmounted before resolve.
2982 if (instance.isUnmounted ||
2983 suspense.isUnmounted ||
2984 suspense.pendingId !== instance.suspenseId) {
2985 return;
2986 }
2987 // retry from this component
2988 instance.asyncResolved = true;
2989 const { vnode } = instance;
2990 {
2991 pushWarningContext(vnode);
2992 }
2993 handleSetupResult(instance, asyncSetupResult, false);
2994 if (hydratedEl) {
2995 // vnode may have been replaced if an update happened before the
2996 // async dep is resolved.
2997 vnode.el = hydratedEl;
2998 }
2999 const placeholder = !hydratedEl && instance.subTree.el;
3000 setupRenderEffect(instance, vnode,
3001 // component may have been moved before resolve.
3002 // if this is not a hydration, instance.subTree will be the comment
3003 // placeholder.
3004 parentNode(hydratedEl || instance.subTree.el),
3005 // anchor will not be used if this is hydration, so only need to
3006 // consider the comment placeholder case.
3007 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
3008 if (placeholder) {
3009 remove(placeholder);
3010 }
3011 updateHOCHostEl(instance, vnode.el);
3012 {
3013 popWarningContext();
3014 }
3015 // only decrease deps count if suspense is not already resolved
3016 if (isInPendingSuspense && --suspense.deps === 0) {
3017 suspense.resolve();
3018 }
3019 });
3020 },
3021 unmount(parentSuspense, doRemove) {
3022 suspense.isUnmounted = true;
3023 if (suspense.activeBranch) {
3024 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
3025 }
3026 if (suspense.pendingBranch) {
3027 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
3028 }
3029 }
3030 };
3031 return suspense;
3032}
3033function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
3034 /* eslint-disable no-restricted-globals */
3035 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
3036 // there are two possible scenarios for server-rendered suspense:
3037 // - success: ssr content should be fully resolved
3038 // - failure: ssr content should be the fallback branch.
3039 // however, on the client we don't really know if it has failed or not
3040 // attempt to hydrate the DOM assuming it has succeeded, but we still
3041 // need to construct a suspense boundary first
3042 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
3043 if (suspense.deps === 0) {
3044 suspense.resolve();
3045 }
3046 return result;
3047 /* eslint-enable no-restricted-globals */
3048}
3049function normalizeSuspenseChildren(vnode) {
3050 const { shapeFlag, children } = vnode;
3051 const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
3052 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
3053 vnode.ssFallback = isSlotChildren
3054 ? normalizeSuspenseSlot(children.fallback)
3055 : createVNode(Comment);
3056}
3057function normalizeSuspenseSlot(s) {
3058 let block;
3059 if (isFunction(s)) {
3060 const isCompiledSlot = s._c;
3061 if (isCompiledSlot) {
3062 // disableTracking: false
3063 // allow block tracking for compiled slots
3064 // (see ./componentRenderContext.ts)
3065 s._d = false;
3066 openBlock();
3067 }
3068 s = s();
3069 if (isCompiledSlot) {
3070 s._d = true;
3071 block = currentBlock;
3072 closeBlock();
3073 }
3074 }
3075 if (isArray(s)) {
3076 const singleChild = filterSingleRoot(s);
3077 if (!singleChild) {
3078 warn(`<Suspense> slots expect a single root node.`);
3079 }
3080 s = singleChild;
3081 }
3082 s = normalizeVNode(s);
3083 if (block) {
3084 s.dynamicChildren = block.filter(c => c !== s);
3085 }
3086 return s;
3087}
3088function queueEffectWithSuspense(fn, suspense) {
3089 if (suspense && suspense.pendingBranch) {
3090 if (isArray(fn)) {
3091 suspense.effects.push(...fn);
3092 }
3093 else {
3094 suspense.effects.push(fn);
3095 }
3096 }
3097 else {
3098 queuePostFlushCb(fn);
3099 }
3100}
3101function setActiveBranch(suspense, branch) {
3102 suspense.activeBranch = branch;
3103 const { vnode, parentComponent } = suspense;
3104 const el = (vnode.el = branch.el);
3105 // in case suspense is the root node of a component,
3106 // recursively update the HOC el
3107 if (parentComponent && parentComponent.subTree === vnode) {
3108 parentComponent.vnode.el = el;
3109 updateHOCHostEl(parentComponent, el);
3110 }
3111}
3112
3113function provide(key, value) {
3114 if (!currentInstance) {
3115 {
3116 warn(`provide() can only be used inside setup().`);
3117 }
3118 }
3119 else {
3120 let provides = currentInstance.provides;
3121 // by default an instance inherits its parent's provides object
3122 // but when it needs to provide values of its own, it creates its
3123 // own provides object using parent provides object as prototype.
3124 // this way in `inject` we can simply look up injections from direct
3125 // parent and let the prototype chain do the work.
3126 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
3127 if (parentProvides === provides) {
3128 provides = currentInstance.provides = Object.create(parentProvides);
3129 }
3130 // TS doesn't allow symbol as index type
3131 provides[key] = value;
3132 }
3133}
3134function inject(key, defaultValue, treatDefaultAsFactory = false) {
3135 // fallback to `currentRenderingInstance` so that this can be called in
3136 // a functional component
3137 const instance = currentInstance || currentRenderingInstance;
3138 if (instance) {
3139 // #2400
3140 // to support `app.use` plugins,
3141 // fallback to appContext's `provides` if the intance is at root
3142 const provides = instance.parent == null
3143 ? instance.vnode.appContext && instance.vnode.appContext.provides
3144 : instance.parent.provides;
3145 if (provides && key in provides) {
3146 // TS doesn't allow symbol as index type
3147 return provides[key];
3148 }
3149 else if (arguments.length > 1) {
3150 return treatDefaultAsFactory && isFunction(defaultValue)
3151 ? defaultValue()
3152 : defaultValue;
3153 }
3154 else {
3155 warn(`injection "${String(key)}" not found.`);
3156 }
3157 }
3158 else {
3159 warn(`inject() can only be used inside setup() or functional components.`);
3160 }
3161}
3162
3163// Simple effect.
3164function watchEffect(effect, options) {
3165 return doWatch(effect, null, options);
3166}
3167// initial value for watchers to trigger on undefined initial values
3168const INITIAL_WATCHER_VALUE = {};
3169// implementation
3170function watch(source, cb, options) {
3171 if (!isFunction(cb)) {
3172 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3173 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3174 `supports \`watch(source, cb, options?) signature.`);
3175 }
3176 return doWatch(source, cb, options);
3177}
3178function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
3179 if (!cb) {
3180 if (immediate !== undefined) {
3181 warn(`watch() "immediate" option is only respected when using the ` +
3182 `watch(source, callback, options?) signature.`);
3183 }
3184 if (deep !== undefined) {
3185 warn(`watch() "deep" option is only respected when using the ` +
3186 `watch(source, callback, options?) signature.`);
3187 }
3188 }
3189 const warnInvalidSource = (s) => {
3190 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3191 `a reactive object, or an array of these types.`);
3192 };
3193 let getter;
3194 let forceTrigger = false;
3195 let isMultiSource = false;
3196 if (isRef(source)) {
3197 getter = () => source.value;
3198 forceTrigger = !!source._shallow;
3199 }
3200 else if (isReactive(source)) {
3201 getter = () => source;
3202 deep = true;
3203 }
3204 else if (isArray(source)) {
3205 isMultiSource = true;
3206 forceTrigger = source.some(isReactive);
3207 getter = () => source.map(s => {
3208 if (isRef(s)) {
3209 return s.value;
3210 }
3211 else if (isReactive(s)) {
3212 return traverse(s);
3213 }
3214 else if (isFunction(s)) {
3215 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
3216 }
3217 else {
3218 warnInvalidSource(s);
3219 }
3220 });
3221 }
3222 else if (isFunction(source)) {
3223 if (cb) {
3224 // getter with cb
3225 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
3226 }
3227 else {
3228 // no cb -> simple effect
3229 getter = () => {
3230 if (instance && instance.isUnmounted) {
3231 return;
3232 }
3233 if (cleanup) {
3234 cleanup();
3235 }
3236 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
3237 };
3238 }
3239 }
3240 else {
3241 getter = NOOP;
3242 warnInvalidSource(source);
3243 }
3244 if (cb && deep) {
3245 const baseGetter = getter;
3246 getter = () => traverse(baseGetter());
3247 }
3248 let cleanup;
3249 let onInvalidate = (fn) => {
3250 cleanup = runner.options.onStop = () => {
3251 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3252 };
3253 };
3254 let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;
3255 const job = () => {
3256 if (!runner.active) {
3257 return;
3258 }
3259 if (cb) {
3260 // watch(source, cb)
3261 const newValue = runner();
3262 if (deep ||
3263 forceTrigger ||
3264 (isMultiSource
3265 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
3266 : hasChanged(newValue, oldValue)) ||
3267 (false )) {
3268 // cleanup before running cb again
3269 if (cleanup) {
3270 cleanup();
3271 }
3272 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3273 newValue,
3274 // pass undefined as the old value when it's changed for the first time
3275 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3276 onInvalidate
3277 ]);
3278 oldValue = newValue;
3279 }
3280 }
3281 else {
3282 // watchEffect
3283 runner();
3284 }
3285 };
3286 // important: mark the job as a watcher callback so that scheduler knows
3287 // it is allowed to self-trigger (#1727)
3288 job.allowRecurse = !!cb;
3289 let scheduler;
3290 if (flush === 'sync') {
3291 scheduler = job; // the scheduler function gets called directly
3292 }
3293 else if (flush === 'post') {
3294 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3295 }
3296 else {
3297 // default: 'pre'
3298 scheduler = () => {
3299 if (!instance || instance.isMounted) {
3300 queuePreFlushCb(job);
3301 }
3302 else {
3303 // with 'pre' option, the first call must happen before
3304 // the component is mounted so it is called synchronously.
3305 job();
3306 }
3307 };
3308 }
3309 const runner = effect(getter, {
3310 lazy: true,
3311 onTrack,
3312 onTrigger,
3313 scheduler
3314 });
3315 recordInstanceBoundEffect(runner, instance);
3316 // initial run
3317 if (cb) {
3318 if (immediate) {
3319 job();
3320 }
3321 else {
3322 oldValue = runner();
3323 }
3324 }
3325 else if (flush === 'post') {
3326 queuePostRenderEffect(runner, instance && instance.suspense);
3327 }
3328 else {
3329 runner();
3330 }
3331 return () => {
3332 stop(runner);
3333 if (instance) {
3334 remove(instance.effects, runner);
3335 }
3336 };
3337}
3338// this.$watch
3339function instanceWatch(source, value, options) {
3340 const publicThis = this.proxy;
3341 const getter = isString(source)
3342 ? source.includes('.')
3343 ? createPathGetter(publicThis, source)
3344 : () => publicThis[source]
3345 : source.bind(publicThis, publicThis);
3346 let cb;
3347 if (isFunction(value)) {
3348 cb = value;
3349 }
3350 else {
3351 cb = value.handler;
3352 options = value;
3353 }
3354 return doWatch(getter, cb.bind(publicThis), options, this);
3355}
3356function createPathGetter(ctx, path) {
3357 const segments = path.split('.');
3358 return () => {
3359 let cur = ctx;
3360 for (let i = 0; i < segments.length && cur; i++) {
3361 cur = cur[segments[i]];
3362 }
3363 return cur;
3364 };
3365}
3366function traverse(value, seen = new Set()) {
3367 if (!isObject(value) ||
3368 seen.has(value) ||
3369 value["__v_skip" /* SKIP */]) {
3370 return value;
3371 }
3372 seen.add(value);
3373 if (isRef(value)) {
3374 traverse(value.value, seen);
3375 }
3376 else if (isArray(value)) {
3377 for (let i = 0; i < value.length; i++) {
3378 traverse(value[i], seen);
3379 }
3380 }
3381 else if (isSet(value) || isMap(value)) {
3382 value.forEach((v) => {
3383 traverse(v, seen);
3384 });
3385 }
3386 else if (isPlainObject(value)) {
3387 for (const key in value) {
3388 traverse(value[key], seen);
3389 }
3390 }
3391 return value;
3392}
3393
3394function useTransitionState() {
3395 const state = {
3396 isMounted: false,
3397 isLeaving: false,
3398 isUnmounting: false,
3399 leavingVNodes: new Map()
3400 };
3401 onMounted(() => {
3402 state.isMounted = true;
3403 });
3404 onBeforeUnmount(() => {
3405 state.isUnmounting = true;
3406 });
3407 return state;
3408}
3409const TransitionHookValidator = [Function, Array];
3410const BaseTransitionImpl = {
3411 name: `BaseTransition`,
3412 props: {
3413 mode: String,
3414 appear: Boolean,
3415 persisted: Boolean,
3416 // enter
3417 onBeforeEnter: TransitionHookValidator,
3418 onEnter: TransitionHookValidator,
3419 onAfterEnter: TransitionHookValidator,
3420 onEnterCancelled: TransitionHookValidator,
3421 // leave
3422 onBeforeLeave: TransitionHookValidator,
3423 onLeave: TransitionHookValidator,
3424 onAfterLeave: TransitionHookValidator,
3425 onLeaveCancelled: TransitionHookValidator,
3426 // appear
3427 onBeforeAppear: TransitionHookValidator,
3428 onAppear: TransitionHookValidator,
3429 onAfterAppear: TransitionHookValidator,
3430 onAppearCancelled: TransitionHookValidator
3431 },
3432 setup(props, { slots }) {
3433 const instance = getCurrentInstance();
3434 const state = useTransitionState();
3435 let prevTransitionKey;
3436 return () => {
3437 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3438 if (!children || !children.length) {
3439 return;
3440 }
3441 // warn multiple elements
3442 if (children.length > 1) {
3443 warn('<transition> can only be used on a single element or component. Use ' +
3444 '<transition-group> for lists.');
3445 }
3446 // there's no need to track reactivity for these props so use the raw
3447 // props for a bit better perf
3448 const rawProps = toRaw(props);
3449 const { mode } = rawProps;
3450 // check mode
3451 if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
3452 warn(`invalid <transition> mode: ${mode}`);
3453 }
3454 // at this point children has a guaranteed length of 1.
3455 const child = children[0];
3456 if (state.isLeaving) {
3457 return emptyPlaceholder(child);
3458 }
3459 // in the case of <transition><keep-alive/></transition>, we need to
3460 // compare the type of the kept-alive children.
3461 const innerChild = getKeepAliveChild(child);
3462 if (!innerChild) {
3463 return emptyPlaceholder(child);
3464 }
3465 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3466 setTransitionHooks(innerChild, enterHooks);
3467 const oldChild = instance.subTree;
3468 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3469 let transitionKeyChanged = false;
3470 const { getTransitionKey } = innerChild.type;
3471 if (getTransitionKey) {
3472 const key = getTransitionKey();
3473 if (prevTransitionKey === undefined) {
3474 prevTransitionKey = key;
3475 }
3476 else if (key !== prevTransitionKey) {
3477 prevTransitionKey = key;
3478 transitionKeyChanged = true;
3479 }
3480 }
3481 // handle mode
3482 if (oldInnerChild &&
3483 oldInnerChild.type !== Comment$1 &&
3484 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3485 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3486 // update old tree's hooks in case of dynamic transition
3487 setTransitionHooks(oldInnerChild, leavingHooks);
3488 // switching between different views
3489 if (mode === 'out-in') {
3490 state.isLeaving = true;
3491 // return placeholder node and queue update when leave finishes
3492 leavingHooks.afterLeave = () => {
3493 state.isLeaving = false;
3494 instance.update();
3495 };
3496 return emptyPlaceholder(child);
3497 }
3498 else if (mode === 'in-out' && innerChild.type !== Comment$1) {
3499 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3500 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3501 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3502 // early removal callback
3503 el._leaveCb = () => {
3504 earlyRemove();
3505 el._leaveCb = undefined;
3506 delete enterHooks.delayedLeave;
3507 };
3508 enterHooks.delayedLeave = delayedLeave;
3509 };
3510 }
3511 }
3512 return child;
3513 };
3514 }
3515};
3516// export the public type for h/tsx inference
3517// also to avoid inline import() in generated d.ts files
3518const BaseTransition = BaseTransitionImpl;
3519function getLeavingNodesForType(state, vnode) {
3520 const { leavingVNodes } = state;
3521 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3522 if (!leavingVNodesCache) {
3523 leavingVNodesCache = Object.create(null);
3524 leavingVNodes.set(vnode.type, leavingVNodesCache);
3525 }
3526 return leavingVNodesCache;
3527}
3528// The transition hooks are attached to the vnode as vnode.transition
3529// and will be called at appropriate timing in the renderer.
3530function resolveTransitionHooks(vnode, props, state, instance) {
3531 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3532 const key = String(vnode.key);
3533 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3534 const callHook = (hook, args) => {
3535 hook &&
3536 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3537 };
3538 const hooks = {
3539 mode,
3540 persisted,
3541 beforeEnter(el) {
3542 let hook = onBeforeEnter;
3543 if (!state.isMounted) {
3544 if (appear) {
3545 hook = onBeforeAppear || onBeforeEnter;
3546 }
3547 else {
3548 return;
3549 }
3550 }
3551 // for same element (v-show)
3552 if (el._leaveCb) {
3553 el._leaveCb(true /* cancelled */);
3554 }
3555 // for toggled element with same key (v-if)
3556 const leavingVNode = leavingVNodesCache[key];
3557 if (leavingVNode &&
3558 isSameVNodeType(vnode, leavingVNode) &&
3559 leavingVNode.el._leaveCb) {
3560 // force early removal (not cancelled)
3561 leavingVNode.el._leaveCb();
3562 }
3563 callHook(hook, [el]);
3564 },
3565 enter(el) {
3566 let hook = onEnter;
3567 let afterHook = onAfterEnter;
3568 let cancelHook = onEnterCancelled;
3569 if (!state.isMounted) {
3570 if (appear) {
3571 hook = onAppear || onEnter;
3572 afterHook = onAfterAppear || onAfterEnter;
3573 cancelHook = onAppearCancelled || onEnterCancelled;
3574 }
3575 else {
3576 return;
3577 }
3578 }
3579 let called = false;
3580 const done = (el._enterCb = (cancelled) => {
3581 if (called)
3582 return;
3583 called = true;
3584 if (cancelled) {
3585 callHook(cancelHook, [el]);
3586 }
3587 else {
3588 callHook(afterHook, [el]);
3589 }
3590 if (hooks.delayedLeave) {
3591 hooks.delayedLeave();
3592 }
3593 el._enterCb = undefined;
3594 });
3595 if (hook) {
3596 hook(el, done);
3597 if (hook.length <= 1) {
3598 done();
3599 }
3600 }
3601 else {
3602 done();
3603 }
3604 },
3605 leave(el, remove) {
3606 const key = String(vnode.key);
3607 if (el._enterCb) {
3608 el._enterCb(true /* cancelled */);
3609 }
3610 if (state.isUnmounting) {
3611 return remove();
3612 }
3613 callHook(onBeforeLeave, [el]);
3614 let called = false;
3615 const done = (el._leaveCb = (cancelled) => {
3616 if (called)
3617 return;
3618 called = true;
3619 remove();
3620 if (cancelled) {
3621 callHook(onLeaveCancelled, [el]);
3622 }
3623 else {
3624 callHook(onAfterLeave, [el]);
3625 }
3626 el._leaveCb = undefined;
3627 if (leavingVNodesCache[key] === vnode) {
3628 delete leavingVNodesCache[key];
3629 }
3630 });
3631 leavingVNodesCache[key] = vnode;
3632 if (onLeave) {
3633 onLeave(el, done);
3634 if (onLeave.length <= 1) {
3635 done();
3636 }
3637 }
3638 else {
3639 done();
3640 }
3641 },
3642 clone(vnode) {
3643 return resolveTransitionHooks(vnode, props, state, instance);
3644 }
3645 };
3646 return hooks;
3647}
3648// the placeholder really only handles one special case: KeepAlive
3649// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3650// placeholder with empty content to avoid the KeepAlive instance from being
3651// unmounted.
3652function emptyPlaceholder(vnode) {
3653 if (isKeepAlive(vnode)) {
3654 vnode = cloneVNode(vnode);
3655 vnode.children = null;
3656 return vnode;
3657 }
3658}
3659function getKeepAliveChild(vnode) {
3660 return isKeepAlive(vnode)
3661 ? vnode.children
3662 ? vnode.children[0]
3663 : undefined
3664 : vnode;
3665}
3666function setTransitionHooks(vnode, hooks) {
3667 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3668 setTransitionHooks(vnode.component.subTree, hooks);
3669 }
3670 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3671 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3672 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3673 }
3674 else {
3675 vnode.transition = hooks;
3676 }
3677}
3678function getTransitionRawChildren(children, keepComment = false) {
3679 let ret = [];
3680 let keyedFragmentCount = 0;
3681 for (let i = 0; i < children.length; i++) {
3682 const child = children[i];
3683 // handle fragment children case, e.g. v-for
3684 if (child.type === Fragment) {
3685 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3686 keyedFragmentCount++;
3687 ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
3688 }
3689 // comment placeholders should be skipped, e.g. v-if
3690 else if (keepComment || child.type !== Comment$1) {
3691 ret.push(child);
3692 }
3693 }
3694 // #1126 if a transition children list contains multiple sub fragments, these
3695 // fragments will be merged into a flat children array. Since each v-for
3696 // fragment may contain different static bindings inside, we need to de-op
3697 // these children to force full diffs to ensure correct behavior.
3698 if (keyedFragmentCount > 1) {
3699 for (let i = 0; i < ret.length; i++) {
3700 ret[i].patchFlag = -2 /* BAIL */;
3701 }
3702 }
3703 return ret;
3704}
3705
3706// implementation, close to no-op
3707function defineComponent(options) {
3708 return isFunction(options) ? { setup: options, name: options.name } : options;
3709}
3710
3711const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
3712function defineAsyncComponent(source) {
3713 if (isFunction(source)) {
3714 source = { loader: source };
3715 }
3716 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
3717 suspensible = true, onError: userOnError } = source;
3718 let pendingRequest = null;
3719 let resolvedComp;
3720 let retries = 0;
3721 const retry = () => {
3722 retries++;
3723 pendingRequest = null;
3724 return load();
3725 };
3726 const load = () => {
3727 let thisRequest;
3728 return (pendingRequest ||
3729 (thisRequest = pendingRequest = loader()
3730 .catch(err => {
3731 err = err instanceof Error ? err : new Error(String(err));
3732 if (userOnError) {
3733 return new Promise((resolve, reject) => {
3734 const userRetry = () => resolve(retry());
3735 const userFail = () => reject(err);
3736 userOnError(err, userRetry, userFail, retries + 1);
3737 });
3738 }
3739 else {
3740 throw err;
3741 }
3742 })
3743 .then((comp) => {
3744 if (thisRequest !== pendingRequest && pendingRequest) {
3745 return pendingRequest;
3746 }
3747 if (!comp) {
3748 warn(`Async component loader resolved to undefined. ` +
3749 `If you are using retry(), make sure to return its return value.`);
3750 }
3751 // interop module default
3752 if (comp &&
3753 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3754 comp = comp.default;
3755 }
3756 if (comp && !isObject(comp) && !isFunction(comp)) {
3757 throw new Error(`Invalid async component load result: ${comp}`);
3758 }
3759 resolvedComp = comp;
3760 return comp;
3761 })));
3762 };
3763 return defineComponent({
3764 name: 'AsyncComponentWrapper',
3765 __asyncLoader: load,
3766 get __asyncResolved() {
3767 return resolvedComp;
3768 },
3769 setup() {
3770 const instance = currentInstance;
3771 // already resolved
3772 if (resolvedComp) {
3773 return () => createInnerComp(resolvedComp, instance);
3774 }
3775 const onError = (err) => {
3776 pendingRequest = null;
3777 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3778 };
3779 // suspense-controlled or SSR.
3780 if ((suspensible && instance.suspense) ||
3781 (false )) {
3782 return load()
3783 .then(comp => {
3784 return () => createInnerComp(comp, instance);
3785 })
3786 .catch(err => {
3787 onError(err);
3788 return () => errorComponent
3789 ? createVNode(errorComponent, {
3790 error: err
3791 })
3792 : null;
3793 });
3794 }
3795 const loaded = ref(false);
3796 const error = ref();
3797 const delayed = ref(!!delay);
3798 if (delay) {
3799 setTimeout(() => {
3800 delayed.value = false;
3801 }, delay);
3802 }
3803 if (timeout != null) {
3804 setTimeout(() => {
3805 if (!loaded.value && !error.value) {
3806 const err = new Error(`Async component timed out after ${timeout}ms.`);
3807 onError(err);
3808 error.value = err;
3809 }
3810 }, timeout);
3811 }
3812 load()
3813 .then(() => {
3814 loaded.value = true;
3815 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3816 // parent is keep-alive, force update so the loaded component's
3817 // name is taken into account
3818 queueJob(instance.parent.update);
3819 }
3820 })
3821 .catch(err => {
3822 onError(err);
3823 error.value = err;
3824 });
3825 return () => {
3826 if (loaded.value && resolvedComp) {
3827 return createInnerComp(resolvedComp, instance);
3828 }
3829 else if (error.value && errorComponent) {
3830 return createVNode(errorComponent, {
3831 error: error.value
3832 });
3833 }
3834 else if (loadingComponent && !delayed.value) {
3835 return createVNode(loadingComponent);
3836 }
3837 };
3838 }
3839 });
3840}
3841function createInnerComp(comp, { vnode: { ref, props, children } }) {
3842 const vnode = createVNode(comp, props, children);
3843 // ensure inner component inherits the async wrapper's ref owner
3844 vnode.ref = ref;
3845 return vnode;
3846}
3847
3848const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3849const KeepAliveImpl = {
3850 name: `KeepAlive`,
3851 // Marker for special handling inside the renderer. We are not using a ===
3852 // check directly on KeepAlive in the renderer, because importing it directly
3853 // would prevent it from being tree-shaken.
3854 __isKeepAlive: true,
3855 props: {
3856 include: [String, RegExp, Array],
3857 exclude: [String, RegExp, Array],
3858 max: [String, Number]
3859 },
3860 setup(props, { slots }) {
3861 const instance = getCurrentInstance();
3862 // KeepAlive communicates with the instantiated renderer via the
3863 // ctx where the renderer passes in its internals,
3864 // and the KeepAlive instance exposes activate/deactivate implementations.
3865 // The whole point of this is to avoid importing KeepAlive directly in the
3866 // renderer to facilitate tree-shaking.
3867 const sharedContext = instance.ctx;
3868 // if the internal renderer is not registered, it indicates that this is server-side rendering,
3869 // for KeepAlive, we just need to render its children
3870 if (!sharedContext.renderer) {
3871 return slots.default;
3872 }
3873 const cache = new Map();
3874 const keys = new Set();
3875 let current = null;
3876 {
3877 instance.__v_cache = cache;
3878 }
3879 const parentSuspense = instance.suspense;
3880 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3881 const storageContainer = createElement('div');
3882 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3883 const instance = vnode.component;
3884 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3885 // in case props have changed
3886 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3887 queuePostRenderEffect(() => {
3888 instance.isDeactivated = false;
3889 if (instance.a) {
3890 invokeArrayFns(instance.a);
3891 }
3892 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3893 if (vnodeHook) {
3894 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3895 }
3896 }, parentSuspense);
3897 {
3898 // Update components tree
3899 devtoolsComponentAdded(instance);
3900 }
3901 };
3902 sharedContext.deactivate = (vnode) => {
3903 const instance = vnode.component;
3904 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3905 queuePostRenderEffect(() => {
3906 if (instance.da) {
3907 invokeArrayFns(instance.da);
3908 }
3909 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3910 if (vnodeHook) {
3911 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3912 }
3913 instance.isDeactivated = true;
3914 }, parentSuspense);
3915 {
3916 // Update components tree
3917 devtoolsComponentAdded(instance);
3918 }
3919 };
3920 function unmount(vnode) {
3921 // reset the shapeFlag so it can be properly unmounted
3922 resetShapeFlag(vnode);
3923 _unmount(vnode, instance, parentSuspense);
3924 }
3925 function pruneCache(filter) {
3926 cache.forEach((vnode, key) => {
3927 const name = getComponentName(vnode.type);
3928 if (name && (!filter || !filter(name))) {
3929 pruneCacheEntry(key);
3930 }
3931 });
3932 }
3933 function pruneCacheEntry(key) {
3934 const cached = cache.get(key);
3935 if (!current || cached.type !== current.type) {
3936 unmount(cached);
3937 }
3938 else if (current) {
3939 // current active instance should no longer be kept-alive.
3940 // we can't unmount it now but it might be later, so reset its flag now.
3941 resetShapeFlag(current);
3942 }
3943 cache.delete(key);
3944 keys.delete(key);
3945 }
3946 // prune cache on include/exclude prop change
3947 watch(() => [props.include, props.exclude], ([include, exclude]) => {
3948 include && pruneCache(name => matches(include, name));
3949 exclude && pruneCache(name => !matches(exclude, name));
3950 },
3951 // prune post-render after `current` has been updated
3952 { flush: 'post', deep: true });
3953 // cache sub tree after render
3954 let pendingCacheKey = null;
3955 const cacheSubtree = () => {
3956 // fix #1621, the pendingCacheKey could be 0
3957 if (pendingCacheKey != null) {
3958 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
3959 }
3960 };
3961 onMounted(cacheSubtree);
3962 onUpdated(cacheSubtree);
3963 onBeforeUnmount(() => {
3964 cache.forEach(cached => {
3965 const { subTree, suspense } = instance;
3966 const vnode = getInnerChild(subTree);
3967 if (cached.type === vnode.type) {
3968 // current instance will be unmounted as part of keep-alive's unmount
3969 resetShapeFlag(vnode);
3970 // but invoke its deactivated hook here
3971 const da = vnode.component.da;
3972 da && queuePostRenderEffect(da, suspense);
3973 return;
3974 }
3975 unmount(cached);
3976 });
3977 });
3978 return () => {
3979 pendingCacheKey = null;
3980 if (!slots.default) {
3981 return null;
3982 }
3983 const children = slots.default();
3984 const rawVNode = children[0];
3985 if (children.length > 1) {
3986 {
3987 warn(`KeepAlive should contain exactly one component child.`);
3988 }
3989 current = null;
3990 return children;
3991 }
3992 else if (!isVNode(rawVNode) ||
3993 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
3994 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
3995 current = null;
3996 return rawVNode;
3997 }
3998 let vnode = getInnerChild(rawVNode);
3999 const comp = vnode.type;
4000 // for async components, name check should be based in its loaded
4001 // inner component if available
4002 const name = getComponentName(isAsyncWrapper(vnode)
4003 ? vnode.type.__asyncResolved || {}
4004 : comp);
4005 const { include, exclude, max } = props;
4006 if ((include && (!name || !matches(include, name))) ||
4007 (exclude && name && matches(exclude, name))) {
4008 current = vnode;
4009 return rawVNode;
4010 }
4011 const key = vnode.key == null ? comp : vnode.key;
4012 const cachedVNode = cache.get(key);
4013 // clone vnode if it's reused because we are going to mutate it
4014 if (vnode.el) {
4015 vnode = cloneVNode(vnode);
4016 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
4017 rawVNode.ssContent = vnode;
4018 }
4019 }
4020 // #1513 it's possible for the returned vnode to be cloned due to attr
4021 // fallthrough or scopeId, so the vnode here may not be the final vnode
4022 // that is mounted. Instead of caching it directly, we store the pending
4023 // key and cache `instance.subTree` (the normalized vnode) in
4024 // beforeMount/beforeUpdate hooks.
4025 pendingCacheKey = key;
4026 if (cachedVNode) {
4027 // copy over mounted state
4028 vnode.el = cachedVNode.el;
4029 vnode.component = cachedVNode.component;
4030 if (vnode.transition) {
4031 // recursively update transition hooks on subTree
4032 setTransitionHooks(vnode, vnode.transition);
4033 }
4034 // avoid vnode being mounted as fresh
4035 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
4036 // make this key the freshest
4037 keys.delete(key);
4038 keys.add(key);
4039 }
4040 else {
4041 keys.add(key);
4042 // prune oldest entry
4043 if (max && keys.size > parseInt(max, 10)) {
4044 pruneCacheEntry(keys.values().next().value);
4045 }
4046 }
4047 // avoid vnode being unmounted
4048 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4049 current = vnode;
4050 return rawVNode;
4051 };
4052 }
4053};
4054// export the public type for h/tsx inference
4055// also to avoid inline import() in generated d.ts files
4056const KeepAlive = KeepAliveImpl;
4057function matches(pattern, name) {
4058 if (isArray(pattern)) {
4059 return pattern.some((p) => matches(p, name));
4060 }
4061 else if (isString(pattern)) {
4062 return pattern.split(',').indexOf(name) > -1;
4063 }
4064 else if (pattern.test) {
4065 return pattern.test(name);
4066 }
4067 /* istanbul ignore next */
4068 return false;
4069}
4070function onActivated(hook, target) {
4071 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
4072}
4073function onDeactivated(hook, target) {
4074 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
4075}
4076function registerKeepAliveHook(hook, type, target = currentInstance) {
4077 // cache the deactivate branch check wrapper for injected hooks so the same
4078 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
4079 // deactivation check".
4080 const wrappedHook = hook.__wdc ||
4081 (hook.__wdc = () => {
4082 // only fire the hook if the target instance is NOT in a deactivated branch.
4083 let current = target;
4084 while (current) {
4085 if (current.isDeactivated) {
4086 return;
4087 }
4088 current = current.parent;
4089 }
4090 hook();
4091 });
4092 injectHook(type, wrappedHook, target);
4093 // In addition to registering it on the target instance, we walk up the parent
4094 // chain and register it on all ancestor instances that are keep-alive roots.
4095 // This avoids the need to walk the entire component tree when invoking these
4096 // hooks, and more importantly, avoids the need to track child components in
4097 // arrays.
4098 if (target) {
4099 let current = target.parent;
4100 while (current && current.parent) {
4101 if (isKeepAlive(current.parent.vnode)) {
4102 injectToKeepAliveRoot(wrappedHook, type, target, current);
4103 }
4104 current = current.parent;
4105 }
4106 }
4107}
4108function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
4109 // injectHook wraps the original for error handling, so make sure to remove
4110 // the wrapped version.
4111 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4112 onUnmounted(() => {
4113 remove(keepAliveRoot[type], injected);
4114 }, target);
4115}
4116function resetShapeFlag(vnode) {
4117 let shapeFlag = vnode.shapeFlag;
4118 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
4119 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4120 }
4121 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
4122 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
4123 }
4124 vnode.shapeFlag = shapeFlag;
4125}
4126function getInnerChild(vnode) {
4127 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
4128}
4129
4130function injectHook(type, hook, target = currentInstance, prepend = false) {
4131 if (target) {
4132 const hooks = target[type] || (target[type] = []);
4133 // cache the error handling wrapper for injected hooks so the same hook
4134 // can be properly deduped by the scheduler. "__weh" stands for "with error
4135 // handling".
4136 const wrappedHook = hook.__weh ||
4137 (hook.__weh = (...args) => {
4138 if (target.isUnmounted) {
4139 return;
4140 }
4141 // disable tracking inside all lifecycle hooks
4142 // since they can potentially be called inside effects.
4143 pauseTracking();
4144 // Set currentInstance during hook invocation.
4145 // This assumes the hook does not synchronously trigger other hooks, which
4146 // can only be false when the user does something really funky.
4147 setCurrentInstance(target);
4148 const res = callWithAsyncErrorHandling(hook, target, type, args);
4149 setCurrentInstance(null);
4150 resetTracking();
4151 return res;
4152 });
4153 if (prepend) {
4154 hooks.unshift(wrappedHook);
4155 }
4156 else {
4157 hooks.push(wrappedHook);
4158 }
4159 return wrappedHook;
4160 }
4161 else {
4162 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
4163 warn(`${apiName} is called when there is no active component instance to be ` +
4164 `associated with. ` +
4165 `Lifecycle injection APIs can only be used during execution of setup().` +
4166 (` If you are using async setup(), make sure to register lifecycle ` +
4167 `hooks before the first await statement.`
4168 ));
4169 }
4170}
4171const createHook = (lifecycle) => (hook, target = currentInstance) =>
4172// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
4173(!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
4174 injectHook(lifecycle, hook, target);
4175const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
4176const onMounted = createHook("m" /* MOUNTED */);
4177const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
4178const onUpdated = createHook("u" /* UPDATED */);
4179const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
4180const onUnmounted = createHook("um" /* UNMOUNTED */);
4181const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
4182const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
4183const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
4184function onErrorCaptured(hook, target = currentInstance) {
4185 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
4186}
4187
4188function createDuplicateChecker() {
4189 const cache = Object.create(null);
4190 return (type, key) => {
4191 if (cache[key]) {
4192 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
4193 }
4194 else {
4195 cache[key] = type;
4196 }
4197 };
4198}
4199let shouldCacheAccess = true;
4200function applyOptions(instance) {
4201 const options = resolveMergedOptions(instance);
4202 const publicThis = instance.proxy;
4203 const ctx = instance.ctx;
4204 // do not cache property access on public proxy during state initialization
4205 shouldCacheAccess = false;
4206 // call beforeCreate first before accessing other options since
4207 // the hook may mutate resolved options (#2791)
4208 if (options.beforeCreate) {
4209 callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
4210 }
4211 const {
4212 // state
4213 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
4214 // lifecycle
4215 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
4216 // public API
4217 expose, inheritAttrs,
4218 // assets
4219 components, directives, filters } = options;
4220 const checkDuplicateProperties = createDuplicateChecker() ;
4221 {
4222 const [propsOptions] = instance.propsOptions;
4223 if (propsOptions) {
4224 for (const key in propsOptions) {
4225 checkDuplicateProperties("Props" /* PROPS */, key);
4226 }
4227 }
4228 }
4229 // options initialization order (to be consistent with Vue 2):
4230 // - props (already done outside of this function)
4231 // - inject
4232 // - methods
4233 // - data (deferred since it relies on `this` access)
4234 // - computed
4235 // - watch (deferred since it relies on `this` access)
4236 if (injectOptions) {
4237 resolveInjections(injectOptions, ctx, checkDuplicateProperties);
4238 }
4239 if (methods) {
4240 for (const key in methods) {
4241 const methodHandler = methods[key];
4242 if (isFunction(methodHandler)) {
4243 // In dev mode, we use the `createRenderContext` function to define methods to the proxy target,
4244 // and those are read-only but reconfigurable, so it needs to be redefined here
4245 {
4246 Object.defineProperty(ctx, key, {
4247 value: methodHandler.bind(publicThis),
4248 configurable: true,
4249 enumerable: true,
4250 writable: true
4251 });
4252 }
4253 {
4254 checkDuplicateProperties("Methods" /* METHODS */, key);
4255 }
4256 }
4257 else {
4258 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
4259 `Did you reference the function correctly?`);
4260 }
4261 }
4262 }
4263 if (dataOptions) {
4264 if (!isFunction(dataOptions)) {
4265 warn(`The data option must be a function. ` +
4266 `Plain object usage is no longer supported.`);
4267 }
4268 const data = dataOptions.call(publicThis, publicThis);
4269 if (isPromise(data)) {
4270 warn(`data() returned a Promise - note data() cannot be async; If you ` +
4271 `intend to perform data fetching before component renders, use ` +
4272 `async setup() + <Suspense>.`);
4273 }
4274 if (!isObject(data)) {
4275 warn(`data() should return an object.`);
4276 }
4277 else {
4278 instance.data = reactive(data);
4279 {
4280 for (const key in data) {
4281 checkDuplicateProperties("Data" /* DATA */, key);
4282 // expose data on ctx during dev
4283 if (key[0] !== '$' && key[0] !== '_') {
4284 Object.defineProperty(ctx, key, {
4285 configurable: true,
4286 enumerable: true,
4287 get: () => data[key],
4288 set: NOOP
4289 });
4290 }
4291 }
4292 }
4293 }
4294 }
4295 // state initialization complete at this point - start caching access
4296 shouldCacheAccess = true;
4297 if (computedOptions) {
4298 for (const key in computedOptions) {
4299 const opt = computedOptions[key];
4300 const get = isFunction(opt)
4301 ? opt.bind(publicThis, publicThis)
4302 : isFunction(opt.get)
4303 ? opt.get.bind(publicThis, publicThis)
4304 : NOOP;
4305 if (get === NOOP) {
4306 warn(`Computed property "${key}" has no getter.`);
4307 }
4308 const set = !isFunction(opt) && isFunction(opt.set)
4309 ? opt.set.bind(publicThis)
4310 : () => {
4311 warn(`Write operation failed: computed property "${key}" is readonly.`);
4312 }
4313 ;
4314 const c = computed$1({
4315 get,
4316 set
4317 });
4318 Object.defineProperty(ctx, key, {
4319 enumerable: true,
4320 configurable: true,
4321 get: () => c.value,
4322 set: v => (c.value = v)
4323 });
4324 {
4325 checkDuplicateProperties("Computed" /* COMPUTED */, key);
4326 }
4327 }
4328 }
4329 if (watchOptions) {
4330 for (const key in watchOptions) {
4331 createWatcher(watchOptions[key], ctx, publicThis, key);
4332 }
4333 }
4334 if (provideOptions) {
4335 const provides = isFunction(provideOptions)
4336 ? provideOptions.call(publicThis)
4337 : provideOptions;
4338 Reflect.ownKeys(provides).forEach(key => {
4339 provide(key, provides[key]);
4340 });
4341 }
4342 if (created) {
4343 callHook(created, instance, "c" /* CREATED */);
4344 }
4345 function registerLifecycleHook(register, hook) {
4346 if (isArray(hook)) {
4347 hook.forEach(_hook => register(_hook.bind(publicThis)));
4348 }
4349 else if (hook) {
4350 register(hook.bind(publicThis));
4351 }
4352 }
4353 registerLifecycleHook(onBeforeMount, beforeMount);
4354 registerLifecycleHook(onMounted, mounted);
4355 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
4356 registerLifecycleHook(onUpdated, updated);
4357 registerLifecycleHook(onActivated, activated);
4358 registerLifecycleHook(onDeactivated, deactivated);
4359 registerLifecycleHook(onErrorCaptured, errorCaptured);
4360 registerLifecycleHook(onRenderTracked, renderTracked);
4361 registerLifecycleHook(onRenderTriggered, renderTriggered);
4362 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
4363 registerLifecycleHook(onUnmounted, unmounted);
4364 registerLifecycleHook(onServerPrefetch, serverPrefetch);
4365 if (isArray(expose)) {
4366 if (expose.length) {
4367 const exposed = instance.exposed || (instance.exposed = proxyRefs({}));
4368 expose.forEach(key => {
4369 exposed[key] = toRef(publicThis, key);
4370 });
4371 }
4372 else if (!instance.exposed) {
4373 instance.exposed = EMPTY_OBJ;
4374 }
4375 }
4376 // options that are handled when creating the instance but also need to be
4377 // applied from mixins
4378 if (render && instance.render === NOOP) {
4379 instance.render = render;
4380 }
4381 if (inheritAttrs != null) {
4382 instance.inheritAttrs = inheritAttrs;
4383 }
4384 // asset options.
4385 if (components)
4386 instance.components = components;
4387 if (directives)
4388 instance.directives = directives;
4389}
4390function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP) {
4391 if (isArray(injectOptions)) {
4392 injectOptions = normalizeInject(injectOptions);
4393 }
4394 for (const key in injectOptions) {
4395 const opt = injectOptions[key];
4396 if (isObject(opt)) {
4397 if ('default' in opt) {
4398 ctx[key] = inject(opt.from || key, opt.default, true /* treat default function as factory */);
4399 }
4400 else {
4401 ctx[key] = inject(opt.from || key);
4402 }
4403 }
4404 else {
4405 ctx[key] = inject(opt);
4406 }
4407 {
4408 checkDuplicateProperties("Inject" /* INJECT */, key);
4409 }
4410 }
4411}
4412function callHook(hook, instance, type) {
4413 callWithAsyncErrorHandling(isArray(hook)
4414 ? hook.map(h => h.bind(instance.proxy))
4415 : hook.bind(instance.proxy), instance, type);
4416}
4417function createWatcher(raw, ctx, publicThis, key) {
4418 const getter = key.includes('.')
4419 ? createPathGetter(publicThis, key)
4420 : () => publicThis[key];
4421 if (isString(raw)) {
4422 const handler = ctx[raw];
4423 if (isFunction(handler)) {
4424 watch(getter, handler);
4425 }
4426 else {
4427 warn(`Invalid watch handler specified by key "${raw}"`, handler);
4428 }
4429 }
4430 else if (isFunction(raw)) {
4431 watch(getter, raw.bind(publicThis));
4432 }
4433 else if (isObject(raw)) {
4434 if (isArray(raw)) {
4435 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
4436 }
4437 else {
4438 const handler = isFunction(raw.handler)
4439 ? raw.handler.bind(publicThis)
4440 : ctx[raw.handler];
4441 if (isFunction(handler)) {
4442 watch(getter, handler, raw);
4443 }
4444 else {
4445 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
4446 }
4447 }
4448 }
4449 else {
4450 warn(`Invalid watch option: "${key}"`, raw);
4451 }
4452}
4453/**
4454 * Resolve merged options and cache it on the component.
4455 * This is done only once per-component since the merging does not involve
4456 * instances.
4457 */
4458function resolveMergedOptions(instance) {
4459 const base = instance.type;
4460 const { mixins, extends: extendsOptions } = base;
4461 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
4462 const cached = cache.get(base);
4463 let resolved;
4464 if (cached) {
4465 resolved = cached;
4466 }
4467 else if (!globalMixins.length && !mixins && !extendsOptions) {
4468 {
4469 resolved = base;
4470 }
4471 }
4472 else {
4473 resolved = {};
4474 if (globalMixins.length) {
4475 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
4476 }
4477 mergeOptions(resolved, base, optionMergeStrategies);
4478 }
4479 cache.set(base, resolved);
4480 return resolved;
4481}
4482function mergeOptions(to, from, strats, asMixin = false) {
4483 const { mixins, extends: extendsOptions } = from;
4484 if (extendsOptions) {
4485 mergeOptions(to, extendsOptions, strats, true);
4486 }
4487 if (mixins) {
4488 mixins.forEach((m) => mergeOptions(to, m, strats, true));
4489 }
4490 for (const key in from) {
4491 if (asMixin && key === 'expose') {
4492 warn(`"expose" option is ignored when declared in mixins or extends. ` +
4493 `It should only be declared in the base component itself.`);
4494 }
4495 else {
4496 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
4497 to[key] = strat ? strat(to[key], from[key]) : from[key];
4498 }
4499 }
4500 return to;
4501}
4502const internalOptionMergeStrats = {
4503 data: mergeDataFn,
4504 props: mergeObjectOptions,
4505 emits: mergeObjectOptions,
4506 // objects
4507 methods: mergeObjectOptions,
4508 computed: mergeObjectOptions,
4509 // lifecycle
4510 beforeCreate: mergeHook,
4511 created: mergeHook,
4512 beforeMount: mergeHook,
4513 mounted: mergeHook,
4514 beforeUpdate: mergeHook,
4515 updated: mergeHook,
4516 beforeDestroy: mergeHook,
4517 destroyed: mergeHook,
4518 activated: mergeHook,
4519 deactivated: mergeHook,
4520 errorCaptured: mergeHook,
4521 serverPrefetch: mergeHook,
4522 // assets
4523 components: mergeObjectOptions,
4524 directives: mergeObjectOptions,
4525 // watch has special merge behavior in v2, but isn't actually needed in v3.
4526 // since we are only exposing these for compat and nobody should be relying
4527 // on the watch-specific behavior, just expose the object merge strat.
4528 watch: mergeObjectOptions,
4529 // provide / inject
4530 provide: mergeDataFn,
4531 inject: mergeInject
4532};
4533function mergeDataFn(to, from) {
4534 if (!from) {
4535 return to;
4536 }
4537 if (!to) {
4538 return from;
4539 }
4540 return function mergedDataFn() {
4541 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
4542 };
4543}
4544function mergeInject(to, from) {
4545 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
4546}
4547function normalizeInject(raw) {
4548 if (isArray(raw)) {
4549 const res = {};
4550 for (let i = 0; i < raw.length; i++) {
4551 res[raw[i]] = raw[i];
4552 }
4553 return res;
4554 }
4555 return raw;
4556}
4557function mergeHook(to, from) {
4558 return to ? [...new Set([].concat(to, from))] : from;
4559}
4560function mergeObjectOptions(to, from) {
4561 return to ? extend(extend(Object.create(null), to), from) : from;
4562}
4563
4564function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
4565isSSR = false) {
4566 const props = {};
4567 const attrs = {};
4568 def(attrs, InternalObjectKey, 1);
4569 instance.propsDefaults = Object.create(null);
4570 setFullProps(instance, rawProps, props, attrs);
4571 // ensure all declared prop keys are present
4572 for (const key in instance.propsOptions[0]) {
4573 if (!(key in props)) {
4574 props[key] = undefined;
4575 }
4576 }
4577 // validation
4578 {
4579 validateProps(rawProps || {}, props, instance);
4580 }
4581 if (isStateful) {
4582 // stateful
4583 instance.props = isSSR ? props : shallowReactive(props);
4584 }
4585 else {
4586 if (!instance.type.props) {
4587 // functional w/ optional props, props === attrs
4588 instance.props = attrs;
4589 }
4590 else {
4591 // functional w/ declared props
4592 instance.props = props;
4593 }
4594 }
4595 instance.attrs = attrs;
4596}
4597function updateProps(instance, rawProps, rawPrevProps, optimized) {
4598 const { props, attrs, vnode: { patchFlag } } = instance;
4599 const rawCurrentProps = toRaw(props);
4600 const [options] = instance.propsOptions;
4601 let hasAttrsChanged = false;
4602 if (
4603 // always force full diff in dev
4604 // - #1942 if hmr is enabled with sfc component
4605 // - vite#872 non-sfc component used by sfc component
4606 !((instance.type.__hmrId ||
4607 (instance.parent && instance.parent.type.__hmrId))) &&
4608 (optimized || patchFlag > 0) &&
4609 !(patchFlag & 16 /* FULL_PROPS */)) {
4610 if (patchFlag & 8 /* PROPS */) {
4611 // Compiler-generated props & no keys change, just set the updated
4612 // the props.
4613 const propsToUpdate = instance.vnode.dynamicProps;
4614 for (let i = 0; i < propsToUpdate.length; i++) {
4615 let key = propsToUpdate[i];
4616 // PROPS flag guarantees rawProps to be non-null
4617 const value = rawProps[key];
4618 if (options) {
4619 // attr / props separation was done on init and will be consistent
4620 // in this code path, so just check if attrs have it.
4621 if (hasOwn(attrs, key)) {
4622 if (value !== attrs[key]) {
4623 attrs[key] = value;
4624 hasAttrsChanged = true;
4625 }
4626 }
4627 else {
4628 const camelizedKey = camelize(key);
4629 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
4630 }
4631 }
4632 else {
4633 if (value !== attrs[key]) {
4634 attrs[key] = value;
4635 hasAttrsChanged = true;
4636 }
4637 }
4638 }
4639 }
4640 }
4641 else {
4642 // full props update.
4643 if (setFullProps(instance, rawProps, props, attrs)) {
4644 hasAttrsChanged = true;
4645 }
4646 // in case of dynamic props, check if we need to delete keys from
4647 // the props object
4648 let kebabKey;
4649 for (const key in rawCurrentProps) {
4650 if (!rawProps ||
4651 // for camelCase
4652 (!hasOwn(rawProps, key) &&
4653 // it's possible the original props was passed in as kebab-case
4654 // and converted to camelCase (#955)
4655 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
4656 if (options) {
4657 if (rawPrevProps &&
4658 // for camelCase
4659 (rawPrevProps[key] !== undefined ||
4660 // for kebab-case
4661 rawPrevProps[kebabKey] !== undefined)) {
4662 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
4663 }
4664 }
4665 else {
4666 delete props[key];
4667 }
4668 }
4669 }
4670 // in the case of functional component w/o props declaration, props and
4671 // attrs point to the same object so it should already have been updated.
4672 if (attrs !== rawCurrentProps) {
4673 for (const key in attrs) {
4674 if (!rawProps || !hasOwn(rawProps, key)) {
4675 delete attrs[key];
4676 hasAttrsChanged = true;
4677 }
4678 }
4679 }
4680 }
4681 // trigger updates for $attrs in case it's used in component slots
4682 if (hasAttrsChanged) {
4683 trigger(instance, "set" /* SET */, '$attrs');
4684 }
4685 {
4686 validateProps(rawProps || {}, props, instance);
4687 }
4688}
4689function setFullProps(instance, rawProps, props, attrs) {
4690 const [options, needCastKeys] = instance.propsOptions;
4691 let hasAttrsChanged = false;
4692 let rawCastValues;
4693 if (rawProps) {
4694 for (let key in rawProps) {
4695 // key, ref are reserved and never passed down
4696 if (isReservedProp(key)) {
4697 continue;
4698 }
4699 const value = rawProps[key];
4700 // prop option names are camelized during normalization, so to support
4701 // kebab -> camel conversion here we need to camelize the key.
4702 let camelKey;
4703 if (options && hasOwn(options, (camelKey = camelize(key)))) {
4704 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
4705 props[camelKey] = value;
4706 }
4707 else {
4708 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
4709 }
4710 }
4711 else if (!isEmitListener(instance.emitsOptions, key)) {
4712 if (value !== attrs[key]) {
4713 attrs[key] = value;
4714 hasAttrsChanged = true;
4715 }
4716 }
4717 }
4718 }
4719 if (needCastKeys) {
4720 const rawCurrentProps = toRaw(props);
4721 const castValues = rawCastValues || EMPTY_OBJ;
4722 for (let i = 0; i < needCastKeys.length; i++) {
4723 const key = needCastKeys[i];
4724 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
4725 }
4726 }
4727 return hasAttrsChanged;
4728}
4729function resolvePropValue(options, props, key, value, instance, isAbsent) {
4730 const opt = options[key];
4731 if (opt != null) {
4732 const hasDefault = hasOwn(opt, 'default');
4733 // default values
4734 if (hasDefault && value === undefined) {
4735 const defaultValue = opt.default;
4736 if (opt.type !== Function && isFunction(defaultValue)) {
4737 const { propsDefaults } = instance;
4738 if (key in propsDefaults) {
4739 value = propsDefaults[key];
4740 }
4741 else {
4742 setCurrentInstance(instance);
4743 value = propsDefaults[key] = defaultValue.call(null, props);
4744 setCurrentInstance(null);
4745 }
4746 }
4747 else {
4748 value = defaultValue;
4749 }
4750 }
4751 // boolean casting
4752 if (opt[0 /* shouldCast */]) {
4753 if (isAbsent && !hasDefault) {
4754 value = false;
4755 }
4756 else if (opt[1 /* shouldCastTrue */] &&
4757 (value === '' || value === hyphenate(key))) {
4758 value = true;
4759 }
4760 }
4761 }
4762 return value;
4763}
4764function normalizePropsOptions(comp, appContext, asMixin = false) {
4765 const cache = appContext.propsCache;
4766 const cached = cache.get(comp);
4767 if (cached) {
4768 return cached;
4769 }
4770 const raw = comp.props;
4771 const normalized = {};
4772 const needCastKeys = [];
4773 // apply mixin/extends props
4774 let hasExtends = false;
4775 if (!isFunction(comp)) {
4776 const extendProps = (raw) => {
4777 hasExtends = true;
4778 const [props, keys] = normalizePropsOptions(raw, appContext, true);
4779 extend(normalized, props);
4780 if (keys)
4781 needCastKeys.push(...keys);
4782 };
4783 if (!asMixin && appContext.mixins.length) {
4784 appContext.mixins.forEach(extendProps);
4785 }
4786 if (comp.extends) {
4787 extendProps(comp.extends);
4788 }
4789 if (comp.mixins) {
4790 comp.mixins.forEach(extendProps);
4791 }
4792 }
4793 if (!raw && !hasExtends) {
4794 cache.set(comp, EMPTY_ARR);
4795 return EMPTY_ARR;
4796 }
4797 if (isArray(raw)) {
4798 for (let i = 0; i < raw.length; i++) {
4799 if (!isString(raw[i])) {
4800 warn(`props must be strings when using array syntax.`, raw[i]);
4801 }
4802 const normalizedKey = camelize(raw[i]);
4803 if (validatePropName(normalizedKey)) {
4804 normalized[normalizedKey] = EMPTY_OBJ;
4805 }
4806 }
4807 }
4808 else if (raw) {
4809 if (!isObject(raw)) {
4810 warn(`invalid props options`, raw);
4811 }
4812 for (const key in raw) {
4813 const normalizedKey = camelize(key);
4814 if (validatePropName(normalizedKey)) {
4815 const opt = raw[key];
4816 const prop = (normalized[normalizedKey] =
4817 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
4818 if (prop) {
4819 const booleanIndex = getTypeIndex(Boolean, prop.type);
4820 const stringIndex = getTypeIndex(String, prop.type);
4821 prop[0 /* shouldCast */] = booleanIndex > -1;
4822 prop[1 /* shouldCastTrue */] =
4823 stringIndex < 0 || booleanIndex < stringIndex;
4824 // if the prop needs boolean casting or default value
4825 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
4826 needCastKeys.push(normalizedKey);
4827 }
4828 }
4829 }
4830 }
4831 }
4832 const res = [normalized, needCastKeys];
4833 cache.set(comp, res);
4834 return res;
4835}
4836function validatePropName(key) {
4837 if (key[0] !== '$') {
4838 return true;
4839 }
4840 else {
4841 warn(`Invalid prop name: "${key}" is a reserved property.`);
4842 }
4843 return false;
4844}
4845// use function string name to check type constructors
4846// so that it works across vms / iframes.
4847function getType(ctor) {
4848 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
4849 return match ? match[1] : '';
4850}
4851function isSameType(a, b) {
4852 return getType(a) === getType(b);
4853}
4854function getTypeIndex(type, expectedTypes) {
4855 if (isArray(expectedTypes)) {
4856 return expectedTypes.findIndex(t => isSameType(t, type));
4857 }
4858 else if (isFunction(expectedTypes)) {
4859 return isSameType(expectedTypes, type) ? 0 : -1;
4860 }
4861 return -1;
4862}
4863/**
4864 * dev only
4865 */
4866function validateProps(rawProps, props, instance) {
4867 const resolvedValues = toRaw(props);
4868 const options = instance.propsOptions[0];
4869 for (const key in options) {
4870 let opt = options[key];
4871 if (opt == null)
4872 continue;
4873 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
4874 }
4875}
4876/**
4877 * dev only
4878 */
4879function validateProp(name, value, prop, isAbsent) {
4880 const { type, required, validator } = prop;
4881 // required!
4882 if (required && isAbsent) {
4883 warn('Missing required prop: "' + name + '"');
4884 return;
4885 }
4886 // missing but optional
4887 if (value == null && !prop.required) {
4888 return;
4889 }
4890 // type check
4891 if (type != null && type !== true) {
4892 let isValid = false;
4893 const types = isArray(type) ? type : [type];
4894 const expectedTypes = [];
4895 // value is valid as long as one of the specified types match
4896 for (let i = 0; i < types.length && !isValid; i++) {
4897 const { valid, expectedType } = assertType(value, types[i]);
4898 expectedTypes.push(expectedType || '');
4899 isValid = valid;
4900 }
4901 if (!isValid) {
4902 warn(getInvalidTypeMessage(name, value, expectedTypes));
4903 return;
4904 }
4905 }
4906 // custom validator
4907 if (validator && !validator(value)) {
4908 warn('Invalid prop: custom validator check failed for prop "' + name + '".');
4909 }
4910}
4911const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
4912/**
4913 * dev only
4914 */
4915function assertType(value, type) {
4916 let valid;
4917 const expectedType = getType(type);
4918 if (isSimpleType(expectedType)) {
4919 const t = typeof value;
4920 valid = t === expectedType.toLowerCase();
4921 // for primitive wrapper objects
4922 if (!valid && t === 'object') {
4923 valid = value instanceof type;
4924 }
4925 }
4926 else if (expectedType === 'Object') {
4927 valid = isObject(value);
4928 }
4929 else if (expectedType === 'Array') {
4930 valid = isArray(value);
4931 }
4932 else {
4933 valid = value instanceof type;
4934 }
4935 return {
4936 valid,
4937 expectedType
4938 };
4939}
4940/**
4941 * dev only
4942 */
4943function getInvalidTypeMessage(name, value, expectedTypes) {
4944 let message = `Invalid prop: type check failed for prop "${name}".` +
4945 ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
4946 const expectedType = expectedTypes[0];
4947 const receivedType = toRawType(value);
4948 const expectedValue = styleValue(value, expectedType);
4949 const receivedValue = styleValue(value, receivedType);
4950 // check if we need to specify expected value
4951 if (expectedTypes.length === 1 &&
4952 isExplicable(expectedType) &&
4953 !isBoolean(expectedType, receivedType)) {
4954 message += ` with value ${expectedValue}`;
4955 }
4956 message += `, got ${receivedType} `;
4957 // check if we need to specify received value
4958 if (isExplicable(receivedType)) {
4959 message += `with value ${receivedValue}.`;
4960 }
4961 return message;
4962}
4963/**
4964 * dev only
4965 */
4966function styleValue(value, type) {
4967 if (type === 'String') {
4968 return `"${value}"`;
4969 }
4970 else if (type === 'Number') {
4971 return `${Number(value)}`;
4972 }
4973 else {
4974 return `${value}`;
4975 }
4976}
4977/**
4978 * dev only
4979 */
4980function isExplicable(type) {
4981 const explicitTypes = ['string', 'number', 'boolean'];
4982 return explicitTypes.some(elem => type.toLowerCase() === elem);
4983}
4984/**
4985 * dev only
4986 */
4987function isBoolean(...args) {
4988 return args.some(elem => elem.toLowerCase() === 'boolean');
4989}
4990
4991const isInternalKey = (key) => key[0] === '_' || key === '$stable';
4992const normalizeSlotValue = (value) => isArray(value)
4993 ? value.map(normalizeVNode)
4994 : [normalizeVNode(value)];
4995const normalizeSlot = (key, rawSlot, ctx) => {
4996 const normalized = withCtx((props) => {
4997 if (currentInstance) {
4998 warn(`Slot "${key}" invoked outside of the render function: ` +
4999 `this will not track dependencies used in the slot. ` +
5000 `Invoke the slot function inside the render function instead.`);
5001 }
5002 return normalizeSlotValue(rawSlot(props));
5003 }, ctx);
5004 normalized._c = false;
5005 return normalized;
5006};
5007const normalizeObjectSlots = (rawSlots, slots, instance) => {
5008 const ctx = rawSlots._ctx;
5009 for (const key in rawSlots) {
5010 if (isInternalKey(key))
5011 continue;
5012 const value = rawSlots[key];
5013 if (isFunction(value)) {
5014 slots[key] = normalizeSlot(key, value, ctx);
5015 }
5016 else if (value != null) {
5017 {
5018 warn(`Non-function value encountered for slot "${key}". ` +
5019 `Prefer function slots for better performance.`);
5020 }
5021 const normalized = normalizeSlotValue(value);
5022 slots[key] = () => normalized;
5023 }
5024 }
5025};
5026const normalizeVNodeSlots = (instance, children) => {
5027 if (!isKeepAlive(instance.vnode) &&
5028 !(false )) {
5029 warn(`Non-function value encountered for default slot. ` +
5030 `Prefer function slots for better performance.`);
5031 }
5032 const normalized = normalizeSlotValue(children);
5033 instance.slots.default = () => normalized;
5034};
5035const initSlots = (instance, children) => {
5036 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5037 const type = children._;
5038 if (type) {
5039 // users can get the shallow readonly version of the slots object through `this.$slots`,
5040 // we should avoid the proxy object polluting the slots of the internal instance
5041 instance.slots = toRaw(children);
5042 // make compiler marker non-enumerable
5043 def(children, '_', type);
5044 }
5045 else {
5046 normalizeObjectSlots(children, (instance.slots = {}));
5047 }
5048 }
5049 else {
5050 instance.slots = {};
5051 if (children) {
5052 normalizeVNodeSlots(instance, children);
5053 }
5054 }
5055 def(instance.slots, InternalObjectKey, 1);
5056};
5057const updateSlots = (instance, children, optimized) => {
5058 const { vnode, slots } = instance;
5059 let needDeletionCheck = true;
5060 let deletionComparisonTarget = EMPTY_OBJ;
5061 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
5062 const type = children._;
5063 if (type) {
5064 // compiled slots.
5065 if (isHmrUpdating) {
5066 // Parent was HMR updated so slot content may have changed.
5067 // force update slots and mark instance for hmr as well
5068 extend(slots, children);
5069 }
5070 else if (optimized && type === 1 /* STABLE */) {
5071 // compiled AND stable.
5072 // no need to update, and skip stale slots removal.
5073 needDeletionCheck = false;
5074 }
5075 else {
5076 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
5077 // normalization.
5078 extend(slots, children);
5079 // #2893
5080 // when rendering the optimized slots by manually written render function,
5081 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
5082 // i.e. let the `renderSlot` create the bailed Fragment
5083 if (!optimized && type === 1 /* STABLE */) {
5084 delete slots._;
5085 }
5086 }
5087 }
5088 else {
5089 needDeletionCheck = !children.$stable;
5090 normalizeObjectSlots(children, slots);
5091 }
5092 deletionComparisonTarget = children;
5093 }
5094 else if (children) {
5095 // non slot object children (direct value) passed to a component
5096 normalizeVNodeSlots(instance, children);
5097 deletionComparisonTarget = { default: 1 };
5098 }
5099 // delete stale slots
5100 if (needDeletionCheck) {
5101 for (const key in slots) {
5102 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
5103 delete slots[key];
5104 }
5105 }
5106 }
5107};
5108
5109/**
5110Runtime helper for applying directives to a vnode. Example usage:
5111
5112const comp = resolveComponent('comp')
5113const foo = resolveDirective('foo')
5114const bar = resolveDirective('bar')
5115
5116return withDirectives(h(comp), [
5117 [foo, this.x],
5118 [bar, this.y]
5119])
5120*/
5121const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
5122function validateDirectiveName(name) {
5123 if (isBuiltInDirective(name)) {
5124 warn('Do not use built-in directive ids as custom directive id: ' + name);
5125 }
5126}
5127/**
5128 * Adds directives to a VNode.
5129 */
5130function withDirectives(vnode, directives) {
5131 const internalInstance = currentRenderingInstance;
5132 if (internalInstance === null) {
5133 warn(`withDirectives can only be used inside render functions.`);
5134 return vnode;
5135 }
5136 const instance = internalInstance.proxy;
5137 const bindings = vnode.dirs || (vnode.dirs = []);
5138 for (let i = 0; i < directives.length; i++) {
5139 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
5140 if (isFunction(dir)) {
5141 dir = {
5142 mounted: dir,
5143 updated: dir
5144 };
5145 }
5146 bindings.push({
5147 dir,
5148 instance,
5149 value,
5150 oldValue: void 0,
5151 arg,
5152 modifiers
5153 });
5154 }
5155 return vnode;
5156}
5157function invokeDirectiveHook(vnode, prevVNode, instance, name) {
5158 const bindings = vnode.dirs;
5159 const oldBindings = prevVNode && prevVNode.dirs;
5160 for (let i = 0; i < bindings.length; i++) {
5161 const binding = bindings[i];
5162 if (oldBindings) {
5163 binding.oldValue = oldBindings[i].value;
5164 }
5165 let hook = binding.dir[name];
5166 if (hook) {
5167 // disable tracking inside all lifecycle hooks
5168 // since they can potentially be called inside effects.
5169 pauseTracking();
5170 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
5171 vnode.el,
5172 binding,
5173 vnode,
5174 prevVNode
5175 ]);
5176 resetTracking();
5177 }
5178 }
5179}
5180
5181function createAppContext() {
5182 return {
5183 app: null,
5184 config: {
5185 isNativeTag: NO,
5186 performance: false,
5187 globalProperties: {},
5188 optionMergeStrategies: {},
5189 errorHandler: undefined,
5190 warnHandler: undefined,
5191 compilerOptions: {}
5192 },
5193 mixins: [],
5194 components: {},
5195 directives: {},
5196 provides: Object.create(null),
5197 optionsCache: new WeakMap(),
5198 propsCache: new WeakMap(),
5199 emitsCache: new WeakMap()
5200 };
5201}
5202let uid$1 = 0;
5203function createAppAPI(render, hydrate) {
5204 return function createApp(rootComponent, rootProps = null) {
5205 if (rootProps != null && !isObject(rootProps)) {
5206 warn(`root props passed to app.mount() must be an object.`);
5207 rootProps = null;
5208 }
5209 const context = createAppContext();
5210 const installedPlugins = new Set();
5211 let isMounted = false;
5212 const app = (context.app = {
5213 _uid: uid$1++,
5214 _component: rootComponent,
5215 _props: rootProps,
5216 _container: null,
5217 _context: context,
5218 version,
5219 get config() {
5220 return context.config;
5221 },
5222 set config(v) {
5223 {
5224 warn(`app.config cannot be replaced. Modify individual options instead.`);
5225 }
5226 },
5227 use(plugin, ...options) {
5228 if (installedPlugins.has(plugin)) {
5229 warn(`Plugin has already been applied to target app.`);
5230 }
5231 else if (plugin && isFunction(plugin.install)) {
5232 installedPlugins.add(plugin);
5233 plugin.install(app, ...options);
5234 }
5235 else if (isFunction(plugin)) {
5236 installedPlugins.add(plugin);
5237 plugin(app, ...options);
5238 }
5239 else {
5240 warn(`A plugin must either be a function or an object with an "install" ` +
5241 `function.`);
5242 }
5243 return app;
5244 },
5245 mixin(mixin) {
5246 {
5247 if (!context.mixins.includes(mixin)) {
5248 context.mixins.push(mixin);
5249 }
5250 else {
5251 warn('Mixin has already been applied to target app' +
5252 (mixin.name ? `: ${mixin.name}` : ''));
5253 }
5254 }
5255 return app;
5256 },
5257 component(name, component) {
5258 {
5259 validateComponentName(name, context.config);
5260 }
5261 if (!component) {
5262 return context.components[name];
5263 }
5264 if (context.components[name]) {
5265 warn(`Component "${name}" has already been registered in target app.`);
5266 }
5267 context.components[name] = component;
5268 return app;
5269 },
5270 directive(name, directive) {
5271 {
5272 validateDirectiveName(name);
5273 }
5274 if (!directive) {
5275 return context.directives[name];
5276 }
5277 if (context.directives[name]) {
5278 warn(`Directive "${name}" has already been registered in target app.`);
5279 }
5280 context.directives[name] = directive;
5281 return app;
5282 },
5283 mount(rootContainer, isHydrate, isSVG) {
5284 if (!isMounted) {
5285 const vnode = createVNode(rootComponent, rootProps);
5286 // store app context on the root VNode.
5287 // this will be set on the root instance on initial mount.
5288 vnode.appContext = context;
5289 // HMR root reload
5290 {
5291 context.reload = () => {
5292 render(cloneVNode(vnode), rootContainer, isSVG);
5293 };
5294 }
5295 if (isHydrate && hydrate) {
5296 hydrate(vnode, rootContainer);
5297 }
5298 else {
5299 render(vnode, rootContainer, isSVG);
5300 }
5301 isMounted = true;
5302 app._container = rootContainer;
5303 rootContainer.__vue_app__ = app;
5304 {
5305 devtoolsInitApp(app, version);
5306 }
5307 return vnode.component.proxy;
5308 }
5309 else {
5310 warn(`App has already been mounted.\n` +
5311 `If you want to remount the same app, move your app creation logic ` +
5312 `into a factory function and create fresh app instances for each ` +
5313 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
5314 }
5315 },
5316 unmount() {
5317 if (isMounted) {
5318 render(null, app._container);
5319 {
5320 devtoolsUnmountApp(app);
5321 }
5322 delete app._container.__vue_app__;
5323 }
5324 else {
5325 warn(`Cannot unmount an app that is not mounted.`);
5326 }
5327 },
5328 provide(key, value) {
5329 if (key in context.provides) {
5330 warn(`App already provides property with key "${String(key)}". ` +
5331 `It will be overwritten with the new value.`);
5332 }
5333 // TypeScript doesn't allow symbols as index type
5334 // https://github.com/Microsoft/TypeScript/issues/24587
5335 context.provides[key] = value;
5336 return app;
5337 }
5338 });
5339 return app;
5340 };
5341}
5342
5343let hasMismatch = false;
5344const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
5345const isComment = (node) => node.nodeType === 8 /* COMMENT */;
5346// Note: hydration is DOM-specific
5347// But we have to place it in core due to tight coupling with core - splitting
5348// it out creates a ton of unnecessary complexity.
5349// Hydration also depends on some renderer internal logic which needs to be
5350// passed in via arguments.
5351function createHydrationFunctions(rendererInternals) {
5352 const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
5353 const hydrate = (vnode, container) => {
5354 if (!container.hasChildNodes()) {
5355 warn(`Attempting to hydrate existing markup but container is empty. ` +
5356 `Performing full mount instead.`);
5357 patch(null, vnode, container);
5358 return;
5359 }
5360 hasMismatch = false;
5361 hydrateNode(container.firstChild, vnode, null, null, null);
5362 flushPostFlushCbs();
5363 if (hasMismatch && !false) {
5364 // this error should show up in production
5365 console.error(`Hydration completed but contains mismatches.`);
5366 }
5367 };
5368 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
5369 const isFragmentStart = isComment(node) && node.data === '[';
5370 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
5371 const { type, ref, shapeFlag } = vnode;
5372 const domType = node.nodeType;
5373 vnode.el = node;
5374 let nextNode = null;
5375 switch (type) {
5376 case Text:
5377 if (domType !== 3 /* TEXT */) {
5378 nextNode = onMismatch();
5379 }
5380 else {
5381 if (node.data !== vnode.children) {
5382 hasMismatch = true;
5383 warn(`Hydration text mismatch:` +
5384 `\n- Client: ${JSON.stringify(node.data)}` +
5385 `\n- Server: ${JSON.stringify(vnode.children)}`);
5386 node.data = vnode.children;
5387 }
5388 nextNode = nextSibling(node);
5389 }
5390 break;
5391 case Comment$1:
5392 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
5393 nextNode = onMismatch();
5394 }
5395 else {
5396 nextNode = nextSibling(node);
5397 }
5398 break;
5399 case Static:
5400 if (domType !== 1 /* ELEMENT */) {
5401 nextNode = onMismatch();
5402 }
5403 else {
5404 // determine anchor, adopt content
5405 nextNode = node;
5406 // if the static vnode has its content stripped during build,
5407 // adopt it from the server-rendered HTML.
5408 const needToAdoptContent = !vnode.children.length;
5409 for (let i = 0; i < vnode.staticCount; i++) {
5410 if (needToAdoptContent)
5411 vnode.children += nextNode.outerHTML;
5412 if (i === vnode.staticCount - 1) {
5413 vnode.anchor = nextNode;
5414 }
5415 nextNode = nextSibling(nextNode);
5416 }
5417 return nextNode;
5418 }
5419 break;
5420 case Fragment:
5421 if (!isFragmentStart) {
5422 nextNode = onMismatch();
5423 }
5424 else {
5425 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
5426 }
5427 break;
5428 default:
5429 if (shapeFlag & 1 /* ELEMENT */) {
5430 if (domType !== 1 /* ELEMENT */ ||
5431 vnode.type.toLowerCase() !==
5432 node.tagName.toLowerCase()) {
5433 nextNode = onMismatch();
5434 }
5435 else {
5436 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
5437 }
5438 }
5439 else if (shapeFlag & 6 /* COMPONENT */) {
5440 // when setting up the render effect, if the initial vnode already
5441 // has .el set, the component will perform hydration instead of mount
5442 // on its sub-tree.
5443 vnode.slotScopeIds = slotScopeIds;
5444 const container = parentNode(node);
5445 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
5446 // component may be async, so in the case of fragments we cannot rely
5447 // on component's rendered output to determine the end of the fragment
5448 // instead, we do a lookahead to find the end anchor node.
5449 nextNode = isFragmentStart
5450 ? locateClosingAsyncAnchor(node)
5451 : nextSibling(node);
5452 // #3787
5453 // if component is async, it may get moved / unmounted before its
5454 // inner component is loaded, so we need to give it a placeholder
5455 // vnode that matches its adopted DOM.
5456 if (isAsyncWrapper(vnode)) {
5457 let subTree;
5458 if (isFragmentStart) {
5459 subTree = createVNode(Fragment);
5460 subTree.anchor = nextNode
5461 ? nextNode.previousSibling
5462 : container.lastChild;
5463 }
5464 else {
5465 subTree =
5466 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
5467 }
5468 subTree.el = node;
5469 vnode.component.subTree = subTree;
5470 }
5471 }
5472 else if (shapeFlag & 64 /* TELEPORT */) {
5473 if (domType !== 8 /* COMMENT */) {
5474 nextNode = onMismatch();
5475 }
5476 else {
5477 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
5478 }
5479 }
5480 else if (shapeFlag & 128 /* SUSPENSE */) {
5481 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
5482 }
5483 else {
5484 warn('Invalid HostVNode type:', type, `(${typeof type})`);
5485 }
5486 }
5487 if (ref != null) {
5488 setRef(ref, null, parentSuspense, vnode);
5489 }
5490 return nextNode;
5491 };
5492 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
5493 optimized = optimized || !!vnode.dynamicChildren;
5494 const { props, patchFlag, shapeFlag, dirs } = vnode;
5495 // skip props & children if this is hoisted static nodes
5496 if (patchFlag !== -1 /* HOISTED */) {
5497 if (dirs) {
5498 invokeDirectiveHook(vnode, null, parentComponent, 'created');
5499 }
5500 // props
5501 if (props) {
5502 if (!optimized ||
5503 (patchFlag & 16 /* FULL_PROPS */ ||
5504 patchFlag & 32 /* HYDRATE_EVENTS */)) {
5505 for (const key in props) {
5506 if (!isReservedProp(key) && isOn(key)) {
5507 patchProp(el, key, null, props[key]);
5508 }
5509 }
5510 }
5511 else if (props.onClick) {
5512 // Fast path for click listeners (which is most often) to avoid
5513 // iterating through props.
5514 patchProp(el, 'onClick', null, props.onClick);
5515 }
5516 }
5517 // vnode / directive hooks
5518 let vnodeHooks;
5519 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
5520 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
5521 }
5522 if (dirs) {
5523 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
5524 }
5525 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
5526 queueEffectWithSuspense(() => {
5527 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
5528 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
5529 }, parentSuspense);
5530 }
5531 // children
5532 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
5533 // skip if element has innerHTML / textContent
5534 !(props && (props.innerHTML || props.textContent))) {
5535 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
5536 let hasWarned = false;
5537 while (next) {
5538 hasMismatch = true;
5539 if (!hasWarned) {
5540 warn(`Hydration children mismatch in <${vnode.type}>: ` +
5541 `server rendered element contains more child nodes than client vdom.`);
5542 hasWarned = true;
5543 }
5544 // The SSRed DOM contains more nodes than it should. Remove them.
5545 const cur = next;
5546 next = next.nextSibling;
5547 remove(cur);
5548 }
5549 }
5550 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5551 if (el.textContent !== vnode.children) {
5552 hasMismatch = true;
5553 warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
5554 `- Client: ${el.textContent}\n` +
5555 `- Server: ${vnode.children}`);
5556 el.textContent = vnode.children;
5557 }
5558 }
5559 }
5560 return el.nextSibling;
5561 };
5562 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
5563 optimized = optimized || !!parentVNode.dynamicChildren;
5564 const children = parentVNode.children;
5565 const l = children.length;
5566 let hasWarned = false;
5567 for (let i = 0; i < l; i++) {
5568 const vnode = optimized
5569 ? children[i]
5570 : (children[i] = normalizeVNode(children[i]));
5571 if (node) {
5572 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
5573 }
5574 else if (vnode.type === Text && !vnode.children) {
5575 continue;
5576 }
5577 else {
5578 hasMismatch = true;
5579 if (!hasWarned) {
5580 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
5581 `server rendered element contains fewer child nodes than client vdom.`);
5582 hasWarned = true;
5583 }
5584 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
5585 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
5586 }
5587 }
5588 return node;
5589 };
5590 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
5591 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
5592 if (fragmentSlotScopeIds) {
5593 slotScopeIds = slotScopeIds
5594 ? slotScopeIds.concat(fragmentSlotScopeIds)
5595 : fragmentSlotScopeIds;
5596 }
5597 const container = parentNode(node);
5598 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
5599 if (next && isComment(next) && next.data === ']') {
5600 return nextSibling((vnode.anchor = next));
5601 }
5602 else {
5603 // fragment didn't hydrate successfully, since we didn't get a end anchor
5604 // back. This should have led to node/children mismatch warnings.
5605 hasMismatch = true;
5606 // since the anchor is missing, we need to create one and insert it
5607 insert((vnode.anchor = createComment(`]`)), container, next);
5608 return next;
5609 }
5610 };
5611 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
5612 hasMismatch = true;
5613 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
5614 ? `(text)`
5615 : isComment(node) && node.data === '['
5616 ? `(start of fragment)`
5617 : ``);
5618 vnode.el = null;
5619 if (isFragment) {
5620 // remove excessive fragment nodes
5621 const end = locateClosingAsyncAnchor(node);
5622 while (true) {
5623 const next = nextSibling(node);
5624 if (next && next !== end) {
5625 remove(next);
5626 }
5627 else {
5628 break;
5629 }
5630 }
5631 }
5632 const next = nextSibling(node);
5633 const container = parentNode(node);
5634 remove(node);
5635 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
5636 return next;
5637 };
5638 const locateClosingAsyncAnchor = (node) => {
5639 let match = 0;
5640 while (node) {
5641 node = nextSibling(node);
5642 if (node && isComment(node)) {
5643 if (node.data === '[')
5644 match++;
5645 if (node.data === ']') {
5646 if (match === 0) {
5647 return nextSibling(node);
5648 }
5649 else {
5650 match--;
5651 }
5652 }
5653 }
5654 }
5655 return node;
5656 };
5657 return [hydrate, hydrateNode];
5658}
5659
5660let supported;
5661let perf;
5662function startMeasure(instance, type) {
5663 if (instance.appContext.config.performance && isSupported()) {
5664 perf.mark(`vue-${type}-${instance.uid}`);
5665 }
5666 {
5667 devtoolsPerfStart(instance, type, supported ? perf.now() : Date.now());
5668 }
5669}
5670function endMeasure(instance, type) {
5671 if (instance.appContext.config.performance && isSupported()) {
5672 const startTag = `vue-${type}-${instance.uid}`;
5673 const endTag = startTag + `:end`;
5674 perf.mark(endTag);
5675 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
5676 perf.clearMarks(startTag);
5677 perf.clearMarks(endTag);
5678 }
5679 {
5680 devtoolsPerfEnd(instance, type, supported ? perf.now() : Date.now());
5681 }
5682}
5683function isSupported() {
5684 if (supported !== undefined) {
5685 return supported;
5686 }
5687 /* eslint-disable no-restricted-globals */
5688 if (typeof window !== 'undefined' && window.performance) {
5689 supported = true;
5690 perf = window.performance;
5691 }
5692 else {
5693 supported = false;
5694 }
5695 /* eslint-enable no-restricted-globals */
5696 return supported;
5697}
5698
5699function createDevEffectOptions(instance) {
5700 return {
5701 scheduler: queueJob,
5702 allowRecurse: true,
5703 onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0,
5704 onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 0
5705 };
5706}
5707const queuePostRenderEffect = queueEffectWithSuspense
5708 ;
5709const setRef = (rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) => {
5710 if (isArray(rawRef)) {
5711 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
5712 return;
5713 }
5714 if (isAsyncWrapper(vnode) && !isUnmount) {
5715 // when mounting async components, nothing needs to be done,
5716 // because the template ref is forwarded to inner component
5717 return;
5718 }
5719 const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
5720 ? vnode.component.exposed || vnode.component.proxy
5721 : vnode.el;
5722 const value = isUnmount ? null : refValue;
5723 const { i: owner, r: ref } = rawRef;
5724 if (!owner) {
5725 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
5726 `A vnode with ref must be created inside the render function.`);
5727 return;
5728 }
5729 const oldRef = oldRawRef && oldRawRef.r;
5730 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
5731 const setupState = owner.setupState;
5732 // dynamic ref changed. unset old ref
5733 if (oldRef != null && oldRef !== ref) {
5734 if (isString(oldRef)) {
5735 refs[oldRef] = null;
5736 if (hasOwn(setupState, oldRef)) {
5737 setupState[oldRef] = null;
5738 }
5739 }
5740 else if (isRef(oldRef)) {
5741 oldRef.value = null;
5742 }
5743 }
5744 if (isString(ref)) {
5745 const doSet = () => {
5746 {
5747 refs[ref] = value;
5748 }
5749 if (hasOwn(setupState, ref)) {
5750 setupState[ref] = value;
5751 }
5752 };
5753 // #1789: for non-null values, set them after render
5754 // null values means this is unmount and it should not overwrite another
5755 // ref with the same key
5756 if (value) {
5757 doSet.id = -1;
5758 queuePostRenderEffect(doSet, parentSuspense);
5759 }
5760 else {
5761 doSet();
5762 }
5763 }
5764 else if (isRef(ref)) {
5765 const doSet = () => {
5766 ref.value = value;
5767 };
5768 if (value) {
5769 doSet.id = -1;
5770 queuePostRenderEffect(doSet, parentSuspense);
5771 }
5772 else {
5773 doSet();
5774 }
5775 }
5776 else if (isFunction(ref)) {
5777 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
5778 }
5779 else {
5780 warn('Invalid template ref type:', value, `(${typeof value})`);
5781 }
5782};
5783/**
5784 * The createRenderer function accepts two generic arguments:
5785 * HostNode and HostElement, corresponding to Node and Element types in the
5786 * host environment. For example, for runtime-dom, HostNode would be the DOM
5787 * `Node` interface and HostElement would be the DOM `Element` interface.
5788 *
5789 * Custom renderers can pass in the platform specific types like this:
5790 *
5791 * ``` js
5792 * const { render, createApp } = createRenderer<Node, Element>({
5793 * patchProp,
5794 * ...nodeOps
5795 * })
5796 * ```
5797 */
5798function createRenderer(options) {
5799 return baseCreateRenderer(options);
5800}
5801// Separate API for creating hydration-enabled renderer.
5802// Hydration logic is only used when calling this function, making it
5803// tree-shakable.
5804function createHydrationRenderer(options) {
5805 return baseCreateRenderer(options, createHydrationFunctions);
5806}
5807// implementation
5808function baseCreateRenderer(options, createHydrationFns) {
5809 {
5810 const target = getGlobalThis();
5811 target.__VUE__ = true;
5812 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__);
5813 }
5814 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
5815 // Note: functions inside this closure should use `const xxx = () => {}`
5816 // style in order to prevent being inlined by minifiers.
5817 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = false) => {
5818 // patching & not same type, unmount old tree
5819 if (n1 && !isSameVNodeType(n1, n2)) {
5820 anchor = getNextHostNode(n1);
5821 unmount(n1, parentComponent, parentSuspense, true);
5822 n1 = null;
5823 }
5824 if (n2.patchFlag === -2 /* BAIL */) {
5825 optimized = false;
5826 n2.dynamicChildren = null;
5827 }
5828 const { type, ref, shapeFlag } = n2;
5829 switch (type) {
5830 case Text:
5831 processText(n1, n2, container, anchor);
5832 break;
5833 case Comment$1:
5834 processCommentNode(n1, n2, container, anchor);
5835 break;
5836 case Static:
5837 if (n1 == null) {
5838 mountStaticNode(n2, container, anchor, isSVG);
5839 }
5840 else {
5841 patchStaticNode(n1, n2, container, isSVG);
5842 }
5843 break;
5844 case Fragment:
5845 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5846 break;
5847 default:
5848 if (shapeFlag & 1 /* ELEMENT */) {
5849 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5850 }
5851 else if (shapeFlag & 6 /* COMPONENT */) {
5852 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5853 }
5854 else if (shapeFlag & 64 /* TELEPORT */) {
5855 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
5856 }
5857 else if (shapeFlag & 128 /* SUSPENSE */) {
5858 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
5859 }
5860 else {
5861 warn('Invalid VNode type:', type, `(${typeof type})`);
5862 }
5863 }
5864 // set ref
5865 if (ref != null && parentComponent) {
5866 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
5867 }
5868 };
5869 const processText = (n1, n2, container, anchor) => {
5870 if (n1 == null) {
5871 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
5872 }
5873 else {
5874 const el = (n2.el = n1.el);
5875 if (n2.children !== n1.children) {
5876 hostSetText(el, n2.children);
5877 }
5878 }
5879 };
5880 const processCommentNode = (n1, n2, container, anchor) => {
5881 if (n1 == null) {
5882 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
5883 }
5884 else {
5885 // there's no support for dynamic comments
5886 n2.el = n1.el;
5887 }
5888 };
5889 const mountStaticNode = (n2, container, anchor, isSVG) => {
5890 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5891 };
5892 /**
5893 * Dev / HMR only
5894 */
5895 const patchStaticNode = (n1, n2, container, isSVG) => {
5896 // static nodes are only patched during dev for HMR
5897 if (n2.children !== n1.children) {
5898 const anchor = hostNextSibling(n1.anchor);
5899 // remove existing
5900 removeStaticNode(n1);
5901 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5902 }
5903 else {
5904 n2.el = n1.el;
5905 n2.anchor = n1.anchor;
5906 }
5907 };
5908 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
5909 let next;
5910 while (el && el !== anchor) {
5911 next = hostNextSibling(el);
5912 hostInsert(el, container, nextSibling);
5913 el = next;
5914 }
5915 hostInsert(anchor, container, nextSibling);
5916 };
5917 const removeStaticNode = ({ el, anchor }) => {
5918 let next;
5919 while (el && el !== anchor) {
5920 next = hostNextSibling(el);
5921 hostRemove(el);
5922 el = next;
5923 }
5924 hostRemove(anchor);
5925 };
5926 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5927 isSVG = isSVG || n2.type === 'svg';
5928 if (n1 == null) {
5929 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5930 }
5931 else {
5932 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5933 }
5934 };
5935 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5936 let el;
5937 let vnodeHook;
5938 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
5939 {
5940 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
5941 // mount children first, since some props may rely on child content
5942 // being already rendered, e.g. `<select value>`
5943 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5944 hostSetElementText(el, vnode.children);
5945 }
5946 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5947 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized || !!vnode.dynamicChildren);
5948 }
5949 if (dirs) {
5950 invokeDirectiveHook(vnode, null, parentComponent, 'created');
5951 }
5952 // props
5953 if (props) {
5954 for (const key in props) {
5955 if (!isReservedProp(key)) {
5956 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5957 }
5958 }
5959 if ((vnodeHook = props.onVnodeBeforeMount)) {
5960 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5961 }
5962 }
5963 // scopeId
5964 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
5965 }
5966 {
5967 Object.defineProperty(el, '__vnode', {
5968 value: vnode,
5969 enumerable: false
5970 });
5971 Object.defineProperty(el, '__vueParentComponent', {
5972 value: parentComponent,
5973 enumerable: false
5974 });
5975 }
5976 if (dirs) {
5977 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
5978 }
5979 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
5980 // #1689 For inside suspense + suspense resolved case, just call it
5981 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
5982 transition &&
5983 !transition.persisted;
5984 if (needCallTransitionHooks) {
5985 transition.beforeEnter(el);
5986 }
5987 hostInsert(el, container, anchor);
5988 if ((vnodeHook = props && props.onVnodeMounted) ||
5989 needCallTransitionHooks ||
5990 dirs) {
5991 queuePostRenderEffect(() => {
5992 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5993 needCallTransitionHooks && transition.enter(el);
5994 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
5995 }, parentSuspense);
5996 }
5997 };
5998 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
5999 if (scopeId) {
6000 hostSetScopeId(el, scopeId);
6001 }
6002 if (slotScopeIds) {
6003 for (let i = 0; i < slotScopeIds.length; i++) {
6004 hostSetScopeId(el, slotScopeIds[i]);
6005 }
6006 }
6007 if (parentComponent) {
6008 let subTree = parentComponent.subTree;
6009 if (subTree.patchFlag > 0 &&
6010 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
6011 subTree =
6012 filterSingleRoot(subTree.children) || subTree;
6013 }
6014 if (vnode === subTree) {
6015 const parentVNode = parentComponent.vnode;
6016 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
6017 }
6018 }
6019 };
6020 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
6021 for (let i = start; i < children.length; i++) {
6022 const child = (children[i] = optimized
6023 ? cloneIfMounted(children[i])
6024 : normalizeVNode(children[i]));
6025 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6026 }
6027 };
6028 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6029 const el = (n2.el = n1.el);
6030 let { patchFlag, dynamicChildren, dirs } = n2;
6031 // #1426 take the old vnode's patch flag into account since user may clone a
6032 // compiler-generated vnode, which de-opts to FULL_PROPS
6033 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
6034 const oldProps = n1.props || EMPTY_OBJ;
6035 const newProps = n2.props || EMPTY_OBJ;
6036 let vnodeHook;
6037 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6038 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6039 }
6040 if (dirs) {
6041 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6042 }
6043 if (isHmrUpdating) {
6044 // HMR updated, force full diff
6045 patchFlag = 0;
6046 optimized = false;
6047 dynamicChildren = null;
6048 }
6049 if (patchFlag > 0) {
6050 // the presence of a patchFlag means this element's render code was
6051 // generated by the compiler and can take the fast path.
6052 // in this path old node and new node are guaranteed to have the same shape
6053 // (i.e. at the exact same position in the source template)
6054 if (patchFlag & 16 /* FULL_PROPS */) {
6055 // element props contain dynamic keys, full diff needed
6056 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6057 }
6058 else {
6059 // class
6060 // this flag is matched when the element has dynamic class bindings.
6061 if (patchFlag & 2 /* CLASS */) {
6062 if (oldProps.class !== newProps.class) {
6063 hostPatchProp(el, 'class', null, newProps.class, isSVG);
6064 }
6065 }
6066 // style
6067 // this flag is matched when the element has dynamic style bindings
6068 if (patchFlag & 4 /* STYLE */) {
6069 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
6070 }
6071 // props
6072 // This flag is matched when the element has dynamic prop/attr bindings
6073 // other than class and style. The keys of dynamic prop/attrs are saved for
6074 // faster iteration.
6075 // Note dynamic keys like :[foo]="bar" will cause this optimization to
6076 // bail out and go through a full diff because we need to unset the old key
6077 if (patchFlag & 8 /* PROPS */) {
6078 // if the flag is present then dynamicProps must be non-null
6079 const propsToUpdate = n2.dynamicProps;
6080 for (let i = 0; i < propsToUpdate.length; i++) {
6081 const key = propsToUpdate[i];
6082 const prev = oldProps[key];
6083 const next = newProps[key];
6084 if (next !== prev ||
6085 (hostForcePatchProp && hostForcePatchProp(el, key))) {
6086 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
6087 }
6088 }
6089 }
6090 }
6091 // text
6092 // This flag is matched when the element has only dynamic text children.
6093 if (patchFlag & 1 /* TEXT */) {
6094 if (n1.children !== n2.children) {
6095 hostSetElementText(el, n2.children);
6096 }
6097 }
6098 }
6099 else if (!optimized && dynamicChildren == null) {
6100 // unoptimized, full diff
6101 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6102 }
6103 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
6104 if (dynamicChildren) {
6105 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
6106 if (parentComponent && parentComponent.type.__hmrId) {
6107 traverseStaticChildren(n1, n2);
6108 }
6109 }
6110 else if (!optimized) {
6111 // full diff
6112 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
6113 }
6114 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
6115 queuePostRenderEffect(() => {
6116 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6117 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
6118 }, parentSuspense);
6119 }
6120 };
6121 // The fast path for blocks.
6122 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
6123 for (let i = 0; i < newChildren.length; i++) {
6124 const oldVNode = oldChildren[i];
6125 const newVNode = newChildren[i];
6126 // Determine the container (parent element) for the patch.
6127 const container =
6128 // oldVNode may be an errored async setup() component inside Suspense
6129 // which will not have a mounted element
6130 oldVNode.el &&
6131 // - In the case of a Fragment, we need to provide the actual parent
6132 // of the Fragment itself so it can move its children.
6133 (oldVNode.type === Fragment ||
6134 // - In the case of different nodes, there is going to be a replacement
6135 // which also requires the correct parent container
6136 !isSameVNodeType(oldVNode, newVNode) ||
6137 // - In the case of a component, it could contain anything.
6138 oldVNode.shapeFlag & 6 /* COMPONENT */ ||
6139 oldVNode.shapeFlag & 64 /* TELEPORT */)
6140 ? hostParentNode(oldVNode.el)
6141 : // In other cases, the parent container is not actually used so we
6142 // just pass the block element here to avoid a DOM parentNode call.
6143 fallbackContainer;
6144 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
6145 }
6146 };
6147 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
6148 if (oldProps !== newProps) {
6149 for (const key in newProps) {
6150 // empty string is not valid prop
6151 if (isReservedProp(key))
6152 continue;
6153 const next = newProps[key];
6154 const prev = oldProps[key];
6155 if (next !== prev ||
6156 (hostForcePatchProp && hostForcePatchProp(el, key))) {
6157 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6158 }
6159 }
6160 if (oldProps !== EMPTY_OBJ) {
6161 for (const key in oldProps) {
6162 if (!isReservedProp(key) && !(key in newProps)) {
6163 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6164 }
6165 }
6166 }
6167 }
6168 };
6169 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6170 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
6171 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
6172 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
6173 if (dynamicChildren) {
6174 optimized = true;
6175 }
6176 // check if this is a slot fragment with :slotted scope ids
6177 if (fragmentSlotScopeIds) {
6178 slotScopeIds = slotScopeIds
6179 ? slotScopeIds.concat(fragmentSlotScopeIds)
6180 : fragmentSlotScopeIds;
6181 }
6182 if (isHmrUpdating) {
6183 // HMR updated, force full diff
6184 patchFlag = 0;
6185 optimized = false;
6186 dynamicChildren = null;
6187 }
6188 if (n1 == null) {
6189 hostInsert(fragmentStartAnchor, container, anchor);
6190 hostInsert(fragmentEndAnchor, container, anchor);
6191 // a fragment can only have array children
6192 // since they are either generated by the compiler, or implicitly created
6193 // from arrays.
6194 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6195 }
6196 else {
6197 if (patchFlag > 0 &&
6198 patchFlag & 64 /* STABLE_FRAGMENT */ &&
6199 dynamicChildren &&
6200 // #2715 the previous fragment could've been a BAILed one as a result
6201 // of renderSlot() with no valid children
6202 n1.dynamicChildren) {
6203 // a stable fragment (template root or <template v-for>) doesn't need to
6204 // patch children order, but it may contain dynamicChildren.
6205 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
6206 if (parentComponent && parentComponent.type.__hmrId) {
6207 traverseStaticChildren(n1, n2);
6208 }
6209 else if (
6210 // #2080 if the stable fragment has a key, it's a <template v-for> that may
6211 // get moved around. Make sure all root level vnodes inherit el.
6212 // #2134 or if it's a component root, it may also get moved around
6213 // as the component is being moved.
6214 n2.key != null ||
6215 (parentComponent && n2 === parentComponent.subTree)) {
6216 traverseStaticChildren(n1, n2, true /* shallow */);
6217 }
6218 }
6219 else {
6220 // keyed / unkeyed, or manual fragments.
6221 // for keyed & unkeyed, since they are compiler generated from v-for,
6222 // each child is guaranteed to be a block so the fragment will never
6223 // have dynamicChildren.
6224 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6225 }
6226 }
6227 };
6228 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6229 n2.slotScopeIds = slotScopeIds;
6230 if (n1 == null) {
6231 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
6232 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
6233 }
6234 else {
6235 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
6236 }
6237 }
6238 else {
6239 updateComponent(n1, n2, optimized);
6240 }
6241 };
6242 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
6243 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
6244 if (instance.type.__hmrId) {
6245 registerHMR(instance);
6246 }
6247 {
6248 pushWarningContext(initialVNode);
6249 startMeasure(instance, `mount`);
6250 }
6251 // inject renderer internals for keepAlive
6252 if (isKeepAlive(initialVNode)) {
6253 instance.ctx.renderer = internals;
6254 }
6255 // resolve props and slots for setup context
6256 {
6257 {
6258 startMeasure(instance, `init`);
6259 }
6260 setupComponent(instance);
6261 {
6262 endMeasure(instance, `init`);
6263 }
6264 }
6265 // setup() is async. This component relies on async logic to be resolved
6266 // before proceeding
6267 if (instance.asyncDep) {
6268 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
6269 // Give it a placeholder if this is not hydration
6270 // TODO handle self-defined fallback
6271 if (!initialVNode.el) {
6272 const placeholder = (instance.subTree = createVNode(Comment$1));
6273 processCommentNode(null, placeholder, container, anchor);
6274 }
6275 return;
6276 }
6277 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
6278 {
6279 popWarningContext();
6280 endMeasure(instance, `mount`);
6281 }
6282 };
6283 const updateComponent = (n1, n2, optimized) => {
6284 const instance = (n2.component = n1.component);
6285 if (shouldUpdateComponent(n1, n2, optimized)) {
6286 if (instance.asyncDep &&
6287 !instance.asyncResolved) {
6288 // async & still pending - just update props and slots
6289 // since the component's reactive effect for render isn't set-up yet
6290 {
6291 pushWarningContext(n2);
6292 }
6293 updateComponentPreRender(instance, n2, optimized);
6294 {
6295 popWarningContext();
6296 }
6297 return;
6298 }
6299 else {
6300 // normal update
6301 instance.next = n2;
6302 // in case the child component is also queued, remove it to avoid
6303 // double updating the same child component in the same flush.
6304 invalidateJob(instance.update);
6305 // instance.update is the reactive effect runner.
6306 instance.update();
6307 }
6308 }
6309 else {
6310 // no update needed. just copy over properties
6311 n2.component = n1.component;
6312 n2.el = n1.el;
6313 instance.vnode = n2;
6314 }
6315 };
6316 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
6317 // create reactive effect for rendering
6318 instance.update = effect(function componentEffect() {
6319 if (!instance.isMounted) {
6320 let vnodeHook;
6321 const { el, props } = initialVNode;
6322 const { bm, m, parent } = instance;
6323 // beforeMount hook
6324 if (bm) {
6325 invokeArrayFns(bm);
6326 }
6327 // onVnodeBeforeMount
6328 if ((vnodeHook = props && props.onVnodeBeforeMount)) {
6329 invokeVNodeHook(vnodeHook, parent, initialVNode);
6330 }
6331 if (el && hydrateNode) {
6332 // vnode has adopted host node - perform hydration instead of mount.
6333 const hydrateSubTree = () => {
6334 {
6335 startMeasure(instance, `render`);
6336 }
6337 instance.subTree = renderComponentRoot(instance);
6338 {
6339 endMeasure(instance, `render`);
6340 }
6341 {
6342 startMeasure(instance, `hydrate`);
6343 }
6344 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
6345 {
6346 endMeasure(instance, `hydrate`);
6347 }
6348 };
6349 if (isAsyncWrapper(initialVNode)) {
6350 initialVNode.type.__asyncLoader().then(
6351 // note: we are moving the render call into an async callback,
6352 // which means it won't track dependencies - but it's ok because
6353 // a server-rendered async wrapper is already in resolved state
6354 // and it will never need to change.
6355 () => !instance.isUnmounted && hydrateSubTree());
6356 }
6357 else {
6358 hydrateSubTree();
6359 }
6360 }
6361 else {
6362 {
6363 startMeasure(instance, `render`);
6364 }
6365 const subTree = (instance.subTree = renderComponentRoot(instance));
6366 {
6367 endMeasure(instance, `render`);
6368 }
6369 {
6370 startMeasure(instance, `patch`);
6371 }
6372 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
6373 {
6374 endMeasure(instance, `patch`);
6375 }
6376 initialVNode.el = subTree.el;
6377 }
6378 // mounted hook
6379 if (m) {
6380 queuePostRenderEffect(m, parentSuspense);
6381 }
6382 // onVnodeMounted
6383 if ((vnodeHook = props && props.onVnodeMounted)) {
6384 const scopedInitialVNode = initialVNode;
6385 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
6386 }
6387 // activated hook for keep-alive roots.
6388 // #1742 activated hook must be accessed after first render
6389 // since the hook may be injected by a child keep-alive
6390 if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
6391 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
6392 }
6393 instance.isMounted = true;
6394 {
6395 devtoolsComponentAdded(instance);
6396 }
6397 // #2458: deference mount-only object parameters to prevent memleaks
6398 initialVNode = container = anchor = null;
6399 }
6400 else {
6401 // updateComponent
6402 // This is triggered by mutation of component's own state (next: null)
6403 // OR parent calling processComponent (next: VNode)
6404 let { next, bu, u, parent, vnode } = instance;
6405 let originNext = next;
6406 let vnodeHook;
6407 {
6408 pushWarningContext(next || instance.vnode);
6409 }
6410 if (next) {
6411 next.el = vnode.el;
6412 updateComponentPreRender(instance, next, optimized);
6413 }
6414 else {
6415 next = vnode;
6416 }
6417 // beforeUpdate hook
6418 if (bu) {
6419 invokeArrayFns(bu);
6420 }
6421 // onVnodeBeforeUpdate
6422 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
6423 invokeVNodeHook(vnodeHook, parent, next, vnode);
6424 }
6425 // render
6426 {
6427 startMeasure(instance, `render`);
6428 }
6429 const nextTree = renderComponentRoot(instance);
6430 {
6431 endMeasure(instance, `render`);
6432 }
6433 const prevTree = instance.subTree;
6434 instance.subTree = nextTree;
6435 {
6436 startMeasure(instance, `patch`);
6437 }
6438 patch(prevTree, nextTree,
6439 // parent may have changed if it's in a teleport
6440 hostParentNode(prevTree.el),
6441 // anchor may have changed if it's in a fragment
6442 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
6443 {
6444 endMeasure(instance, `patch`);
6445 }
6446 next.el = nextTree.el;
6447 if (originNext === null) {
6448 // self-triggered update. In case of HOC, update parent component
6449 // vnode el. HOC is indicated by parent instance's subTree pointing
6450 // to child component's vnode
6451 updateHOCHostEl(instance, nextTree.el);
6452 }
6453 // updated hook
6454 if (u) {
6455 queuePostRenderEffect(u, parentSuspense);
6456 }
6457 // onVnodeUpdated
6458 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
6459 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
6460 }
6461 {
6462 devtoolsComponentUpdated(instance);
6463 }
6464 {
6465 popWarningContext();
6466 }
6467 }
6468 }, createDevEffectOptions(instance) );
6469 {
6470 // @ts-ignore
6471 instance.update.ownerInstance = instance;
6472 }
6473 };
6474 const updateComponentPreRender = (instance, nextVNode, optimized) => {
6475 nextVNode.component = instance;
6476 const prevProps = instance.vnode.props;
6477 instance.vnode = nextVNode;
6478 instance.next = null;
6479 updateProps(instance, nextVNode.props, prevProps, optimized);
6480 updateSlots(instance, nextVNode.children, optimized);
6481 pauseTracking();
6482 // props update may have triggered pre-flush watchers.
6483 // flush them before the render update.
6484 flushPreFlushCbs(undefined, instance.update);
6485 resetTracking();
6486 };
6487 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
6488 const c1 = n1 && n1.children;
6489 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
6490 const c2 = n2.children;
6491 const { patchFlag, shapeFlag } = n2;
6492 // fast path
6493 if (patchFlag > 0) {
6494 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
6495 // this could be either fully-keyed or mixed (some keyed some not)
6496 // presence of patchFlag means children are guaranteed to be arrays
6497 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6498 return;
6499 }
6500 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
6501 // unkeyed
6502 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6503 return;
6504 }
6505 }
6506 // children has 3 possibilities: text, array or no children.
6507 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
6508 // text children fast path
6509 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
6510 unmountChildren(c1, parentComponent, parentSuspense);
6511 }
6512 if (c2 !== c1) {
6513 hostSetElementText(container, c2);
6514 }
6515 }
6516 else {
6517 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
6518 // prev children was array
6519 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6520 // two arrays, cannot assume anything, do full diff
6521 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6522 }
6523 else {
6524 // no new children, just unmount old
6525 unmountChildren(c1, parentComponent, parentSuspense, true);
6526 }
6527 }
6528 else {
6529 // prev children was text OR null
6530 // new children is array OR null
6531 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
6532 hostSetElementText(container, '');
6533 }
6534 // mount new if array
6535 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6536 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6537 }
6538 }
6539 }
6540 };
6541 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6542 c1 = c1 || EMPTY_ARR;
6543 c2 = c2 || EMPTY_ARR;
6544 const oldLength = c1.length;
6545 const newLength = c2.length;
6546 const commonLength = Math.min(oldLength, newLength);
6547 let i;
6548 for (i = 0; i < commonLength; i++) {
6549 const nextChild = (c2[i] = optimized
6550 ? cloneIfMounted(c2[i])
6551 : normalizeVNode(c2[i]));
6552 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6553 }
6554 if (oldLength > newLength) {
6555 // remove old
6556 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
6557 }
6558 else {
6559 // mount new
6560 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
6561 }
6562 };
6563 // can be all-keyed or mixed
6564 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6565 let i = 0;
6566 const l2 = c2.length;
6567 let e1 = c1.length - 1; // prev ending index
6568 let e2 = l2 - 1; // next ending index
6569 // 1. sync from start
6570 // (a b) c
6571 // (a b) d e
6572 while (i <= e1 && i <= e2) {
6573 const n1 = c1[i];
6574 const n2 = (c2[i] = optimized
6575 ? cloneIfMounted(c2[i])
6576 : normalizeVNode(c2[i]));
6577 if (isSameVNodeType(n1, n2)) {
6578 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6579 }
6580 else {
6581 break;
6582 }
6583 i++;
6584 }
6585 // 2. sync from end
6586 // a (b c)
6587 // d e (b c)
6588 while (i <= e1 && i <= e2) {
6589 const n1 = c1[e1];
6590 const n2 = (c2[e2] = optimized
6591 ? cloneIfMounted(c2[e2])
6592 : normalizeVNode(c2[e2]));
6593 if (isSameVNodeType(n1, n2)) {
6594 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6595 }
6596 else {
6597 break;
6598 }
6599 e1--;
6600 e2--;
6601 }
6602 // 3. common sequence + mount
6603 // (a b)
6604 // (a b) c
6605 // i = 2, e1 = 1, e2 = 2
6606 // (a b)
6607 // c (a b)
6608 // i = 0, e1 = -1, e2 = 0
6609 if (i > e1) {
6610 if (i <= e2) {
6611 const nextPos = e2 + 1;
6612 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
6613 while (i <= e2) {
6614 patch(null, (c2[i] = optimized
6615 ? cloneIfMounted(c2[i])
6616 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6617 i++;
6618 }
6619 }
6620 }
6621 // 4. common sequence + unmount
6622 // (a b) c
6623 // (a b)
6624 // i = 2, e1 = 2, e2 = 1
6625 // a (b c)
6626 // (b c)
6627 // i = 0, e1 = 0, e2 = -1
6628 else if (i > e2) {
6629 while (i <= e1) {
6630 unmount(c1[i], parentComponent, parentSuspense, true);
6631 i++;
6632 }
6633 }
6634 // 5. unknown sequence
6635 // [i ... e1 + 1]: a b [c d e] f g
6636 // [i ... e2 + 1]: a b [e d c h] f g
6637 // i = 2, e1 = 4, e2 = 5
6638 else {
6639 const s1 = i; // prev starting index
6640 const s2 = i; // next starting index
6641 // 5.1 build key:index map for newChildren
6642 const keyToNewIndexMap = new Map();
6643 for (i = s2; i <= e2; i++) {
6644 const nextChild = (c2[i] = optimized
6645 ? cloneIfMounted(c2[i])
6646 : normalizeVNode(c2[i]));
6647 if (nextChild.key != null) {
6648 if (keyToNewIndexMap.has(nextChild.key)) {
6649 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
6650 }
6651 keyToNewIndexMap.set(nextChild.key, i);
6652 }
6653 }
6654 // 5.2 loop through old children left to be patched and try to patch
6655 // matching nodes & remove nodes that are no longer present
6656 let j;
6657 let patched = 0;
6658 const toBePatched = e2 - s2 + 1;
6659 let moved = false;
6660 // used to track whether any node has moved
6661 let maxNewIndexSoFar = 0;
6662 // works as Map<newIndex, oldIndex>
6663 // Note that oldIndex is offset by +1
6664 // and oldIndex = 0 is a special value indicating the new node has
6665 // no corresponding old node.
6666 // used for determining longest stable subsequence
6667 const newIndexToOldIndexMap = new Array(toBePatched);
6668 for (i = 0; i < toBePatched; i++)
6669 newIndexToOldIndexMap[i] = 0;
6670 for (i = s1; i <= e1; i++) {
6671 const prevChild = c1[i];
6672 if (patched >= toBePatched) {
6673 // all new children have been patched so this can only be a removal
6674 unmount(prevChild, parentComponent, parentSuspense, true);
6675 continue;
6676 }
6677 let newIndex;
6678 if (prevChild.key != null) {
6679 newIndex = keyToNewIndexMap.get(prevChild.key);
6680 }
6681 else {
6682 // key-less node, try to locate a key-less node of the same type
6683 for (j = s2; j <= e2; j++) {
6684 if (newIndexToOldIndexMap[j - s2] === 0 &&
6685 isSameVNodeType(prevChild, c2[j])) {
6686 newIndex = j;
6687 break;
6688 }
6689 }
6690 }
6691 if (newIndex === undefined) {
6692 unmount(prevChild, parentComponent, parentSuspense, true);
6693 }
6694 else {
6695 newIndexToOldIndexMap[newIndex - s2] = i + 1;
6696 if (newIndex >= maxNewIndexSoFar) {
6697 maxNewIndexSoFar = newIndex;
6698 }
6699 else {
6700 moved = true;
6701 }
6702 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6703 patched++;
6704 }
6705 }
6706 // 5.3 move and mount
6707 // generate longest stable subsequence only when nodes have moved
6708 const increasingNewIndexSequence = moved
6709 ? getSequence(newIndexToOldIndexMap)
6710 : EMPTY_ARR;
6711 j = increasingNewIndexSequence.length - 1;
6712 // looping backwards so that we can use last patched node as anchor
6713 for (i = toBePatched - 1; i >= 0; i--) {
6714 const nextIndex = s2 + i;
6715 const nextChild = c2[nextIndex];
6716 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
6717 if (newIndexToOldIndexMap[i] === 0) {
6718 // mount new
6719 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6720 }
6721 else if (moved) {
6722 // move if:
6723 // There is no stable subsequence (e.g. a reverse)
6724 // OR current node is not among the stable sequence
6725 if (j < 0 || i !== increasingNewIndexSequence[j]) {
6726 move(nextChild, container, anchor, 2 /* REORDER */);
6727 }
6728 else {
6729 j--;
6730 }
6731 }
6732 }
6733 }
6734 };
6735 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
6736 const { el, type, transition, children, shapeFlag } = vnode;
6737 if (shapeFlag & 6 /* COMPONENT */) {
6738 move(vnode.component.subTree, container, anchor, moveType);
6739 return;
6740 }
6741 if (shapeFlag & 128 /* SUSPENSE */) {
6742 vnode.suspense.move(container, anchor, moveType);
6743 return;
6744 }
6745 if (shapeFlag & 64 /* TELEPORT */) {
6746 type.move(vnode, container, anchor, internals);
6747 return;
6748 }
6749 if (type === Fragment) {
6750 hostInsert(el, container, anchor);
6751 for (let i = 0; i < children.length; i++) {
6752 move(children[i], container, anchor, moveType);
6753 }
6754 hostInsert(vnode.anchor, container, anchor);
6755 return;
6756 }
6757 if (type === Static) {
6758 moveStaticNode(vnode, container, anchor);
6759 return;
6760 }
6761 // single nodes
6762 const needTransition = moveType !== 2 /* REORDER */ &&
6763 shapeFlag & 1 /* ELEMENT */ &&
6764 transition;
6765 if (needTransition) {
6766 if (moveType === 0 /* ENTER */) {
6767 transition.beforeEnter(el);
6768 hostInsert(el, container, anchor);
6769 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
6770 }
6771 else {
6772 const { leave, delayLeave, afterLeave } = transition;
6773 const remove = () => hostInsert(el, container, anchor);
6774 const performLeave = () => {
6775 leave(el, () => {
6776 remove();
6777 afterLeave && afterLeave();
6778 });
6779 };
6780 if (delayLeave) {
6781 delayLeave(el, remove, performLeave);
6782 }
6783 else {
6784 performLeave();
6785 }
6786 }
6787 }
6788 else {
6789 hostInsert(el, container, anchor);
6790 }
6791 };
6792 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
6793 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
6794 // unset ref
6795 if (ref != null) {
6796 setRef(ref, null, parentSuspense, vnode, true);
6797 }
6798 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
6799 parentComponent.ctx.deactivate(vnode);
6800 return;
6801 }
6802 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
6803 let vnodeHook;
6804 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {
6805 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6806 }
6807 if (shapeFlag & 6 /* COMPONENT */) {
6808 unmountComponent(vnode.component, parentSuspense, doRemove);
6809 }
6810 else {
6811 if (shapeFlag & 128 /* SUSPENSE */) {
6812 vnode.suspense.unmount(parentSuspense, doRemove);
6813 return;
6814 }
6815 if (shouldInvokeDirs) {
6816 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
6817 }
6818 if (shapeFlag & 64 /* TELEPORT */) {
6819 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
6820 }
6821 else if (dynamicChildren &&
6822 // #1153: fast path should not be taken for non-stable (v-for) fragments
6823 (type !== Fragment ||
6824 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
6825 // fast path for block nodes: only need to unmount dynamic children.
6826 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
6827 }
6828 else if ((type === Fragment &&
6829 (patchFlag & 128 /* KEYED_FRAGMENT */ ||
6830 patchFlag & 256 /* UNKEYED_FRAGMENT */)) ||
6831 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
6832 unmountChildren(children, parentComponent, parentSuspense);
6833 }
6834 if (doRemove) {
6835 remove(vnode);
6836 }
6837 }
6838 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {
6839 queuePostRenderEffect(() => {
6840 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6841 shouldInvokeDirs &&
6842 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
6843 }, parentSuspense);
6844 }
6845 };
6846 const remove = vnode => {
6847 const { type, el, anchor, transition } = vnode;
6848 if (type === Fragment) {
6849 removeFragment(el, anchor);
6850 return;
6851 }
6852 if (type === Static) {
6853 removeStaticNode(vnode);
6854 return;
6855 }
6856 const performRemove = () => {
6857 hostRemove(el);
6858 if (transition && !transition.persisted && transition.afterLeave) {
6859 transition.afterLeave();
6860 }
6861 };
6862 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
6863 transition &&
6864 !transition.persisted) {
6865 const { leave, delayLeave } = transition;
6866 const performLeave = () => leave(el, performRemove);
6867 if (delayLeave) {
6868 delayLeave(vnode.el, performRemove, performLeave);
6869 }
6870 else {
6871 performLeave();
6872 }
6873 }
6874 else {
6875 performRemove();
6876 }
6877 };
6878 const removeFragment = (cur, end) => {
6879 // For fragments, directly remove all contained DOM nodes.
6880 // (fragment child nodes cannot have transition)
6881 let next;
6882 while (cur !== end) {
6883 next = hostNextSibling(cur);
6884 hostRemove(cur);
6885 cur = next;
6886 }
6887 hostRemove(end);
6888 };
6889 const unmountComponent = (instance, parentSuspense, doRemove) => {
6890 if (instance.type.__hmrId) {
6891 unregisterHMR(instance);
6892 }
6893 const { bum, effects, update, subTree, um } = instance;
6894 // beforeUnmount hook
6895 if (bum) {
6896 invokeArrayFns(bum);
6897 }
6898 if (effects) {
6899 for (let i = 0; i < effects.length; i++) {
6900 stop(effects[i]);
6901 }
6902 }
6903 // update may be null if a component is unmounted before its async
6904 // setup has resolved.
6905 if (update) {
6906 stop(update);
6907 unmount(subTree, instance, parentSuspense, doRemove);
6908 }
6909 // unmounted hook
6910 if (um) {
6911 queuePostRenderEffect(um, parentSuspense);
6912 }
6913 queuePostRenderEffect(() => {
6914 instance.isUnmounted = true;
6915 }, parentSuspense);
6916 // A component with async dep inside a pending suspense is unmounted before
6917 // its async dep resolves. This should remove the dep from the suspense, and
6918 // cause the suspense to resolve immediately if that was the last dep.
6919 if (parentSuspense &&
6920 parentSuspense.pendingBranch &&
6921 !parentSuspense.isUnmounted &&
6922 instance.asyncDep &&
6923 !instance.asyncResolved &&
6924 instance.suspenseId === parentSuspense.pendingId) {
6925 parentSuspense.deps--;
6926 if (parentSuspense.deps === 0) {
6927 parentSuspense.resolve();
6928 }
6929 }
6930 {
6931 devtoolsComponentRemoved(instance);
6932 }
6933 };
6934 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
6935 for (let i = start; i < children.length; i++) {
6936 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
6937 }
6938 };
6939 const getNextHostNode = vnode => {
6940 if (vnode.shapeFlag & 6 /* COMPONENT */) {
6941 return getNextHostNode(vnode.component.subTree);
6942 }
6943 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
6944 return vnode.suspense.next();
6945 }
6946 return hostNextSibling((vnode.anchor || vnode.el));
6947 };
6948 const render = (vnode, container, isSVG) => {
6949 if (vnode == null) {
6950 if (container._vnode) {
6951 unmount(container._vnode, null, null, true);
6952 }
6953 }
6954 else {
6955 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
6956 }
6957 flushPostFlushCbs();
6958 container._vnode = vnode;
6959 };
6960 const internals = {
6961 p: patch,
6962 um: unmount,
6963 m: move,
6964 r: remove,
6965 mt: mountComponent,
6966 mc: mountChildren,
6967 pc: patchChildren,
6968 pbc: patchBlockChildren,
6969 n: getNextHostNode,
6970 o: options
6971 };
6972 let hydrate;
6973 let hydrateNode;
6974 if (createHydrationFns) {
6975 [hydrate, hydrateNode] = createHydrationFns(internals);
6976 }
6977 return {
6978 render,
6979 hydrate,
6980 createApp: createAppAPI(render, hydrate)
6981 };
6982}
6983function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6984 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6985 vnode,
6986 prevVNode
6987 ]);
6988}
6989/**
6990 * #1156
6991 * When a component is HMR-enabled, we need to make sure that all static nodes
6992 * inside a block also inherit the DOM element from the previous tree so that
6993 * HMR updates (which are full updates) can retrieve the element for patching.
6994 *
6995 * #2080
6996 * Inside keyed `template` fragment static children, if a fragment is moved,
6997 * the children will always moved so that need inherit el form previous nodes
6998 * to ensure correct moved position.
6999 */
7000function traverseStaticChildren(n1, n2, shallow = false) {
7001 const ch1 = n1.children;
7002 const ch2 = n2.children;
7003 if (isArray(ch1) && isArray(ch2)) {
7004 for (let i = 0; i < ch1.length; i++) {
7005 // this is only called in the optimized path so array children are
7006 // guaranteed to be vnodes
7007 const c1 = ch1[i];
7008 let c2 = ch2[i];
7009 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
7010 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
7011 c2 = ch2[i] = cloneIfMounted(ch2[i]);
7012 c2.el = c1.el;
7013 }
7014 if (!shallow)
7015 traverseStaticChildren(c1, c2);
7016 }
7017 // also inherit for comment nodes, but not placeholders (e.g. v-if which
7018 // would have received .el during block patch)
7019 if (c2.type === Comment$1 && !c2.el) {
7020 c2.el = c1.el;
7021 }
7022 }
7023 }
7024}
7025// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
7026function getSequence(arr) {
7027 const p = arr.slice();
7028 const result = [0];
7029 let i, j, u, v, c;
7030 const len = arr.length;
7031 for (i = 0; i < len; i++) {
7032 const arrI = arr[i];
7033 if (arrI !== 0) {
7034 j = result[result.length - 1];
7035 if (arr[j] < arrI) {
7036 p[i] = j;
7037 result.push(i);
7038 continue;
7039 }
7040 u = 0;
7041 v = result.length - 1;
7042 while (u < v) {
7043 c = ((u + v) / 2) | 0;
7044 if (arr[result[c]] < arrI) {
7045 u = c + 1;
7046 }
7047 else {
7048 v = c;
7049 }
7050 }
7051 if (arrI < arr[result[u]]) {
7052 if (u > 0) {
7053 p[i] = result[u - 1];
7054 }
7055 result[u] = i;
7056 }
7057 }
7058 }
7059 u = result.length;
7060 v = result[u - 1];
7061 while (u-- > 0) {
7062 result[u] = v;
7063 v = p[v];
7064 }
7065 return result;
7066}
7067
7068const isTeleport = (type) => type.__isTeleport;
7069const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
7070const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
7071const resolveTarget = (props, select) => {
7072 const targetSelector = props && props.to;
7073 if (isString(targetSelector)) {
7074 if (!select) {
7075 warn(`Current renderer does not support string target for Teleports. ` +
7076 `(missing querySelector renderer option)`);
7077 return null;
7078 }
7079 else {
7080 const target = select(targetSelector);
7081 if (!target) {
7082 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
7083 `Note the target element must exist before the component is mounted - ` +
7084 `i.e. the target cannot be rendered by the component itself, and ` +
7085 `ideally should be outside of the entire Vue component tree.`);
7086 }
7087 return target;
7088 }
7089 }
7090 else {
7091 if (!targetSelector && !isTeleportDisabled(props)) {
7092 warn(`Invalid Teleport target: ${targetSelector}`);
7093 }
7094 return targetSelector;
7095 }
7096};
7097const TeleportImpl = {
7098 __isTeleport: true,
7099 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
7100 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
7101 const disabled = isTeleportDisabled(n2.props);
7102 let { shapeFlag, children, dynamicChildren } = n2;
7103 // #3302
7104 // HMR updated, force full diff
7105 if (isHmrUpdating) {
7106 optimized = false;
7107 dynamicChildren = null;
7108 }
7109 if (n1 == null) {
7110 // insert anchors in the main view
7111 const placeholder = (n2.el = createComment('teleport start')
7112 );
7113 const mainAnchor = (n2.anchor = createComment('teleport end')
7114 );
7115 insert(placeholder, container, anchor);
7116 insert(mainAnchor, container, anchor);
7117 const target = (n2.target = resolveTarget(n2.props, querySelector));
7118 const targetAnchor = (n2.targetAnchor = createText(''));
7119 if (target) {
7120 insert(targetAnchor, target);
7121 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
7122 isSVG = isSVG || isTargetSVG(target);
7123 }
7124 else if (!disabled) {
7125 warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
7126 }
7127 const mount = (container, anchor) => {
7128 // Teleport *always* has Array children. This is enforced in both the
7129 // compiler and vnode children normalization.
7130 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7131 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7132 }
7133 };
7134 if (disabled) {
7135 mount(container, mainAnchor);
7136 }
7137 else if (target) {
7138 mount(target, targetAnchor);
7139 }
7140 }
7141 else {
7142 // update content
7143 n2.el = n1.el;
7144 const mainAnchor = (n2.anchor = n1.anchor);
7145 const target = (n2.target = n1.target);
7146 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
7147 const wasDisabled = isTeleportDisabled(n1.props);
7148 const currentContainer = wasDisabled ? container : target;
7149 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
7150 isSVG = isSVG || isTargetSVG(target);
7151 if (dynamicChildren) {
7152 // fast path when the teleport happens to be a block root
7153 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
7154 // even in block tree mode we need to make sure all root-level nodes
7155 // in the teleport inherit previous DOM references so that they can
7156 // be moved in future patches.
7157 traverseStaticChildren(n1, n2, true);
7158 }
7159 else if (!optimized) {
7160 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
7161 }
7162 if (disabled) {
7163 if (!wasDisabled) {
7164 // enabled -> disabled
7165 // move into main container
7166 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
7167 }
7168 }
7169 else {
7170 // target changed
7171 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
7172 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
7173 if (nextTarget) {
7174 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
7175 }
7176 else {
7177 warn('Invalid Teleport target on update:', target, `(${typeof target})`);
7178 }
7179 }
7180 else if (wasDisabled) {
7181 // disabled -> enabled
7182 // move into teleport target
7183 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
7184 }
7185 }
7186 }
7187 },
7188 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
7189 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
7190 if (target) {
7191 hostRemove(targetAnchor);
7192 }
7193 // an unmounted teleport should always remove its children if not disabled
7194 if (doRemove || !isTeleportDisabled(props)) {
7195 hostRemove(anchor);
7196 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7197 for (let i = 0; i < children.length; i++) {
7198 const child = children[i];
7199 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
7200 }
7201 }
7202 }
7203 },
7204 move: moveTeleport,
7205 hydrate: hydrateTeleport
7206};
7207function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
7208 // move target anchor if this is a target change.
7209 if (moveType === 0 /* TARGET_CHANGE */) {
7210 insert(vnode.targetAnchor, container, parentAnchor);
7211 }
7212 const { el, anchor, shapeFlag, children, props } = vnode;
7213 const isReorder = moveType === 2 /* REORDER */;
7214 // move main view anchor if this is a re-order.
7215 if (isReorder) {
7216 insert(el, container, parentAnchor);
7217 }
7218 // if this is a re-order and teleport is enabled (content is in target)
7219 // do not move children. So the opposite is: only move children if this
7220 // is not a reorder, or the teleport is disabled
7221 if (!isReorder || isTeleportDisabled(props)) {
7222 // Teleport has either Array children or no children.
7223 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
7224 for (let i = 0; i < children.length; i++) {
7225 move(children[i], container, parentAnchor, 2 /* REORDER */);
7226 }
7227 }
7228 }
7229 // move main view anchor if this is a re-order.
7230 if (isReorder) {
7231 insert(anchor, container, parentAnchor);
7232 }
7233}
7234function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
7235 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
7236 if (target) {
7237 // if multiple teleports rendered to the same target element, we need to
7238 // pick up from where the last teleport finished instead of the first node
7239 const targetNode = target._lpa || target.firstChild;
7240 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
7241 if (isTeleportDisabled(vnode.props)) {
7242 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
7243 vnode.targetAnchor = targetNode;
7244 }
7245 else {
7246 vnode.anchor = nextSibling(node);
7247 vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
7248 }
7249 target._lpa =
7250 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
7251 }
7252 }
7253 return vnode.anchor && nextSibling(vnode.anchor);
7254}
7255// Force-casted public typing for h and TSX props inference
7256const Teleport = TeleportImpl;
7257
7258const COMPONENTS = 'components';
7259const DIRECTIVES = 'directives';
7260/**
7261 * @private
7262 */
7263function resolveComponent(name, maybeSelfReference) {
7264 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
7265}
7266const NULL_DYNAMIC_COMPONENT = Symbol();
7267/**
7268 * @private
7269 */
7270function resolveDynamicComponent(component) {
7271 if (isString(component)) {
7272 return resolveAsset(COMPONENTS, component, false) || component;
7273 }
7274 else {
7275 // invalid types will fallthrough to createVNode and raise warning
7276 return (component || NULL_DYNAMIC_COMPONENT);
7277 }
7278}
7279/**
7280 * @private
7281 */
7282function resolveDirective(name) {
7283 return resolveAsset(DIRECTIVES, name);
7284}
7285// implementation
7286function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
7287 const instance = currentRenderingInstance || currentInstance;
7288 if (instance) {
7289 const Component = instance.type;
7290 // explicit self name has highest priority
7291 if (type === COMPONENTS) {
7292 const selfName = getComponentName(Component);
7293 if (selfName &&
7294 (selfName === name ||
7295 selfName === camelize(name) ||
7296 selfName === capitalize(camelize(name)))) {
7297 return Component;
7298 }
7299 }
7300 const res =
7301 // local registration
7302 // check instance[type] first which is resolved for options API
7303 resolve(instance[type] || Component[type], name) ||
7304 // global registration
7305 resolve(instance.appContext[type], name);
7306 if (!res && maybeSelfReference) {
7307 // fallback to implicit self-reference
7308 return Component;
7309 }
7310 if (warnMissing && !res) {
7311 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
7312 }
7313 return res;
7314 }
7315 else {
7316 warn(`resolve${capitalize(type.slice(0, -1))} ` +
7317 `can only be used in render() or setup().`);
7318 }
7319}
7320function resolve(registry, name) {
7321 return (registry &&
7322 (registry[name] ||
7323 registry[camelize(name)] ||
7324 registry[capitalize(camelize(name))]));
7325}
7326
7327const Fragment = Symbol('Fragment' );
7328const Text = Symbol('Text' );
7329const Comment$1 = Symbol('Comment' );
7330const Static = Symbol('Static' );
7331// Since v-if and v-for are the two possible ways node structure can dynamically
7332// change, once we consider v-if branches and each v-for fragment a block, we
7333// can divide a template into nested blocks, and within each block the node
7334// structure would be stable. This allows us to skip most children diffing
7335// and only worry about the dynamic nodes (indicated by patch flags).
7336const blockStack = [];
7337let currentBlock = null;
7338/**
7339 * Open a block.
7340 * This must be called before `createBlock`. It cannot be part of `createBlock`
7341 * because the children of the block are evaluated before `createBlock` itself
7342 * is called. The generated code typically looks like this:
7343 *
7344 * ```js
7345 * function render() {
7346 * return (openBlock(),createBlock('div', null, [...]))
7347 * }
7348 * ```
7349 * disableTracking is true when creating a v-for fragment block, since a v-for
7350 * fragment always diffs its children.
7351 *
7352 * @private
7353 */
7354function openBlock(disableTracking = false) {
7355 blockStack.push((currentBlock = disableTracking ? null : []));
7356}
7357function closeBlock() {
7358 blockStack.pop();
7359 currentBlock = blockStack[blockStack.length - 1] || null;
7360}
7361// Whether we should be tracking dynamic child nodes inside a block.
7362// Only tracks when this value is > 0
7363// We are not using a simple boolean because this value may need to be
7364// incremented/decremented by nested usage of v-once (see below)
7365let isBlockTreeEnabled = 1;
7366/**
7367 * Block tracking sometimes needs to be disabled, for example during the
7368 * creation of a tree that needs to be cached by v-once. The compiler generates
7369 * code like this:
7370 *
7371 * ``` js
7372 * _cache[1] || (
7373 * setBlockTracking(-1),
7374 * _cache[1] = createVNode(...),
7375 * setBlockTracking(1),
7376 * _cache[1]
7377 * )
7378 * ```
7379 *
7380 * @private
7381 */
7382function setBlockTracking(value) {
7383 isBlockTreeEnabled += value;
7384}
7385/**
7386 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
7387 * A block root keeps track of dynamic nodes within the block in the
7388 * `dynamicChildren` array.
7389 *
7390 * @private
7391 */
7392function createBlock(type, props, children, patchFlag, dynamicProps) {
7393 const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
7394 // save current block children on the block vnode
7395 vnode.dynamicChildren =
7396 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
7397 // close block
7398 closeBlock();
7399 // a block is always going to be patched, so track it as a child of its
7400 // parent block
7401 if (isBlockTreeEnabled > 0 && currentBlock) {
7402 currentBlock.push(vnode);
7403 }
7404 return vnode;
7405}
7406function isVNode(value) {
7407 return value ? value.__v_isVNode === true : false;
7408}
7409function isSameVNodeType(n1, n2) {
7410 if (n2.shapeFlag & 6 /* COMPONENT */ &&
7411 hmrDirtyComponents.has(n2.type)) {
7412 // HMR only: if the component has been hot-updated, force a reload.
7413 return false;
7414 }
7415 return n1.type === n2.type && n1.key === n2.key;
7416}
7417let vnodeArgsTransformer;
7418/**
7419 * Internal API for registering an arguments transform for createVNode
7420 * used for creating stubs in the test-utils
7421 * It is *internal* but needs to be exposed for test-utils to pick up proper
7422 * typings
7423 */
7424function transformVNodeArgs(transformer) {
7425 vnodeArgsTransformer = transformer;
7426}
7427const createVNodeWithArgsTransform = (...args) => {
7428 return _createVNode(...(vnodeArgsTransformer
7429 ? vnodeArgsTransformer(args, currentRenderingInstance)
7430 : args));
7431};
7432const InternalObjectKey = `__vInternal`;
7433const normalizeKey = ({ key }) => key != null ? key : null;
7434const normalizeRef = ({ ref }) => {
7435 return (ref != null
7436 ? isString(ref) || isRef(ref) || isFunction(ref)
7437 ? { i: currentRenderingInstance, r: ref }
7438 : ref
7439 : null);
7440};
7441const createVNode = (createVNodeWithArgsTransform
7442 );
7443function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
7444 if (!type || type === NULL_DYNAMIC_COMPONENT) {
7445 if (!type) {
7446 warn(`Invalid vnode type when creating vnode: ${type}.`);
7447 }
7448 type = Comment$1;
7449 }
7450 if (isVNode(type)) {
7451 // createVNode receiving an existing vnode. This happens in cases like
7452 // <component :is="vnode"/>
7453 // #2078 make sure to merge refs during the clone instead of overwriting it
7454 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
7455 if (children) {
7456 normalizeChildren(cloned, children);
7457 }
7458 return cloned;
7459 }
7460 // class component normalization.
7461 if (isClassComponent(type)) {
7462 type = type.__vccOpts;
7463 }
7464 // class & style normalization.
7465 if (props) {
7466 // for reactive or proxy objects, we need to clone it to enable mutation.
7467 if (isProxy(props) || InternalObjectKey in props) {
7468 props = extend({}, props);
7469 }
7470 let { class: klass, style } = props;
7471 if (klass && !isString(klass)) {
7472 props.class = normalizeClass(klass);
7473 }
7474 if (isObject(style)) {
7475 // reactive state objects need to be cloned since they are likely to be
7476 // mutated
7477 if (isProxy(style) && !isArray(style)) {
7478 style = extend({}, style);
7479 }
7480 props.style = normalizeStyle(style);
7481 }
7482 }
7483 // encode the vnode type information into a bitmap
7484 const shapeFlag = isString(type)
7485 ? 1 /* ELEMENT */
7486 : isSuspense(type)
7487 ? 128 /* SUSPENSE */
7488 : isTeleport(type)
7489 ? 64 /* TELEPORT */
7490 : isObject(type)
7491 ? 4 /* STATEFUL_COMPONENT */
7492 : isFunction(type)
7493 ? 2 /* FUNCTIONAL_COMPONENT */
7494 : 0;
7495 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
7496 type = toRaw(type);
7497 warn(`Vue received a Component which was made a reactive object. This can ` +
7498 `lead to unnecessary performance overhead, and should be avoided by ` +
7499 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
7500 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
7501 }
7502 const vnode = {
7503 __v_isVNode: true,
7504 __v_skip: true,
7505 type,
7506 props,
7507 key: props && normalizeKey(props),
7508 ref: props && normalizeRef(props),
7509 scopeId: currentScopeId,
7510 slotScopeIds: null,
7511 children: null,
7512 component: null,
7513 suspense: null,
7514 ssContent: null,
7515 ssFallback: null,
7516 dirs: null,
7517 transition: null,
7518 el: null,
7519 anchor: null,
7520 target: null,
7521 targetAnchor: null,
7522 staticCount: 0,
7523 shapeFlag,
7524 patchFlag,
7525 dynamicProps,
7526 dynamicChildren: null,
7527 appContext: null
7528 };
7529 // validate key
7530 if (vnode.key !== vnode.key) {
7531 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
7532 }
7533 normalizeChildren(vnode, children);
7534 // normalize suspense children
7535 if (shapeFlag & 128 /* SUSPENSE */) {
7536 type.normalize(vnode);
7537 }
7538 if (isBlockTreeEnabled > 0 &&
7539 // avoid a block node from tracking itself
7540 !isBlockNode &&
7541 // has current parent block
7542 currentBlock &&
7543 // presence of a patch flag indicates this node needs patching on updates.
7544 // component nodes also should always be patched, because even if the
7545 // component doesn't need to update, it needs to persist the instance on to
7546 // the next vnode so that it can be properly unmounted later.
7547 (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
7548 // the EVENTS flag is only for hydration and if it is the only flag, the
7549 // vnode should not be considered dynamic due to handler caching.
7550 patchFlag !== 32 /* HYDRATE_EVENTS */) {
7551 currentBlock.push(vnode);
7552 }
7553 return vnode;
7554}
7555function cloneVNode(vnode, extraProps, mergeRef = false) {
7556 // This is intentionally NOT using spread or extend to avoid the runtime
7557 // key enumeration cost.
7558 const { props, ref, patchFlag, children } = vnode;
7559 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
7560 const cloned = {
7561 __v_isVNode: true,
7562 __v_skip: true,
7563 type: vnode.type,
7564 props: mergedProps,
7565 key: mergedProps && normalizeKey(mergedProps),
7566 ref: extraProps && extraProps.ref
7567 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
7568 // if the vnode itself already has a ref, cloneVNode will need to merge
7569 // the refs so the single vnode can be set on multiple refs
7570 mergeRef && ref
7571 ? isArray(ref)
7572 ? ref.concat(normalizeRef(extraProps))
7573 : [ref, normalizeRef(extraProps)]
7574 : normalizeRef(extraProps)
7575 : ref,
7576 scopeId: vnode.scopeId,
7577 slotScopeIds: vnode.slotScopeIds,
7578 children: patchFlag === -1 /* HOISTED */ && isArray(children)
7579 ? children.map(deepCloneVNode)
7580 : children,
7581 target: vnode.target,
7582 targetAnchor: vnode.targetAnchor,
7583 staticCount: vnode.staticCount,
7584 shapeFlag: vnode.shapeFlag,
7585 // if the vnode is cloned with extra props, we can no longer assume its
7586 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
7587 // note: perserve flag for fragments since they use the flag for children
7588 // fast paths only.
7589 patchFlag: extraProps && vnode.type !== Fragment
7590 ? patchFlag === -1 // hoisted node
7591 ? 16 /* FULL_PROPS */
7592 : patchFlag | 16 /* FULL_PROPS */
7593 : patchFlag,
7594 dynamicProps: vnode.dynamicProps,
7595 dynamicChildren: vnode.dynamicChildren,
7596 appContext: vnode.appContext,
7597 dirs: vnode.dirs,
7598 transition: vnode.transition,
7599 // These should technically only be non-null on mounted VNodes. However,
7600 // they *should* be copied for kept-alive vnodes. So we just always copy
7601 // them since them being non-null during a mount doesn't affect the logic as
7602 // they will simply be overwritten.
7603 component: vnode.component,
7604 suspense: vnode.suspense,
7605 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
7606 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
7607 el: vnode.el,
7608 anchor: vnode.anchor
7609 };
7610 return cloned;
7611}
7612/**
7613 * Dev only, for HMR of hoisted vnodes reused in v-for
7614 * https://github.com/vitejs/vite/issues/2022
7615 */
7616function deepCloneVNode(vnode) {
7617 const cloned = cloneVNode(vnode);
7618 if (isArray(vnode.children)) {
7619 cloned.children = vnode.children.map(deepCloneVNode);
7620 }
7621 return cloned;
7622}
7623/**
7624 * @private
7625 */
7626function createTextVNode(text = ' ', flag = 0) {
7627 return createVNode(Text, null, text, flag);
7628}
7629/**
7630 * @private
7631 */
7632function createStaticVNode(content, numberOfNodes) {
7633 // A static vnode can contain multiple stringified elements, and the number
7634 // of elements is necessary for hydration.
7635 const vnode = createVNode(Static, null, content);
7636 vnode.staticCount = numberOfNodes;
7637 return vnode;
7638}
7639/**
7640 * @private
7641 */
7642function createCommentVNode(text = '',
7643// when used as the v-else branch, the comment node must be created as a
7644// block to ensure correct updates.
7645asBlock = false) {
7646 return asBlock
7647 ? (openBlock(), createBlock(Comment$1, null, text))
7648 : createVNode(Comment$1, null, text);
7649}
7650function normalizeVNode(child) {
7651 if (child == null || typeof child === 'boolean') {
7652 // empty placeholder
7653 return createVNode(Comment$1);
7654 }
7655 else if (isArray(child)) {
7656 // fragment
7657 return createVNode(Fragment, null,
7658 // #3666, avoid reference pollution when reusing vnode
7659 child.slice());
7660 }
7661 else if (typeof child === 'object') {
7662 // already vnode, this should be the most common since compiled templates
7663 // always produce all-vnode children arrays
7664 return cloneIfMounted(child);
7665 }
7666 else {
7667 // strings and numbers
7668 return createVNode(Text, null, String(child));
7669 }
7670}
7671// optimized normalization for template-compiled render fns
7672function cloneIfMounted(child) {
7673 return child.el === null ? child : cloneVNode(child);
7674}
7675function normalizeChildren(vnode, children) {
7676 let type = 0;
7677 const { shapeFlag } = vnode;
7678 if (children == null) {
7679 children = null;
7680 }
7681 else if (isArray(children)) {
7682 type = 16 /* ARRAY_CHILDREN */;
7683 }
7684 else if (typeof children === 'object') {
7685 if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
7686 // Normalize slot to plain children for plain element and Teleport
7687 const slot = children.default;
7688 if (slot) {
7689 // _c marker is added by withCtx() indicating this is a compiled slot
7690 slot._c && (slot._d = false);
7691 normalizeChildren(vnode, slot());
7692 slot._c && (slot._d = true);
7693 }
7694 return;
7695 }
7696 else {
7697 type = 32 /* SLOTS_CHILDREN */;
7698 const slotFlag = children._;
7699 if (!slotFlag && !(InternalObjectKey in children)) {
7700 children._ctx = currentRenderingInstance;
7701 }
7702 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
7703 // a child component receives forwarded slots from the parent.
7704 // its slot type is determined by its parent's slot type.
7705 if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
7706 children._ = 1 /* STABLE */;
7707 }
7708 else {
7709 children._ = 2 /* DYNAMIC */;
7710 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
7711 }
7712 }
7713 }
7714 }
7715 else if (isFunction(children)) {
7716 children = { default: children, _ctx: currentRenderingInstance };
7717 type = 32 /* SLOTS_CHILDREN */;
7718 }
7719 else {
7720 children = String(children);
7721 // force teleport children to array so it can be moved around
7722 if (shapeFlag & 64 /* TELEPORT */) {
7723 type = 16 /* ARRAY_CHILDREN */;
7724 children = [createTextVNode(children)];
7725 }
7726 else {
7727 type = 8 /* TEXT_CHILDREN */;
7728 }
7729 }
7730 vnode.children = children;
7731 vnode.shapeFlag |= type;
7732}
7733function mergeProps(...args) {
7734 const ret = extend({}, args[0]);
7735 for (let i = 1; i < args.length; i++) {
7736 const toMerge = args[i];
7737 for (const key in toMerge) {
7738 if (key === 'class') {
7739 if (ret.class !== toMerge.class) {
7740 ret.class = normalizeClass([ret.class, toMerge.class]);
7741 }
7742 }
7743 else if (key === 'style') {
7744 ret.style = normalizeStyle([ret.style, toMerge.style]);
7745 }
7746 else if (isOn(key)) {
7747 const existing = ret[key];
7748 const incoming = toMerge[key];
7749 if (existing !== incoming) {
7750 ret[key] = existing
7751 ? [].concat(existing, incoming)
7752 : incoming;
7753 }
7754 }
7755 else if (key !== '') {
7756 ret[key] = toMerge[key];
7757 }
7758 }
7759 }
7760 return ret;
7761}
7762
7763/**
7764 * Actual implementation
7765 */
7766function renderList(source, renderItem) {
7767 let ret;
7768 if (isArray(source) || isString(source)) {
7769 ret = new Array(source.length);
7770 for (let i = 0, l = source.length; i < l; i++) {
7771 ret[i] = renderItem(source[i], i);
7772 }
7773 }
7774 else if (typeof source === 'number') {
7775 if (!Number.isInteger(source)) {
7776 warn(`The v-for range expect an integer value but got ${source}.`);
7777 return [];
7778 }
7779 ret = new Array(source);
7780 for (let i = 0; i < source; i++) {
7781 ret[i] = renderItem(i + 1, i);
7782 }
7783 }
7784 else if (isObject(source)) {
7785 if (source[Symbol.iterator]) {
7786 ret = Array.from(source, renderItem);
7787 }
7788 else {
7789 const keys = Object.keys(source);
7790 ret = new Array(keys.length);
7791 for (let i = 0, l = keys.length; i < l; i++) {
7792 const key = keys[i];
7793 ret[i] = renderItem(source[key], key, i);
7794 }
7795 }
7796 }
7797 else {
7798 ret = [];
7799 }
7800 return ret;
7801}
7802
7803/**
7804 * Compiler runtime helper for creating dynamic slots object
7805 * @private
7806 */
7807function createSlots(slots, dynamicSlots) {
7808 for (let i = 0; i < dynamicSlots.length; i++) {
7809 const slot = dynamicSlots[i];
7810 // array of dynamic slot generated by <template v-for="..." #[...]>
7811 if (isArray(slot)) {
7812 for (let j = 0; j < slot.length; j++) {
7813 slots[slot[j].name] = slot[j].fn;
7814 }
7815 }
7816 else if (slot) {
7817 // conditional single slot generated by <template v-if="..." #foo>
7818 slots[slot.name] = slot.fn;
7819 }
7820 }
7821 return slots;
7822}
7823
7824/**
7825 * Compiler runtime helper for rendering `<slot/>`
7826 * @private
7827 */
7828function renderSlot(slots, name, props = {},
7829// this is not a user-facing function, so the fallback is always generated by
7830// the compiler and guaranteed to be a function returning an array
7831fallback, noSlotted) {
7832 let slot = slots[name];
7833 if (slot && slot.length > 1) {
7834 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
7835 `function. You need to mark this component with $dynamic-slots in the ` +
7836 `parent template.`);
7837 slot = () => [];
7838 }
7839 // a compiled slot disables block tracking by default to avoid manual
7840 // invocation interfering with template-based block tracking, but in
7841 // `renderSlot` we can be sure that it's template-based so we can force
7842 // enable it.
7843 if (slot && slot._c) {
7844 slot._d = false;
7845 }
7846 openBlock();
7847 const validSlotContent = slot && ensureValidVNode(slot(props));
7848 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
7849 ? 64 /* STABLE_FRAGMENT */
7850 : -2 /* BAIL */);
7851 if (!noSlotted && rendered.scopeId) {
7852 rendered.slotScopeIds = [rendered.scopeId + '-s'];
7853 }
7854 if (slot && slot._c) {
7855 slot._d = true;
7856 }
7857 return rendered;
7858}
7859function ensureValidVNode(vnodes) {
7860 return vnodes.some(child => {
7861 if (!isVNode(child))
7862 return true;
7863 if (child.type === Comment$1)
7864 return false;
7865 if (child.type === Fragment &&
7866 !ensureValidVNode(child.children))
7867 return false;
7868 return true;
7869 })
7870 ? vnodes
7871 : null;
7872}
7873
7874/**
7875 * For prefixing keys in v-on="obj" with "on"
7876 * @private
7877 */
7878function toHandlers(obj) {
7879 const ret = {};
7880 if (!isObject(obj)) {
7881 warn(`v-on with no argument expects an object value.`);
7882 return ret;
7883 }
7884 for (const key in obj) {
7885 ret[toHandlerKey(key)] = obj[key];
7886 }
7887 return ret;
7888}
7889
7890/**
7891 * #2437 In Vue 3, functional components do not have a public instance proxy but
7892 * they exist in the internal parent chain. For code that relies on traversing
7893 * public $parent chains, skip functional ones and go to the parent instead.
7894 */
7895const getPublicInstance = (i) => {
7896 if (!i)
7897 return null;
7898 if (isStatefulComponent(i))
7899 return i.exposed ? i.exposed : i.proxy;
7900 return getPublicInstance(i.parent);
7901};
7902const publicPropertiesMap = extend(Object.create(null), {
7903 $: i => i,
7904 $el: i => i.vnode.el,
7905 $data: i => i.data,
7906 $props: i => (shallowReadonly(i.props) ),
7907 $attrs: i => (shallowReadonly(i.attrs) ),
7908 $slots: i => (shallowReadonly(i.slots) ),
7909 $refs: i => (shallowReadonly(i.refs) ),
7910 $parent: i => getPublicInstance(i.parent),
7911 $root: i => getPublicInstance(i.root),
7912 $emit: i => i.emit,
7913 $options: i => (resolveMergedOptions(i) ),
7914 $forceUpdate: i => () => queueJob(i.update),
7915 $nextTick: i => nextTick.bind(i.proxy),
7916 $watch: i => (instanceWatch.bind(i) )
7917});
7918const PublicInstanceProxyHandlers = {
7919 get({ _: instance }, key) {
7920 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
7921 // let @vue/reactivity know it should never observe Vue public instances.
7922 if (key === "__v_skip" /* SKIP */) {
7923 return true;
7924 }
7925 // for internal formatters to know that this is a Vue instance
7926 if (key === '__isVue') {
7927 return true;
7928 }
7929 // data / props / ctx
7930 // This getter gets called for every property access on the render context
7931 // during render and is a major hotspot. The most expensive part of this
7932 // is the multiple hasOwn() calls. It's much faster to do a simple property
7933 // access on a plain object, so we use an accessCache object (with null
7934 // prototype) to memoize what access type a key corresponds to.
7935 let normalizedProps;
7936 if (key[0] !== '$') {
7937 const n = accessCache[key];
7938 if (n !== undefined) {
7939 switch (n) {
7940 case 0 /* SETUP */:
7941 return setupState[key];
7942 case 1 /* DATA */:
7943 return data[key];
7944 case 3 /* CONTEXT */:
7945 return ctx[key];
7946 case 2 /* PROPS */:
7947 return props[key];
7948 // default: just fallthrough
7949 }
7950 }
7951 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7952 accessCache[key] = 0 /* SETUP */;
7953 return setupState[key];
7954 }
7955 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7956 accessCache[key] = 1 /* DATA */;
7957 return data[key];
7958 }
7959 else if (
7960 // only cache other properties when instance has declared (thus stable)
7961 // props
7962 (normalizedProps = instance.propsOptions[0]) &&
7963 hasOwn(normalizedProps, key)) {
7964 accessCache[key] = 2 /* PROPS */;
7965 return props[key];
7966 }
7967 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7968 accessCache[key] = 3 /* CONTEXT */;
7969 return ctx[key];
7970 }
7971 else if (shouldCacheAccess) {
7972 accessCache[key] = 4 /* OTHER */;
7973 }
7974 }
7975 const publicGetter = publicPropertiesMap[key];
7976 let cssModule, globalProperties;
7977 // public $xxx properties
7978 if (publicGetter) {
7979 if (key === '$attrs') {
7980 track(instance, "get" /* GET */, key);
7981 markAttrsAccessed();
7982 }
7983 return publicGetter(instance);
7984 }
7985 else if (
7986 // css module (injected by vue-loader)
7987 (cssModule = type.__cssModules) &&
7988 (cssModule = cssModule[key])) {
7989 return cssModule;
7990 }
7991 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7992 // user may set custom properties to `this` that start with `$`
7993 accessCache[key] = 3 /* CONTEXT */;
7994 return ctx[key];
7995 }
7996 else if (
7997 // global properties
7998 ((globalProperties = appContext.config.globalProperties),
7999 hasOwn(globalProperties, key))) {
8000 {
8001 return globalProperties[key];
8002 }
8003 }
8004 else if (currentRenderingInstance &&
8005 (!isString(key) ||
8006 // #1091 avoid internal isRef/isVNode checks on component instance leading
8007 // to infinite warning loop
8008 key.indexOf('__v') !== 0)) {
8009 if (data !== EMPTY_OBJ &&
8010 (key[0] === '$' || key[0] === '_') &&
8011 hasOwn(data, key)) {
8012 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
8013 `character ("$" or "_") and is not proxied on the render context.`);
8014 }
8015 else if (instance === currentRenderingInstance) {
8016 warn(`Property ${JSON.stringify(key)} was accessed during render ` +
8017 `but is not defined on instance.`);
8018 }
8019 }
8020 },
8021 set({ _: instance }, key, value) {
8022 const { data, setupState, ctx } = instance;
8023 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
8024 setupState[key] = value;
8025 }
8026 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
8027 data[key] = value;
8028 }
8029 else if (hasOwn(instance.props, key)) {
8030 warn(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
8031 return false;
8032 }
8033 if (key[0] === '$' && key.slice(1) in instance) {
8034 warn(`Attempting to mutate public property "${key}". ` +
8035 `Properties starting with $ are reserved and readonly.`, instance);
8036 return false;
8037 }
8038 else {
8039 if (key in instance.appContext.config.globalProperties) {
8040 Object.defineProperty(ctx, key, {
8041 enumerable: true,
8042 configurable: true,
8043 value
8044 });
8045 }
8046 else {
8047 ctx[key] = value;
8048 }
8049 }
8050 return true;
8051 },
8052 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
8053 let normalizedProps;
8054 return (accessCache[key] !== undefined ||
8055 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
8056 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
8057 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
8058 hasOwn(ctx, key) ||
8059 hasOwn(publicPropertiesMap, key) ||
8060 hasOwn(appContext.config.globalProperties, key));
8061 }
8062};
8063{
8064 PublicInstanceProxyHandlers.ownKeys = (target) => {
8065 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
8066 `The keys will be empty in production mode to avoid performance overhead.`);
8067 return Reflect.ownKeys(target);
8068 };
8069}
8070const RuntimeCompiledPublicInstanceProxyHandlers = extend({}, PublicInstanceProxyHandlers, {
8071 get(target, key) {
8072 // fast path for unscopables when using `with` block
8073 if (key === Symbol.unscopables) {
8074 return;
8075 }
8076 return PublicInstanceProxyHandlers.get(target, key, target);
8077 },
8078 has(_, key) {
8079 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
8080 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
8081 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
8082 }
8083 return has;
8084 }
8085});
8086// In dev mode, the proxy target exposes the same properties as seen on `this`
8087// for easier console inspection. In prod mode it will be an empty object so
8088// these properties definitions can be skipped.
8089function createRenderContext(instance) {
8090 const target = {};
8091 // expose internal instance for proxy handlers
8092 Object.defineProperty(target, `_`, {
8093 configurable: true,
8094 enumerable: false,
8095 get: () => instance
8096 });
8097 // expose public properties
8098 Object.keys(publicPropertiesMap).forEach(key => {
8099 Object.defineProperty(target, key, {
8100 configurable: true,
8101 enumerable: false,
8102 get: () => publicPropertiesMap[key](instance),
8103 // intercepted by the proxy so no need for implementation,
8104 // but needed to prevent set errors
8105 set: NOOP
8106 });
8107 });
8108 return target;
8109}
8110// dev only
8111function exposePropsOnRenderContext(instance) {
8112 const { ctx, propsOptions: [propsOptions] } = instance;
8113 if (propsOptions) {
8114 Object.keys(propsOptions).forEach(key => {
8115 Object.defineProperty(ctx, key, {
8116 enumerable: true,
8117 configurable: true,
8118 get: () => instance.props[key],
8119 set: NOOP
8120 });
8121 });
8122 }
8123}
8124// dev only
8125function exposeSetupStateOnRenderContext(instance) {
8126 const { ctx, setupState } = instance;
8127 Object.keys(toRaw(setupState)).forEach(key => {
8128 if (key[0] === '$' || key[0] === '_') {
8129 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
8130 `which are reserved prefixes for Vue internals.`);
8131 return;
8132 }
8133 Object.defineProperty(ctx, key, {
8134 enumerable: true,
8135 configurable: true,
8136 get: () => setupState[key],
8137 set: NOOP
8138 });
8139 });
8140}
8141
8142const emptyAppContext = createAppContext();
8143let uid$2 = 0;
8144function createComponentInstance(vnode, parent, suspense) {
8145 const type = vnode.type;
8146 // inherit parent app context - or - if root, adopt from root vnode
8147 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
8148 const instance = {
8149 uid: uid$2++,
8150 vnode,
8151 type,
8152 parent,
8153 appContext,
8154 root: null,
8155 next: null,
8156 subTree: null,
8157 update: null,
8158 render: null,
8159 proxy: null,
8160 exposed: null,
8161 withProxy: null,
8162 effects: null,
8163 provides: parent ? parent.provides : Object.create(appContext.provides),
8164 accessCache: null,
8165 renderCache: [],
8166 // local resovled assets
8167 components: null,
8168 directives: null,
8169 // resolved props and emits options
8170 propsOptions: normalizePropsOptions(type, appContext),
8171 emitsOptions: normalizeEmitsOptions(type, appContext),
8172 // emit
8173 emit: null,
8174 emitted: null,
8175 // props default value
8176 propsDefaults: EMPTY_OBJ,
8177 // inheritAttrs
8178 inheritAttrs: type.inheritAttrs,
8179 // state
8180 ctx: EMPTY_OBJ,
8181 data: EMPTY_OBJ,
8182 props: EMPTY_OBJ,
8183 attrs: EMPTY_OBJ,
8184 slots: EMPTY_OBJ,
8185 refs: EMPTY_OBJ,
8186 setupState: EMPTY_OBJ,
8187 setupContext: null,
8188 // suspense related
8189 suspense,
8190 suspenseId: suspense ? suspense.pendingId : 0,
8191 asyncDep: null,
8192 asyncResolved: false,
8193 // lifecycle hooks
8194 // not using enums here because it results in computed properties
8195 isMounted: false,
8196 isUnmounted: false,
8197 isDeactivated: false,
8198 bc: null,
8199 c: null,
8200 bm: null,
8201 m: null,
8202 bu: null,
8203 u: null,
8204 um: null,
8205 bum: null,
8206 da: null,
8207 a: null,
8208 rtg: null,
8209 rtc: null,
8210 ec: null,
8211 sp: null
8212 };
8213 {
8214 instance.ctx = createRenderContext(instance);
8215 }
8216 instance.root = parent ? parent.root : instance;
8217 instance.emit = emit.bind(null, instance);
8218 return instance;
8219}
8220let currentInstance = null;
8221const getCurrentInstance = () => currentInstance || currentRenderingInstance;
8222const setCurrentInstance = (instance) => {
8223 currentInstance = instance;
8224};
8225const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
8226function validateComponentName(name, config) {
8227 const appIsNativeTag = config.isNativeTag || NO;
8228 if (isBuiltInTag(name) || appIsNativeTag(name)) {
8229 warn('Do not use built-in or reserved HTML elements as component id: ' + name);
8230 }
8231}
8232function isStatefulComponent(instance) {
8233 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
8234}
8235let isInSSRComponentSetup = false;
8236function setupComponent(instance, isSSR = false) {
8237 isInSSRComponentSetup = isSSR;
8238 const { props, children } = instance.vnode;
8239 const isStateful = isStatefulComponent(instance);
8240 initProps(instance, props, isStateful, isSSR);
8241 initSlots(instance, children);
8242 const setupResult = isStateful
8243 ? setupStatefulComponent(instance, isSSR)
8244 : undefined;
8245 isInSSRComponentSetup = false;
8246 return setupResult;
8247}
8248function setupStatefulComponent(instance, isSSR) {
8249 const Component = instance.type;
8250 {
8251 if (Component.name) {
8252 validateComponentName(Component.name, instance.appContext.config);
8253 }
8254 if (Component.components) {
8255 const names = Object.keys(Component.components);
8256 for (let i = 0; i < names.length; i++) {
8257 validateComponentName(names[i], instance.appContext.config);
8258 }
8259 }
8260 if (Component.directives) {
8261 const names = Object.keys(Component.directives);
8262 for (let i = 0; i < names.length; i++) {
8263 validateDirectiveName(names[i]);
8264 }
8265 }
8266 if (Component.compilerOptions && isRuntimeOnly()) {
8267 warn(`"compilerOptions" is only supported when using a build of Vue that ` +
8268 `includes the runtime compiler. Since you are using a runtime-only ` +
8269 `build, the options should be passed via your build tool config instead.`);
8270 }
8271 }
8272 // 0. create render proxy property access cache
8273 instance.accessCache = Object.create(null);
8274 // 1. create public instance / render proxy
8275 // also mark it raw so it's never observed
8276 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
8277 {
8278 exposePropsOnRenderContext(instance);
8279 }
8280 // 2. call setup()
8281 const { setup } = Component;
8282 if (setup) {
8283 const setupContext = (instance.setupContext =
8284 setup.length > 1 ? createSetupContext(instance) : null);
8285 currentInstance = instance;
8286 pauseTracking();
8287 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
8288 resetTracking();
8289 currentInstance = null;
8290 if (isPromise(setupResult)) {
8291 if (isSSR) {
8292 // return the promise so server-renderer can wait on it
8293 return setupResult
8294 .then((resolvedResult) => {
8295 handleSetupResult(instance, resolvedResult, isSSR);
8296 })
8297 .catch(e => {
8298 handleError(e, instance, 0 /* SETUP_FUNCTION */);
8299 });
8300 }
8301 else {
8302 // async setup returned Promise.
8303 // bail here and wait for re-entry.
8304 instance.asyncDep = setupResult;
8305 }
8306 }
8307 else {
8308 handleSetupResult(instance, setupResult, isSSR);
8309 }
8310 }
8311 else {
8312 finishComponentSetup(instance, isSSR);
8313 }
8314}
8315function handleSetupResult(instance, setupResult, isSSR) {
8316 if (isFunction(setupResult)) {
8317 // setup returned an inline render function
8318 {
8319 instance.render = setupResult;
8320 }
8321 }
8322 else if (isObject(setupResult)) {
8323 if (isVNode(setupResult)) {
8324 warn(`setup() should not return VNodes directly - ` +
8325 `return a render function instead.`);
8326 }
8327 // setup returned bindings.
8328 // assuming a render function compiled from template is present.
8329 {
8330 instance.devtoolsRawSetupState = setupResult;
8331 }
8332 instance.setupState = proxyRefs(setupResult);
8333 {
8334 exposeSetupStateOnRenderContext(instance);
8335 }
8336 }
8337 else if (setupResult !== undefined) {
8338 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
8339 }
8340 finishComponentSetup(instance, isSSR);
8341}
8342let compile;
8343// dev only
8344const isRuntimeOnly = () => !compile;
8345/**
8346 * For runtime-dom to register the compiler.
8347 * Note the exported method uses any to avoid d.ts relying on the compiler types.
8348 */
8349function registerRuntimeCompiler(_compile) {
8350 compile = _compile;
8351}
8352function finishComponentSetup(instance, isSSR, skipOptions) {
8353 const Component = instance.type;
8354 // template / render function normalization
8355 if (!instance.render) {
8356 // could be set from setup()
8357 if (compile && !Component.render) {
8358 const template = Component.template;
8359 if (template) {
8360 {
8361 startMeasure(instance, `compile`);
8362 }
8363 const { isCustomElement, compilerOptions } = instance.appContext.config;
8364 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
8365 const finalCompilerOptions = extend(extend({
8366 isCustomElement,
8367 delimiters
8368 }, compilerOptions), componentCompilerOptions);
8369 Component.render = compile(template, finalCompilerOptions);
8370 {
8371 endMeasure(instance, `compile`);
8372 }
8373 }
8374 }
8375 instance.render = (Component.render || NOOP);
8376 // for runtime-compiled render functions using `with` blocks, the render
8377 // proxy used needs a different `has` handler which is more performant and
8378 // also only allows a whitelist of globals to fallthrough.
8379 if (instance.render._rc) {
8380 instance.withProxy = new Proxy(instance.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
8381 }
8382 }
8383 // support for 2.x options
8384 {
8385 currentInstance = instance;
8386 pauseTracking();
8387 applyOptions(instance);
8388 resetTracking();
8389 currentInstance = null;
8390 }
8391 // warn missing template/render
8392 // the runtime compilation of template in SSR is done by server-render
8393 if (!Component.render && instance.render === NOOP && !isSSR) {
8394 /* istanbul ignore if */
8395 if (!compile && Component.template) {
8396 warn(`Component provided template option but ` +
8397 `runtime compilation is not supported in this build of Vue.` +
8398 (` Use "vue.esm-browser.js" instead.`
8399 ) /* should not happen */);
8400 }
8401 else {
8402 warn(`Component is missing template or render function.`);
8403 }
8404 }
8405}
8406const attrHandlers = {
8407 get: (target, key) => {
8408 {
8409 markAttrsAccessed();
8410 }
8411 return target[key];
8412 },
8413 set: () => {
8414 warn(`setupContext.attrs is readonly.`);
8415 return false;
8416 },
8417 deleteProperty: () => {
8418 warn(`setupContext.attrs is readonly.`);
8419 return false;
8420 }
8421};
8422function createSetupContext(instance) {
8423 const expose = exposed => {
8424 if (instance.exposed) {
8425 warn(`expose() should be called only once per setup().`);
8426 }
8427 instance.exposed = proxyRefs(exposed);
8428 };
8429 {
8430 // We use getters in dev in case libs like test-utils overwrite instance
8431 // properties (overwrites should not be done in prod)
8432 return Object.freeze({
8433 get attrs() {
8434 return new Proxy(instance.attrs, attrHandlers);
8435 },
8436 get slots() {
8437 return shallowReadonly(instance.slots);
8438 },
8439 get emit() {
8440 return (event, ...args) => instance.emit(event, ...args);
8441 },
8442 expose
8443 });
8444 }
8445}
8446// record effects created during a component's setup() so that they can be
8447// stopped when the component unmounts
8448function recordInstanceBoundEffect(effect, instance = currentInstance) {
8449 if (instance) {
8450 (instance.effects || (instance.effects = [])).push(effect);
8451 }
8452}
8453const classifyRE = /(?:^|[-_])(\w)/g;
8454const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
8455function getComponentName(Component) {
8456 return isFunction(Component)
8457 ? Component.displayName || Component.name
8458 : Component.name;
8459}
8460/* istanbul ignore next */
8461function formatComponentName(instance, Component, isRoot = false) {
8462 let name = getComponentName(Component);
8463 if (!name && Component.__file) {
8464 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
8465 if (match) {
8466 name = match[1];
8467 }
8468 }
8469 if (!name && instance && instance.parent) {
8470 // try to infer the name based on reverse resolution
8471 const inferFromRegistry = (registry) => {
8472 for (const key in registry) {
8473 if (registry[key] === Component) {
8474 return key;
8475 }
8476 }
8477 };
8478 name =
8479 inferFromRegistry(instance.components ||
8480 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
8481 }
8482 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
8483}
8484function isClassComponent(value) {
8485 return isFunction(value) && '__vccOpts' in value;
8486}
8487
8488function computed$1(getterOrOptions) {
8489 const c = computed(getterOrOptions);
8490 recordInstanceBoundEffect(c.effect);
8491 return c;
8492}
8493
8494// implementation
8495function defineProps() {
8496 {
8497 warn(`defineProps() is a compiler-hint helper that is only usable inside ` +
8498 `<script setup> of a single file component. Its arguments should be ` +
8499 `compiled away and passing it at runtime has no effect.`);
8500 }
8501 return null;
8502}
8503// implementation
8504function defineEmit() {
8505 {
8506 warn(`defineEmit() is a compiler-hint helper that is only usable inside ` +
8507 `<script setup> of a single file component. Its arguments should be ` +
8508 `compiled away and passing it at runtime has no effect.`);
8509 }
8510 return null;
8511}
8512function useContext() {
8513 const i = getCurrentInstance();
8514 if (!i) {
8515 warn(`useContext() called without active instance.`);
8516 }
8517 return i.setupContext || (i.setupContext = createSetupContext(i));
8518}
8519
8520// Actual implementation
8521function h(type, propsOrChildren, children) {
8522 const l = arguments.length;
8523 if (l === 2) {
8524 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
8525 // single vnode without props
8526 if (isVNode(propsOrChildren)) {
8527 return createVNode(type, null, [propsOrChildren]);
8528 }
8529 // props without children
8530 return createVNode(type, propsOrChildren);
8531 }
8532 else {
8533 // omit props
8534 return createVNode(type, null, propsOrChildren);
8535 }
8536 }
8537 else {
8538 if (l > 3) {
8539 children = Array.prototype.slice.call(arguments, 2);
8540 }
8541 else if (l === 3 && isVNode(children)) {
8542 children = [children];
8543 }
8544 return createVNode(type, propsOrChildren, children);
8545 }
8546}
8547
8548const ssrContextKey = Symbol(`ssrContext` );
8549const useSSRContext = () => {
8550 {
8551 const ctx = inject(ssrContextKey);
8552 if (!ctx) {
8553 warn(`Server rendering context not provided. Make sure to only call ` +
8554 `useSSRContext() conditionally in the server build.`);
8555 }
8556 return ctx;
8557 }
8558};
8559
8560function initCustomFormatter() {
8561 /* eslint-disable no-restricted-globals */
8562 if (typeof window === 'undefined') {
8563 return;
8564 }
8565 const vueStyle = { style: 'color:#3ba776' };
8566 const numberStyle = { style: 'color:#0b1bc9' };
8567 const stringStyle = { style: 'color:#b62e24' };
8568 const keywordStyle = { style: 'color:#9d288c' };
8569 // custom formatter for Chrome
8570 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
8571 const formatter = {
8572 header(obj) {
8573 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
8574 if (!isObject(obj)) {
8575 return null;
8576 }
8577 if (obj.__isVue) {
8578 return ['div', vueStyle, `VueInstance`];
8579 }
8580 else if (isRef(obj)) {
8581 return [
8582 'div',
8583 {},
8584 ['span', vueStyle, genRefFlag(obj)],
8585 '<',
8586 formatValue(obj.value),
8587 `>`
8588 ];
8589 }
8590 else if (isReactive(obj)) {
8591 return [
8592 'div',
8593 {},
8594 ['span', vueStyle, 'Reactive'],
8595 '<',
8596 formatValue(obj),
8597 `>${isReadonly(obj) ? ` (readonly)` : ``}`
8598 ];
8599 }
8600 else if (isReadonly(obj)) {
8601 return [
8602 'div',
8603 {},
8604 ['span', vueStyle, 'Readonly'],
8605 '<',
8606 formatValue(obj),
8607 '>'
8608 ];
8609 }
8610 return null;
8611 },
8612 hasBody(obj) {
8613 return obj && obj.__isVue;
8614 },
8615 body(obj) {
8616 if (obj && obj.__isVue) {
8617 return [
8618 'div',
8619 {},
8620 ...formatInstance(obj.$)
8621 ];
8622 }
8623 }
8624 };
8625 function formatInstance(instance) {
8626 const blocks = [];
8627 if (instance.type.props && instance.props) {
8628 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
8629 }
8630 if (instance.setupState !== EMPTY_OBJ) {
8631 blocks.push(createInstanceBlock('setup', instance.setupState));
8632 }
8633 if (instance.data !== EMPTY_OBJ) {
8634 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
8635 }
8636 const computed = extractKeys(instance, 'computed');
8637 if (computed) {
8638 blocks.push(createInstanceBlock('computed', computed));
8639 }
8640 const injected = extractKeys(instance, 'inject');
8641 if (injected) {
8642 blocks.push(createInstanceBlock('injected', injected));
8643 }
8644 blocks.push([
8645 'div',
8646 {},
8647 [
8648 'span',
8649 {
8650 style: keywordStyle.style + ';opacity:0.66'
8651 },
8652 '$ (internal): '
8653 ],
8654 ['object', { object: instance }]
8655 ]);
8656 return blocks;
8657 }
8658 function createInstanceBlock(type, target) {
8659 target = extend({}, target);
8660 if (!Object.keys(target).length) {
8661 return ['span', {}];
8662 }
8663 return [
8664 'div',
8665 { style: 'line-height:1.25em;margin-bottom:0.6em' },
8666 [
8667 'div',
8668 {
8669 style: 'color:#476582'
8670 },
8671 type
8672 ],
8673 [
8674 'div',
8675 {
8676 style: 'padding-left:1.25em'
8677 },
8678 ...Object.keys(target).map(key => {
8679 return [
8680 'div',
8681 {},
8682 ['span', keywordStyle, key + ': '],
8683 formatValue(target[key], false)
8684 ];
8685 })
8686 ]
8687 ];
8688 }
8689 function formatValue(v, asRaw = true) {
8690 if (typeof v === 'number') {
8691 return ['span', numberStyle, v];
8692 }
8693 else if (typeof v === 'string') {
8694 return ['span', stringStyle, JSON.stringify(v)];
8695 }
8696 else if (typeof v === 'boolean') {
8697 return ['span', keywordStyle, v];
8698 }
8699 else if (isObject(v)) {
8700 return ['object', { object: asRaw ? toRaw(v) : v }];
8701 }
8702 else {
8703 return ['span', stringStyle, String(v)];
8704 }
8705 }
8706 function extractKeys(instance, type) {
8707 const Comp = instance.type;
8708 if (isFunction(Comp)) {
8709 return;
8710 }
8711 const extracted = {};
8712 for (const key in instance.ctx) {
8713 if (isKeyOfType(Comp, key, type)) {
8714 extracted[key] = instance.ctx[key];
8715 }
8716 }
8717 return extracted;
8718 }
8719 function isKeyOfType(Comp, key, type) {
8720 const opts = Comp[type];
8721 if ((isArray(opts) && opts.includes(key)) ||
8722 (isObject(opts) && key in opts)) {
8723 return true;
8724 }
8725 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
8726 return true;
8727 }
8728 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
8729 return true;
8730 }
8731 }
8732 function genRefFlag(v) {
8733 if (v._shallow) {
8734 return `ShallowRef`;
8735 }
8736 if (v.effect) {
8737 return `ComputedRef`;
8738 }
8739 return `Ref`;
8740 }
8741 if (window.devtoolsFormatters) {
8742 window.devtoolsFormatters.push(formatter);
8743 }
8744 else {
8745 window.devtoolsFormatters = [formatter];
8746 }
8747}
8748
8749// Core API ------------------------------------------------------------------
8750const version = "3.1.1";
8751/**
8752 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
8753 * @internal
8754 */
8755const ssrUtils = (null);
8756/**
8757 * @internal only exposed in compat builds
8758 */
8759const resolveFilter = null;
8760/**
8761 * @internal only exposed in compat builds.
8762 */
8763const compatUtils = (null);
8764
8765const svgNS = 'http://www.w3.org/2000/svg';
8766const doc = (typeof document !== 'undefined' ? document : null);
8767let tempContainer;
8768let tempSVGContainer;
8769const nodeOps = {
8770 insert: (child, parent, anchor) => {
8771 parent.insertBefore(child, anchor || null);
8772 },
8773 remove: child => {
8774 const parent = child.parentNode;
8775 if (parent) {
8776 parent.removeChild(child);
8777 }
8778 },
8779 createElement: (tag, isSVG, is, props) => {
8780 const el = isSVG
8781 ? doc.createElementNS(svgNS, tag)
8782 : doc.createElement(tag, is ? { is } : undefined);
8783 if (tag === 'select' && props && props.multiple != null) {
8784 el.setAttribute('multiple', props.multiple);
8785 }
8786 return el;
8787 },
8788 createText: text => doc.createTextNode(text),
8789 createComment: text => doc.createComment(text),
8790 setText: (node, text) => {
8791 node.nodeValue = text;
8792 },
8793 setElementText: (el, text) => {
8794 el.textContent = text;
8795 },
8796 parentNode: node => node.parentNode,
8797 nextSibling: node => node.nextSibling,
8798 querySelector: selector => doc.querySelector(selector),
8799 setScopeId(el, id) {
8800 el.setAttribute(id, '');
8801 },
8802 cloneNode(el) {
8803 const cloned = el.cloneNode(true);
8804 // #3072
8805 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
8806 // - normally, elements using `:value` bindings will not be hoisted, but if
8807 // the bound value is a constant, e.g. `:value="true"` - they do get
8808 // hoisted.
8809 // - in production, hoisted nodes are cloned when subsequent inserts, but
8810 // cloneNode() does not copy the custom property we attached.
8811 // - This may need to account for other custom DOM properties we attach to
8812 // elements in addition to `_value` in the future.
8813 if (`_value` in el) {
8814 cloned._value = el._value;
8815 }
8816 return cloned;
8817 },
8818 // __UNSAFE__
8819 // Reason: innerHTML.
8820 // Static content here can only come from compiled templates.
8821 // As long as the user only uses trusted templates, this is safe.
8822 insertStaticContent(content, parent, anchor, isSVG) {
8823 const temp = isSVG
8824 ? tempSVGContainer ||
8825 (tempSVGContainer = doc.createElementNS(svgNS, 'svg'))
8826 : tempContainer || (tempContainer = doc.createElement('div'));
8827 temp.innerHTML = content;
8828 const first = temp.firstChild;
8829 let node = first;
8830 let last = node;
8831 while (node) {
8832 last = node;
8833 nodeOps.insert(node, parent, anchor);
8834 node = temp.firstChild;
8835 }
8836 return [first, last];
8837 }
8838};
8839
8840// compiler should normalize class + :class bindings on the same element
8841// into a single binding ['staticClass', dynamic]
8842function patchClass(el, value, isSVG) {
8843 if (value == null) {
8844 value = '';
8845 }
8846 if (isSVG) {
8847 el.setAttribute('class', value);
8848 }
8849 else {
8850 // directly setting className should be faster than setAttribute in theory
8851 // if this is an element during a transition, take the temporary transition
8852 // classes into account.
8853 const transitionClasses = el._vtc;
8854 if (transitionClasses) {
8855 value = (value
8856 ? [value, ...transitionClasses]
8857 : [...transitionClasses]).join(' ');
8858 }
8859 el.className = value;
8860 }
8861}
8862
8863function patchStyle(el, prev, next) {
8864 const style = el.style;
8865 if (!next) {
8866 el.removeAttribute('style');
8867 }
8868 else if (isString(next)) {
8869 if (prev !== next) {
8870 const current = style.display;
8871 style.cssText = next;
8872 // indicates that the `display` of the element is controlled by `v-show`,
8873 // so we always keep the current `display` value regardless of the `style` value,
8874 // thus handing over control to `v-show`.
8875 if ('_vod' in el) {
8876 style.display = current;
8877 }
8878 }
8879 }
8880 else {
8881 for (const key in next) {
8882 setStyle(style, key, next[key]);
8883 }
8884 if (prev && !isString(prev)) {
8885 for (const key in prev) {
8886 if (next[key] == null) {
8887 setStyle(style, key, '');
8888 }
8889 }
8890 }
8891 }
8892}
8893const importantRE = /\s*!important$/;
8894function setStyle(style, name, val) {
8895 if (isArray(val)) {
8896 val.forEach(v => setStyle(style, name, v));
8897 }
8898 else {
8899 if (name.startsWith('--')) {
8900 // custom property definition
8901 style.setProperty(name, val);
8902 }
8903 else {
8904 const prefixed = autoPrefix(style, name);
8905 if (importantRE.test(val)) {
8906 // !important
8907 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
8908 }
8909 else {
8910 style[prefixed] = val;
8911 }
8912 }
8913 }
8914}
8915const prefixes = ['Webkit', 'Moz', 'ms'];
8916const prefixCache = {};
8917function autoPrefix(style, rawName) {
8918 const cached = prefixCache[rawName];
8919 if (cached) {
8920 return cached;
8921 }
8922 let name = camelize(rawName);
8923 if (name !== 'filter' && name in style) {
8924 return (prefixCache[rawName] = name);
8925 }
8926 name = capitalize(name);
8927 for (let i = 0; i < prefixes.length; i++) {
8928 const prefixed = prefixes[i] + name;
8929 if (prefixed in style) {
8930 return (prefixCache[rawName] = prefixed);
8931 }
8932 }
8933 return rawName;
8934}
8935
8936const xlinkNS = 'http://www.w3.org/1999/xlink';
8937function patchAttr(el, key, value, isSVG, instance) {
8938 if (isSVG && key.startsWith('xlink:')) {
8939 if (value == null) {
8940 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
8941 }
8942 else {
8943 el.setAttributeNS(xlinkNS, key, value);
8944 }
8945 }
8946 else {
8947 // note we are only checking boolean attributes that don't have a
8948 // corresponding dom prop of the same name here.
8949 const isBoolean = isSpecialBooleanAttr(key);
8950 if (value == null || (isBoolean && value === false)) {
8951 el.removeAttribute(key);
8952 }
8953 else {
8954 el.setAttribute(key, isBoolean ? '' : value);
8955 }
8956 }
8957}
8958
8959// __UNSAFE__
8960// functions. The user is responsible for using them with only trusted content.
8961function patchDOMProp(el, key, value,
8962// the following args are passed only due to potential innerHTML/textContent
8963// overriding existing VNodes, in which case the old tree must be properly
8964// unmounted.
8965prevChildren, parentComponent, parentSuspense, unmountChildren) {
8966 if (key === 'innerHTML' || key === 'textContent') {
8967 if (prevChildren) {
8968 unmountChildren(prevChildren, parentComponent, parentSuspense);
8969 }
8970 el[key] = value == null ? '' : value;
8971 return;
8972 }
8973 if (key === 'value' && el.tagName !== 'PROGRESS') {
8974 // store value as _value as well since
8975 // non-string values will be stringified.
8976 el._value = value;
8977 const newValue = value == null ? '' : value;
8978 if (el.value !== newValue) {
8979 el.value = newValue;
8980 }
8981 if (value == null) {
8982 el.removeAttribute(key);
8983 }
8984 return;
8985 }
8986 if (value === '' || value == null) {
8987 const type = typeof el[key];
8988 if (value === '' && type === 'boolean') {
8989 // e.g. <select multiple> compiles to { multiple: '' }
8990 el[key] = true;
8991 return;
8992 }
8993 else if (value == null && type === 'string') {
8994 // e.g. <div :id="null">
8995 el[key] = '';
8996 el.removeAttribute(key);
8997 return;
8998 }
8999 else if (type === 'number') {
9000 // e.g. <img :width="null">
9001 el[key] = 0;
9002 el.removeAttribute(key);
9003 return;
9004 }
9005 }
9006 // some properties perform value validation and throw
9007 try {
9008 el[key] = value;
9009 }
9010 catch (e) {
9011 {
9012 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9013 `value ${value} is invalid.`, e);
9014 }
9015 }
9016}
9017
9018// Async edge case fix requires storing an event listener's attach timestamp.
9019let _getNow = Date.now;
9020let skipTimestampCheck = false;
9021if (typeof window !== 'undefined') {
9022 // Determine what event timestamp the browser is using. Annoyingly, the
9023 // timestamp can either be hi-res (relative to page load) or low-res
9024 // (relative to UNIX epoch), so in order to compare time we have to use the
9025 // same timestamp type when saving the flush timestamp.
9026 if (_getNow() > document.createEvent('Event').timeStamp) {
9027 // if the low-res timestamp which is bigger than the event timestamp
9028 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
9029 // and we need to use the hi-res version for event listeners as well.
9030 _getNow = () => performance.now();
9031 }
9032 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
9033 // and does not fire microtasks in between event propagation, so safe to exclude.
9034 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
9035 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
9036}
9037// To avoid the overhead of repeatedly calling performance.now(), we cache
9038// and use the same timestamp for all event listeners attached in the same tick.
9039let cachedNow = 0;
9040const p = Promise.resolve();
9041const reset = () => {
9042 cachedNow = 0;
9043};
9044const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
9045function addEventListener(el, event, handler, options) {
9046 el.addEventListener(event, handler, options);
9047}
9048function removeEventListener(el, event, handler, options) {
9049 el.removeEventListener(event, handler, options);
9050}
9051function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9052 // vei = vue event invokers
9053 const invokers = el._vei || (el._vei = {});
9054 const existingInvoker = invokers[rawName];
9055 if (nextValue && existingInvoker) {
9056 // patch
9057 existingInvoker.value = nextValue;
9058 }
9059 else {
9060 const [name, options] = parseName(rawName);
9061 if (nextValue) {
9062 // add
9063 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9064 addEventListener(el, name, invoker, options);
9065 }
9066 else if (existingInvoker) {
9067 // remove
9068 removeEventListener(el, name, existingInvoker, options);
9069 invokers[rawName] = undefined;
9070 }
9071 }
9072}
9073const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9074function parseName(name) {
9075 let options;
9076 if (optionsModifierRE.test(name)) {
9077 options = {};
9078 let m;
9079 while ((m = name.match(optionsModifierRE))) {
9080 name = name.slice(0, name.length - m[0].length);
9081 options[m[0].toLowerCase()] = true;
9082 }
9083 }
9084 return [hyphenate(name.slice(2)), options];
9085}
9086function createInvoker(initialValue, instance) {
9087 const invoker = (e) => {
9088 // async edge case #6566: inner click event triggers patch, event handler
9089 // attached to outer element during patch, and triggered again. This
9090 // happens because browsers fire microtask ticks between event propagation.
9091 // the solution is simple: we save the timestamp when a handler is attached,
9092 // and the handler would only fire if the event passed to it was fired
9093 // AFTER it was attached.
9094 const timeStamp = e.timeStamp || _getNow();
9095 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
9096 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
9097 }
9098 };
9099 invoker.value = initialValue;
9100 invoker.attached = getNow();
9101 return invoker;
9102}
9103function patchStopImmediatePropagation(e, value) {
9104 if (isArray(value)) {
9105 const originalStop = e.stopImmediatePropagation;
9106 e.stopImmediatePropagation = () => {
9107 originalStop.call(e);
9108 e._stopped = true;
9109 };
9110 return value.map(fn => (e) => !e._stopped && fn(e));
9111 }
9112 else {
9113 return value;
9114 }
9115}
9116
9117const nativeOnRE = /^on[a-z]/;
9118const forcePatchProp = (_, key) => key === 'value';
9119const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9120 switch (key) {
9121 // special
9122 case 'class':
9123 patchClass(el, nextValue, isSVG);
9124 break;
9125 case 'style':
9126 patchStyle(el, prevValue, nextValue);
9127 break;
9128 default:
9129 if (isOn(key)) {
9130 // ignore v-model listeners
9131 if (!isModelListener(key)) {
9132 patchEvent(el, key, prevValue, nextValue, parentComponent);
9133 }
9134 }
9135 else if (shouldSetAsProp(el, key, nextValue, isSVG)) {
9136 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9137 }
9138 else {
9139 // special case for <input v-model type="checkbox"> with
9140 // :true-value & :false-value
9141 // store value as dom properties since non-string values will be
9142 // stringified.
9143 if (key === 'true-value') {
9144 el._trueValue = nextValue;
9145 }
9146 else if (key === 'false-value') {
9147 el._falseValue = nextValue;
9148 }
9149 patchAttr(el, key, nextValue, isSVG);
9150 }
9151 break;
9152 }
9153};
9154function shouldSetAsProp(el, key, value, isSVG) {
9155 if (isSVG) {
9156 // most keys must be set as attribute on svg elements to work
9157 // ...except innerHTML
9158 if (key === 'innerHTML') {
9159 return true;
9160 }
9161 // or native onclick with function values
9162 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9163 return true;
9164 }
9165 return false;
9166 }
9167 // spellcheck and draggable are numerated attrs, however their
9168 // corresponding DOM properties are actually booleans - this leads to
9169 // setting it with a string "false" value leading it to be coerced to
9170 // `true`, so we need to always treat them as attributes.
9171 // Note that `contentEditable` doesn't have this problem: its DOM
9172 // property is also enumerated string values.
9173 if (key === 'spellcheck' || key === 'draggable') {
9174 return false;
9175 }
9176 // #1787, #2840 form property on form elements is readonly and must be set as
9177 // attribute.
9178 if (key === 'form') {
9179 return false;
9180 }
9181 // #1526 <input list> must be set as attribute
9182 if (key === 'list' && el.tagName === 'INPUT') {
9183 return false;
9184 }
9185 // #2766 <textarea type> must be set as attribute
9186 if (key === 'type' && el.tagName === 'TEXTAREA') {
9187 return false;
9188 }
9189 // native onclick with string value, must be set as attribute
9190 if (nativeOnRE.test(key) && isString(value)) {
9191 return false;
9192 }
9193 return key in el;
9194}
9195
9196function useCssModule(name = '$style') {
9197 /* istanbul ignore else */
9198 {
9199 const instance = getCurrentInstance();
9200 if (!instance) {
9201 warn(`useCssModule must be called inside setup()`);
9202 return EMPTY_OBJ;
9203 }
9204 const modules = instance.type.__cssModules;
9205 if (!modules) {
9206 warn(`Current instance does not have CSS modules injected.`);
9207 return EMPTY_OBJ;
9208 }
9209 const mod = modules[name];
9210 if (!mod) {
9211 warn(`Current instance does not have CSS module named "${name}".`);
9212 return EMPTY_OBJ;
9213 }
9214 return mod;
9215 }
9216}
9217
9218/**
9219 * Runtime helper for SFC's CSS variable injection feature.
9220 * @private
9221 */
9222function useCssVars(getter) {
9223 const instance = getCurrentInstance();
9224 /* istanbul ignore next */
9225 if (!instance) {
9226 warn(`useCssVars is called without current active component instance.`);
9227 return;
9228 }
9229 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
9230 onMounted(() => watchEffect(setVars, { flush: 'post' }));
9231 onUpdated(setVars);
9232}
9233function setVarsOnVNode(vnode, vars) {
9234 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
9235 const suspense = vnode.suspense;
9236 vnode = suspense.activeBranch;
9237 if (suspense.pendingBranch && !suspense.isHydrating) {
9238 suspense.effects.push(() => {
9239 setVarsOnVNode(suspense.activeBranch, vars);
9240 });
9241 }
9242 }
9243 // drill down HOCs until it's a non-component vnode
9244 while (vnode.component) {
9245 vnode = vnode.component.subTree;
9246 }
9247 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
9248 const style = vnode.el.style;
9249 for (const key in vars) {
9250 style.setProperty(`--${key}`, vars[key]);
9251 }
9252 }
9253 else if (vnode.type === Fragment) {
9254 vnode.children.forEach(c => setVarsOnVNode(c, vars));
9255 }
9256}
9257
9258const TRANSITION = 'transition';
9259const ANIMATION = 'animation';
9260// DOM Transition is a higher-order-component based on the platform-agnostic
9261// base Transition component, with DOM-specific logic.
9262const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
9263Transition.displayName = 'Transition';
9264const DOMTransitionPropsValidators = {
9265 name: String,
9266 type: String,
9267 css: {
9268 type: Boolean,
9269 default: true
9270 },
9271 duration: [String, Number, Object],
9272 enterFromClass: String,
9273 enterActiveClass: String,
9274 enterToClass: String,
9275 appearFromClass: String,
9276 appearActiveClass: String,
9277 appearToClass: String,
9278 leaveFromClass: String,
9279 leaveActiveClass: String,
9280 leaveToClass: String
9281};
9282const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
9283/**
9284 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
9285 * with custom HOCs.
9286 */
9287const callHook$1 = (hook, args = []) => {
9288 if (isArray(hook)) {
9289 hook.forEach(h => h(...args));
9290 }
9291 else if (hook) {
9292 hook(...args);
9293 }
9294};
9295/**
9296 * Check if a hook expects a callback (2nd arg), which means the user
9297 * intends to explicitly control the end of the transition.
9298 */
9299const hasExplicitCallback = (hook) => {
9300 return hook
9301 ? isArray(hook)
9302 ? hook.some(h => h.length > 1)
9303 : hook.length > 1
9304 : false;
9305};
9306function resolveTransitionProps(rawProps) {
9307 const baseProps = {};
9308 for (const key in rawProps) {
9309 if (!(key in DOMTransitionPropsValidators)) {
9310 baseProps[key] = rawProps[key];
9311 }
9312 }
9313 if (rawProps.css === false) {
9314 return baseProps;
9315 }
9316 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;
9317 const durations = normalizeDuration(duration);
9318 const enterDuration = durations && durations[0];
9319 const leaveDuration = durations && durations[1];
9320 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
9321 const finishEnter = (el, isAppear, done) => {
9322 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
9323 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
9324 done && done();
9325 };
9326 const finishLeave = (el, done) => {
9327 removeTransitionClass(el, leaveToClass);
9328 removeTransitionClass(el, leaveActiveClass);
9329 done && done();
9330 };
9331 const makeEnterHook = (isAppear) => {
9332 return (el, done) => {
9333 const hook = isAppear ? onAppear : onEnter;
9334 const resolve = () => finishEnter(el, isAppear, done);
9335 callHook$1(hook, [el, resolve]);
9336 nextFrame(() => {
9337 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
9338 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
9339 if (!hasExplicitCallback(hook)) {
9340 whenTransitionEnds(el, type, enterDuration, resolve);
9341 }
9342 });
9343 };
9344 };
9345 return extend(baseProps, {
9346 onBeforeEnter(el) {
9347 callHook$1(onBeforeEnter, [el]);
9348 addTransitionClass(el, enterFromClass);
9349 addTransitionClass(el, enterActiveClass);
9350 },
9351 onBeforeAppear(el) {
9352 callHook$1(onBeforeAppear, [el]);
9353 addTransitionClass(el, appearFromClass);
9354 addTransitionClass(el, appearActiveClass);
9355 },
9356 onEnter: makeEnterHook(false),
9357 onAppear: makeEnterHook(true),
9358 onLeave(el, done) {
9359 const resolve = () => finishLeave(el, done);
9360 addTransitionClass(el, leaveFromClass);
9361 // force reflow so *-leave-from classes immediately take effect (#2593)
9362 forceReflow();
9363 addTransitionClass(el, leaveActiveClass);
9364 nextFrame(() => {
9365 removeTransitionClass(el, leaveFromClass);
9366 addTransitionClass(el, leaveToClass);
9367 if (!hasExplicitCallback(onLeave)) {
9368 whenTransitionEnds(el, type, leaveDuration, resolve);
9369 }
9370 });
9371 callHook$1(onLeave, [el, resolve]);
9372 },
9373 onEnterCancelled(el) {
9374 finishEnter(el, false);
9375 callHook$1(onEnterCancelled, [el]);
9376 },
9377 onAppearCancelled(el) {
9378 finishEnter(el, true);
9379 callHook$1(onAppearCancelled, [el]);
9380 },
9381 onLeaveCancelled(el) {
9382 finishLeave(el);
9383 callHook$1(onLeaveCancelled, [el]);
9384 }
9385 });
9386}
9387function normalizeDuration(duration) {
9388 if (duration == null) {
9389 return null;
9390 }
9391 else if (isObject(duration)) {
9392 return [NumberOf(duration.enter), NumberOf(duration.leave)];
9393 }
9394 else {
9395 const n = NumberOf(duration);
9396 return [n, n];
9397 }
9398}
9399function NumberOf(val) {
9400 const res = toNumber(val);
9401 validateDuration(res);
9402 return res;
9403}
9404function validateDuration(val) {
9405 if (typeof val !== 'number') {
9406 warn(`<transition> explicit duration is not a valid number - ` +
9407 `got ${JSON.stringify(val)}.`);
9408 }
9409 else if (isNaN(val)) {
9410 warn(`<transition> explicit duration is NaN - ` +
9411 'the duration expression might be incorrect.');
9412 }
9413}
9414function addTransitionClass(el, cls) {
9415 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
9416 (el._vtc ||
9417 (el._vtc = new Set())).add(cls);
9418}
9419function removeTransitionClass(el, cls) {
9420 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
9421 const { _vtc } = el;
9422 if (_vtc) {
9423 _vtc.delete(cls);
9424 if (!_vtc.size) {
9425 el._vtc = undefined;
9426 }
9427 }
9428}
9429function nextFrame(cb) {
9430 requestAnimationFrame(() => {
9431 requestAnimationFrame(cb);
9432 });
9433}
9434let endId = 0;
9435function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
9436 const id = (el._endId = ++endId);
9437 const resolveIfNotStale = () => {
9438 if (id === el._endId) {
9439 resolve();
9440 }
9441 };
9442 if (explicitTimeout) {
9443 return setTimeout(resolveIfNotStale, explicitTimeout);
9444 }
9445 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
9446 if (!type) {
9447 return resolve();
9448 }
9449 const endEvent = type + 'end';
9450 let ended = 0;
9451 const end = () => {
9452 el.removeEventListener(endEvent, onEnd);
9453 resolveIfNotStale();
9454 };
9455 const onEnd = (e) => {
9456 if (e.target === el && ++ended >= propCount) {
9457 end();
9458 }
9459 };
9460 setTimeout(() => {
9461 if (ended < propCount) {
9462 end();
9463 }
9464 }, timeout + 1);
9465 el.addEventListener(endEvent, onEnd);
9466}
9467function getTransitionInfo(el, expectedType) {
9468 const styles = window.getComputedStyle(el);
9469 // JSDOM may return undefined for transition properties
9470 const getStyleProperties = (key) => (styles[key] || '').split(', ');
9471 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
9472 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
9473 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
9474 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
9475 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
9476 const animationTimeout = getTimeout(animationDelays, animationDurations);
9477 let type = null;
9478 let timeout = 0;
9479 let propCount = 0;
9480 /* istanbul ignore if */
9481 if (expectedType === TRANSITION) {
9482 if (transitionTimeout > 0) {
9483 type = TRANSITION;
9484 timeout = transitionTimeout;
9485 propCount = transitionDurations.length;
9486 }
9487 }
9488 else if (expectedType === ANIMATION) {
9489 if (animationTimeout > 0) {
9490 type = ANIMATION;
9491 timeout = animationTimeout;
9492 propCount = animationDurations.length;
9493 }
9494 }
9495 else {
9496 timeout = Math.max(transitionTimeout, animationTimeout);
9497 type =
9498 timeout > 0
9499 ? transitionTimeout > animationTimeout
9500 ? TRANSITION
9501 : ANIMATION
9502 : null;
9503 propCount = type
9504 ? type === TRANSITION
9505 ? transitionDurations.length
9506 : animationDurations.length
9507 : 0;
9508 }
9509 const hasTransform = type === TRANSITION &&
9510 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
9511 return {
9512 type,
9513 timeout,
9514 propCount,
9515 hasTransform
9516 };
9517}
9518function getTimeout(delays, durations) {
9519 while (delays.length < durations.length) {
9520 delays = delays.concat(delays);
9521 }
9522 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
9523}
9524// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
9525// numbers in a locale-dependent way, using a comma instead of a dot.
9526// If comma is not replaced with a dot, the input will be rounded down
9527// (i.e. acting as a floor function) causing unexpected behaviors
9528function toMs(s) {
9529 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
9530}
9531// synchronously force layout to put elements into a certain state
9532function forceReflow() {
9533 return document.body.offsetHeight;
9534}
9535
9536const positionMap = new WeakMap();
9537const newPositionMap = new WeakMap();
9538const TransitionGroupImpl = {
9539 name: 'TransitionGroup',
9540 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
9541 tag: String,
9542 moveClass: String
9543 }),
9544 setup(props, { slots }) {
9545 const instance = getCurrentInstance();
9546 const state = useTransitionState();
9547 let prevChildren;
9548 let children;
9549 onUpdated(() => {
9550 // children is guaranteed to exist after initial render
9551 if (!prevChildren.length) {
9552 return;
9553 }
9554 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
9555 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
9556 return;
9557 }
9558 // we divide the work into three loops to avoid mixing DOM reads and writes
9559 // in each iteration - which helps prevent layout thrashing.
9560 prevChildren.forEach(callPendingCbs);
9561 prevChildren.forEach(recordPosition);
9562 const movedChildren = prevChildren.filter(applyTranslation);
9563 // force reflow to put everything in position
9564 forceReflow();
9565 movedChildren.forEach(c => {
9566 const el = c.el;
9567 const style = el.style;
9568 addTransitionClass(el, moveClass);
9569 style.transform = style.webkitTransform = style.transitionDuration = '';
9570 const cb = (el._moveCb = (e) => {
9571 if (e && e.target !== el) {
9572 return;
9573 }
9574 if (!e || /transform$/.test(e.propertyName)) {
9575 el.removeEventListener('transitionend', cb);
9576 el._moveCb = null;
9577 removeTransitionClass(el, moveClass);
9578 }
9579 });
9580 el.addEventListener('transitionend', cb);
9581 });
9582 });
9583 return () => {
9584 const rawProps = toRaw(props);
9585 const cssTransitionProps = resolveTransitionProps(rawProps);
9586 let tag = rawProps.tag || Fragment;
9587 prevChildren = children;
9588 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
9589 for (let i = 0; i < children.length; i++) {
9590 const child = children[i];
9591 if (child.key != null) {
9592 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
9593 }
9594 else {
9595 warn(`<TransitionGroup> children must be keyed.`);
9596 }
9597 }
9598 if (prevChildren) {
9599 for (let i = 0; i < prevChildren.length; i++) {
9600 const child = prevChildren[i];
9601 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
9602 positionMap.set(child, child.el.getBoundingClientRect());
9603 }
9604 }
9605 return createVNode(tag, null, children);
9606 };
9607 }
9608};
9609const TransitionGroup = TransitionGroupImpl;
9610function callPendingCbs(c) {
9611 const el = c.el;
9612 if (el._moveCb) {
9613 el._moveCb();
9614 }
9615 if (el._enterCb) {
9616 el._enterCb();
9617 }
9618}
9619function recordPosition(c) {
9620 newPositionMap.set(c, c.el.getBoundingClientRect());
9621}
9622function applyTranslation(c) {
9623 const oldPos = positionMap.get(c);
9624 const newPos = newPositionMap.get(c);
9625 const dx = oldPos.left - newPos.left;
9626 const dy = oldPos.top - newPos.top;
9627 if (dx || dy) {
9628 const s = c.el.style;
9629 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
9630 s.transitionDuration = '0s';
9631 return c;
9632 }
9633}
9634function hasCSSTransform(el, root, moveClass) {
9635 // Detect whether an element with the move class applied has
9636 // CSS transitions. Since the element may be inside an entering
9637 // transition at this very moment, we make a clone of it and remove
9638 // all other transition classes applied to ensure only the move class
9639 // is applied.
9640 const clone = el.cloneNode();
9641 if (el._vtc) {
9642 el._vtc.forEach(cls => {
9643 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
9644 });
9645 }
9646 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
9647 clone.style.display = 'none';
9648 const container = (root.nodeType === 1
9649 ? root
9650 : root.parentNode);
9651 container.appendChild(clone);
9652 const { hasTransform } = getTransitionInfo(clone);
9653 container.removeChild(clone);
9654 return hasTransform;
9655}
9656
9657const getModelAssigner = (vnode) => {
9658 const fn = vnode.props['onUpdate:modelValue'];
9659 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
9660};
9661function onCompositionStart(e) {
9662 e.target.composing = true;
9663}
9664function onCompositionEnd(e) {
9665 const target = e.target;
9666 if (target.composing) {
9667 target.composing = false;
9668 trigger$1(target, 'input');
9669 }
9670}
9671function trigger$1(el, type) {
9672 const e = document.createEvent('HTMLEvents');
9673 e.initEvent(type, true, true);
9674 el.dispatchEvent(e);
9675}
9676// We are exporting the v-model runtime directly as vnode hooks so that it can
9677// be tree-shaken in case v-model is never used.
9678const vModelText = {
9679 created(el, { modifiers: { lazy, trim, number } }, vnode) {
9680 el._assign = getModelAssigner(vnode);
9681 const castToNumber = number || el.type === 'number';
9682 addEventListener(el, lazy ? 'change' : 'input', e => {
9683 if (e.target.composing)
9684 return;
9685 let domValue = el.value;
9686 if (trim) {
9687 domValue = domValue.trim();
9688 }
9689 else if (castToNumber) {
9690 domValue = toNumber(domValue);
9691 }
9692 el._assign(domValue);
9693 });
9694 if (trim) {
9695 addEventListener(el, 'change', () => {
9696 el.value = el.value.trim();
9697 });
9698 }
9699 if (!lazy) {
9700 addEventListener(el, 'compositionstart', onCompositionStart);
9701 addEventListener(el, 'compositionend', onCompositionEnd);
9702 // Safari < 10.2 & UIWebView doesn't fire compositionend when
9703 // switching focus before confirming composition choice
9704 // this also fixes the issue where some browsers e.g. iOS Chrome
9705 // fires "change" instead of "input" on autocomplete.
9706 addEventListener(el, 'change', onCompositionEnd);
9707 }
9708 },
9709 // set value on mounted so it's after min/max for type="range"
9710 mounted(el, { value }) {
9711 el.value = value == null ? '' : value;
9712 },
9713 beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
9714 el._assign = getModelAssigner(vnode);
9715 // avoid clearing unresolved text. #2302
9716 if (el.composing)
9717 return;
9718 if (document.activeElement === el) {
9719 if (trim && el.value.trim() === value) {
9720 return;
9721 }
9722 if ((number || el.type === 'number') && toNumber(el.value) === value) {
9723 return;
9724 }
9725 }
9726 const newValue = value == null ? '' : value;
9727 if (el.value !== newValue) {
9728 el.value = newValue;
9729 }
9730 }
9731};
9732const vModelCheckbox = {
9733 created(el, _, vnode) {
9734 el._assign = getModelAssigner(vnode);
9735 addEventListener(el, 'change', () => {
9736 const modelValue = el._modelValue;
9737 const elementValue = getValue(el);
9738 const checked = el.checked;
9739 const assign = el._assign;
9740 if (isArray(modelValue)) {
9741 const index = looseIndexOf(modelValue, elementValue);
9742 const found = index !== -1;
9743 if (checked && !found) {
9744 assign(modelValue.concat(elementValue));
9745 }
9746 else if (!checked && found) {
9747 const filtered = [...modelValue];
9748 filtered.splice(index, 1);
9749 assign(filtered);
9750 }
9751 }
9752 else if (isSet(modelValue)) {
9753 const cloned = new Set(modelValue);
9754 if (checked) {
9755 cloned.add(elementValue);
9756 }
9757 else {
9758 cloned.delete(elementValue);
9759 }
9760 assign(cloned);
9761 }
9762 else {
9763 assign(getCheckboxValue(el, checked));
9764 }
9765 });
9766 },
9767 // set initial checked on mount to wait for true-value/false-value
9768 mounted: setChecked,
9769 beforeUpdate(el, binding, vnode) {
9770 el._assign = getModelAssigner(vnode);
9771 setChecked(el, binding, vnode);
9772 }
9773};
9774function setChecked(el, { value, oldValue }, vnode) {
9775 el._modelValue = value;
9776 if (isArray(value)) {
9777 el.checked = looseIndexOf(value, vnode.props.value) > -1;
9778 }
9779 else if (isSet(value)) {
9780 el.checked = value.has(vnode.props.value);
9781 }
9782 else if (value !== oldValue) {
9783 el.checked = looseEqual(value, getCheckboxValue(el, true));
9784 }
9785}
9786const vModelRadio = {
9787 created(el, { value }, vnode) {
9788 el.checked = looseEqual(value, vnode.props.value);
9789 el._assign = getModelAssigner(vnode);
9790 addEventListener(el, 'change', () => {
9791 el._assign(getValue(el));
9792 });
9793 },
9794 beforeUpdate(el, { value, oldValue }, vnode) {
9795 el._assign = getModelAssigner(vnode);
9796 if (value !== oldValue) {
9797 el.checked = looseEqual(value, vnode.props.value);
9798 }
9799 }
9800};
9801const vModelSelect = {
9802 created(el, { value, modifiers: { number } }, vnode) {
9803 const isSetModel = isSet(value);
9804 addEventListener(el, 'change', () => {
9805 const selectedVal = Array.prototype.filter
9806 .call(el.options, (o) => o.selected)
9807 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
9808 el._assign(el.multiple
9809 ? isSetModel
9810 ? new Set(selectedVal)
9811 : selectedVal
9812 : selectedVal[0]);
9813 });
9814 el._assign = getModelAssigner(vnode);
9815 },
9816 // set value in mounted & updated because <select> relies on its children
9817 // <option>s.
9818 mounted(el, { value }) {
9819 setSelected(el, value);
9820 },
9821 beforeUpdate(el, _binding, vnode) {
9822 el._assign = getModelAssigner(vnode);
9823 },
9824 updated(el, { value }) {
9825 setSelected(el, value);
9826 }
9827};
9828function setSelected(el, value) {
9829 const isMultiple = el.multiple;
9830 if (isMultiple && !isArray(value) && !isSet(value)) {
9831 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
9832 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
9833 return;
9834 }
9835 for (let i = 0, l = el.options.length; i < l; i++) {
9836 const option = el.options[i];
9837 const optionValue = getValue(option);
9838 if (isMultiple) {
9839 if (isArray(value)) {
9840 option.selected = looseIndexOf(value, optionValue) > -1;
9841 }
9842 else {
9843 option.selected = value.has(optionValue);
9844 }
9845 }
9846 else {
9847 if (looseEqual(getValue(option), value)) {
9848 if (el.selectedIndex !== i)
9849 el.selectedIndex = i;
9850 return;
9851 }
9852 }
9853 }
9854 if (!isMultiple && el.selectedIndex !== -1) {
9855 el.selectedIndex = -1;
9856 }
9857}
9858// retrieve raw value set via :value bindings
9859function getValue(el) {
9860 return '_value' in el ? el._value : el.value;
9861}
9862// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
9863function getCheckboxValue(el, checked) {
9864 const key = checked ? '_trueValue' : '_falseValue';
9865 return key in el ? el[key] : checked;
9866}
9867const vModelDynamic = {
9868 created(el, binding, vnode) {
9869 callModelHook(el, binding, vnode, null, 'created');
9870 },
9871 mounted(el, binding, vnode) {
9872 callModelHook(el, binding, vnode, null, 'mounted');
9873 },
9874 beforeUpdate(el, binding, vnode, prevVNode) {
9875 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
9876 },
9877 updated(el, binding, vnode, prevVNode) {
9878 callModelHook(el, binding, vnode, prevVNode, 'updated');
9879 }
9880};
9881function callModelHook(el, binding, vnode, prevVNode, hook) {
9882 let modelToUse;
9883 switch (el.tagName) {
9884 case 'SELECT':
9885 modelToUse = vModelSelect;
9886 break;
9887 case 'TEXTAREA':
9888 modelToUse = vModelText;
9889 break;
9890 default:
9891 switch (vnode.props && vnode.props.type) {
9892 case 'checkbox':
9893 modelToUse = vModelCheckbox;
9894 break;
9895 case 'radio':
9896 modelToUse = vModelRadio;
9897 break;
9898 default:
9899 modelToUse = vModelText;
9900 }
9901 }
9902 const fn = modelToUse[hook];
9903 fn && fn(el, binding, vnode, prevVNode);
9904}
9905
9906const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
9907const modifierGuards = {
9908 stop: e => e.stopPropagation(),
9909 prevent: e => e.preventDefault(),
9910 self: e => e.target !== e.currentTarget,
9911 ctrl: e => !e.ctrlKey,
9912 shift: e => !e.shiftKey,
9913 alt: e => !e.altKey,
9914 meta: e => !e.metaKey,
9915 left: e => 'button' in e && e.button !== 0,
9916 middle: e => 'button' in e && e.button !== 1,
9917 right: e => 'button' in e && e.button !== 2,
9918 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
9919};
9920/**
9921 * @private
9922 */
9923const withModifiers = (fn, modifiers) => {
9924 return (event, ...args) => {
9925 for (let i = 0; i < modifiers.length; i++) {
9926 const guard = modifierGuards[modifiers[i]];
9927 if (guard && guard(event, modifiers))
9928 return;
9929 }
9930 return fn(event, ...args);
9931 };
9932};
9933// Kept for 2.x compat.
9934// Note: IE11 compat for `spacebar` and `del` is removed for now.
9935const keyNames = {
9936 esc: 'escape',
9937 space: ' ',
9938 up: 'arrow-up',
9939 left: 'arrow-left',
9940 right: 'arrow-right',
9941 down: 'arrow-down',
9942 delete: 'backspace'
9943};
9944/**
9945 * @private
9946 */
9947const withKeys = (fn, modifiers) => {
9948 return (event) => {
9949 if (!('key' in event)) {
9950 return;
9951 }
9952 const eventKey = hyphenate(event.key);
9953 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
9954 return fn(event);
9955 }
9956 };
9957};
9958
9959const vShow = {
9960 beforeMount(el, { value }, { transition }) {
9961 el._vod = el.style.display === 'none' ? '' : el.style.display;
9962 if (transition && value) {
9963 transition.beforeEnter(el);
9964 }
9965 else {
9966 setDisplay(el, value);
9967 }
9968 },
9969 mounted(el, { value }, { transition }) {
9970 if (transition && value) {
9971 transition.enter(el);
9972 }
9973 },
9974 updated(el, { value, oldValue }, { transition }) {
9975 if (!value === !oldValue)
9976 return;
9977 if (transition) {
9978 if (value) {
9979 transition.beforeEnter(el);
9980 setDisplay(el, true);
9981 transition.enter(el);
9982 }
9983 else {
9984 transition.leave(el, () => {
9985 setDisplay(el, false);
9986 });
9987 }
9988 }
9989 else {
9990 setDisplay(el, value);
9991 }
9992 },
9993 beforeUnmount(el, { value }) {
9994 setDisplay(el, value);
9995 }
9996};
9997function setDisplay(el, value) {
9998 el.style.display = value ? el._vod : 'none';
9999}
10000
10001const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps);
10002// lazy create the renderer - this makes core renderer logic tree-shakable
10003// in case the user only imports reactivity utilities from Vue.
10004let renderer;
10005let enabledHydration = false;
10006function ensureRenderer() {
10007 return renderer || (renderer = createRenderer(rendererOptions));
10008}
10009function ensureHydrationRenderer() {
10010 renderer = enabledHydration
10011 ? renderer
10012 : createHydrationRenderer(rendererOptions);
10013 enabledHydration = true;
10014 return renderer;
10015}
10016// use explicit type casts here to avoid import() calls in rolled-up d.ts
10017const render = ((...args) => {
10018 ensureRenderer().render(...args);
10019});
10020const hydrate = ((...args) => {
10021 ensureHydrationRenderer().hydrate(...args);
10022});
10023const createApp = ((...args) => {
10024 const app = ensureRenderer().createApp(...args);
10025 {
10026 injectNativeTagCheck(app);
10027 injectCompilerOptionsCheck(app);
10028 }
10029 const { mount } = app;
10030 app.mount = (containerOrSelector) => {
10031 const container = normalizeContainer(containerOrSelector);
10032 if (!container)
10033 return;
10034 const component = app._component;
10035 if (!isFunction(component) && !component.render && !component.template) {
10036 // __UNSAFE__
10037 // Reason: potential execution of JS expressions in in-DOM template.
10038 // The user must make sure the in-DOM template is trusted. If it's
10039 // rendered by the server, the template should not contain any user data.
10040 component.template = container.innerHTML;
10041 }
10042 // clear content before mounting
10043 container.innerHTML = '';
10044 const proxy = mount(container, false, container instanceof SVGElement);
10045 if (container instanceof Element) {
10046 container.removeAttribute('v-cloak');
10047 container.setAttribute('data-v-app', '');
10048 }
10049 return proxy;
10050 };
10051 return app;
10052});
10053const createSSRApp = ((...args) => {
10054 const app = ensureHydrationRenderer().createApp(...args);
10055 {
10056 injectNativeTagCheck(app);
10057 injectCompilerOptionsCheck(app);
10058 }
10059 const { mount } = app;
10060 app.mount = (containerOrSelector) => {
10061 const container = normalizeContainer(containerOrSelector);
10062 if (container) {
10063 return mount(container, true, container instanceof SVGElement);
10064 }
10065 };
10066 return app;
10067});
10068function injectNativeTagCheck(app) {
10069 // Inject `isNativeTag`
10070 // this is used for component name validation (dev only)
10071 Object.defineProperty(app.config, 'isNativeTag', {
10072 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
10073 writable: false
10074 });
10075}
10076// dev only
10077function injectCompilerOptionsCheck(app) {
10078 if (isRuntimeOnly()) {
10079 const isCustomElement = app.config.isCustomElement;
10080 Object.defineProperty(app.config, 'isCustomElement', {
10081 get() {
10082 return isCustomElement;
10083 },
10084 set() {
10085 warn(`The \`isCustomElement\` config option is deprecated. Use ` +
10086 `\`compilerOptions.isCustomElement\` instead.`);
10087 }
10088 });
10089 const compilerOptions = app.config.compilerOptions;
10090 const msg = `The \`compilerOptions\` config option is only respected when using ` +
10091 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
10092 `Since you are using the runtime-only build, \`compilerOptions\` ` +
10093 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
10094 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
10095 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
10096 `- 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`;
10097 Object.defineProperty(app.config, 'compilerOptions', {
10098 get() {
10099 warn(msg);
10100 return compilerOptions;
10101 },
10102 set() {
10103 warn(msg);
10104 }
10105 });
10106 }
10107}
10108function normalizeContainer(container) {
10109 if (isString(container)) {
10110 const res = document.querySelector(container);
10111 if (!res) {
10112 warn(`Failed to mount app: mount target selector "${container}" returned null.`);
10113 }
10114 return res;
10115 }
10116 if (container instanceof window.ShadowRoot &&
10117 container.mode === 'closed') {
10118 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
10119 }
10120 return container;
10121}
10122
10123var runtimeDom = /*#__PURE__*/Object.freeze({
10124 __proto__: null,
10125 render: render,
10126 hydrate: hydrate,
10127 createApp: createApp,
10128 createSSRApp: createSSRApp,
10129 useCssModule: useCssModule,
10130 useCssVars: useCssVars,
10131 Transition: Transition,
10132 TransitionGroup: TransitionGroup,
10133 vModelText: vModelText,
10134 vModelCheckbox: vModelCheckbox,
10135 vModelRadio: vModelRadio,
10136 vModelSelect: vModelSelect,
10137 vModelDynamic: vModelDynamic,
10138 withModifiers: withModifiers,
10139 withKeys: withKeys,
10140 vShow: vShow,
10141 reactive: reactive,
10142 ref: ref,
10143 readonly: readonly,
10144 unref: unref,
10145 proxyRefs: proxyRefs,
10146 isRef: isRef,
10147 toRef: toRef,
10148 toRefs: toRefs,
10149 isProxy: isProxy,
10150 isReactive: isReactive,
10151 isReadonly: isReadonly,
10152 customRef: customRef,
10153 triggerRef: triggerRef,
10154 shallowRef: shallowRef,
10155 shallowReactive: shallowReactive,
10156 shallowReadonly: shallowReadonly,
10157 markRaw: markRaw,
10158 toRaw: toRaw,
10159 computed: computed$1,
10160 watch: watch,
10161 watchEffect: watchEffect,
10162 onBeforeMount: onBeforeMount,
10163 onMounted: onMounted,
10164 onBeforeUpdate: onBeforeUpdate,
10165 onUpdated: onUpdated,
10166 onBeforeUnmount: onBeforeUnmount,
10167 onUnmounted: onUnmounted,
10168 onActivated: onActivated,
10169 onDeactivated: onDeactivated,
10170 onRenderTracked: onRenderTracked,
10171 onRenderTriggered: onRenderTriggered,
10172 onErrorCaptured: onErrorCaptured,
10173 onServerPrefetch: onServerPrefetch,
10174 provide: provide,
10175 inject: inject,
10176 nextTick: nextTick,
10177 defineComponent: defineComponent,
10178 defineAsyncComponent: defineAsyncComponent,
10179 defineProps: defineProps,
10180 defineEmit: defineEmit,
10181 useContext: useContext,
10182 getCurrentInstance: getCurrentInstance,
10183 h: h,
10184 createVNode: createVNode,
10185 cloneVNode: cloneVNode,
10186 mergeProps: mergeProps,
10187 isVNode: isVNode,
10188 Fragment: Fragment,
10189 Text: Text,
10190 Comment: Comment$1,
10191 Static: Static,
10192 Teleport: Teleport,
10193 Suspense: Suspense,
10194 KeepAlive: KeepAlive,
10195 BaseTransition: BaseTransition,
10196 withDirectives: withDirectives,
10197 useSSRContext: useSSRContext,
10198 ssrContextKey: ssrContextKey,
10199 createRenderer: createRenderer,
10200 createHydrationRenderer: createHydrationRenderer,
10201 queuePostFlushCb: queuePostFlushCb,
10202 warn: warn,
10203 handleError: handleError,
10204 callWithErrorHandling: callWithErrorHandling,
10205 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
10206 resolveComponent: resolveComponent,
10207 resolveDirective: resolveDirective,
10208 resolveDynamicComponent: resolveDynamicComponent,
10209 registerRuntimeCompiler: registerRuntimeCompiler,
10210 isRuntimeOnly: isRuntimeOnly,
10211 useTransitionState: useTransitionState,
10212 resolveTransitionHooks: resolveTransitionHooks,
10213 setTransitionHooks: setTransitionHooks,
10214 getTransitionRawChildren: getTransitionRawChildren,
10215 initCustomFormatter: initCustomFormatter,
10216 get devtools () { return devtools; },
10217 setDevtoolsHook: setDevtoolsHook,
10218 withCtx: withCtx,
10219 pushScopeId: pushScopeId,
10220 popScopeId: popScopeId,
10221 withScopeId: withScopeId,
10222 renderList: renderList,
10223 toHandlers: toHandlers,
10224 renderSlot: renderSlot,
10225 createSlots: createSlots,
10226 openBlock: openBlock,
10227 createBlock: createBlock,
10228 setBlockTracking: setBlockTracking,
10229 createTextVNode: createTextVNode,
10230 createCommentVNode: createCommentVNode,
10231 createStaticVNode: createStaticVNode,
10232 toDisplayString: toDisplayString,
10233 camelize: camelize,
10234 capitalize: capitalize,
10235 toHandlerKey: toHandlerKey,
10236 transformVNodeArgs: transformVNodeArgs,
10237 version: version,
10238 ssrUtils: ssrUtils,
10239 resolveFilter: resolveFilter,
10240 compatUtils: compatUtils
10241});
10242
10243function initDev() {
10244 {
10245 {
10246 console.info(`You are running a development build of Vue.\n` +
10247 `Make sure to use the production build (*.prod.js) when deploying for production.`);
10248 }
10249 initCustomFormatter();
10250 }
10251}
10252
10253function defaultOnError(error) {
10254 throw error;
10255}
10256function defaultOnWarn(msg) {
10257 console.warn(`[Vue warn] ${msg.message}`);
10258}
10259function createCompilerError(code, loc, messages, additionalMessage) {
10260 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
10261 ;
10262 const error = new SyntaxError(String(msg));
10263 error.code = code;
10264 error.loc = loc;
10265 return error;
10266}
10267const errorMessages = {
10268 // parse errors
10269 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
10270 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
10271 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
10272 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
10273 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
10274 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
10275 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
10276 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
10277 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
10278 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
10279 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
10280 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
10281 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
10282 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
10283 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
10284 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
10285 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
10286 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
10287 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
10288 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
10289 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
10290 [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null cahracter.`,
10291 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
10292 // Vue-specific parse errors
10293 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
10294 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
10295 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
10296 [26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
10297 'Note that dynamic directive argument cannot contain spaces.',
10298 // transform errors
10299 [27 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
10300 [28 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
10301 [29 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if.`,
10302 [30 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
10303 [31 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
10304 [32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
10305 [33 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
10306 [34 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
10307 [35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
10308 [36 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
10309 `When there are multiple named slots, all slots should use <template> ` +
10310 `syntax to avoid scope ambiguity.`,
10311 [37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
10312 [38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
10313 `default slot. These children will be ignored.`,
10314 [39 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
10315 [40 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
10316 [41 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
10317 [42 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
10318 [43 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
10319 [44 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
10320 // generic errors
10321 [45 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
10322 [46 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
10323 [47 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
10324 [48 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
10325 // just to fullfill types
10326 [49 /* __EXTEND_POINT__ */]: ``
10327};
10328
10329const FRAGMENT = Symbol(`Fragment` );
10330const TELEPORT = Symbol(`Teleport` );
10331const SUSPENSE = Symbol(`Suspense` );
10332const KEEP_ALIVE = Symbol(`KeepAlive` );
10333const BASE_TRANSITION = Symbol(`BaseTransition` );
10334const OPEN_BLOCK = Symbol(`openBlock` );
10335const CREATE_BLOCK = Symbol(`createBlock` );
10336const CREATE_VNODE = Symbol(`createVNode` );
10337const CREATE_COMMENT = Symbol(`createCommentVNode` );
10338const CREATE_TEXT = Symbol(`createTextVNode` );
10339const CREATE_STATIC = Symbol(`createStaticVNode` );
10340const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
10341const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
10342const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
10343const RESOLVE_FILTER = Symbol(`resolveFilter` );
10344const WITH_DIRECTIVES = Symbol(`withDirectives` );
10345const RENDER_LIST = Symbol(`renderList` );
10346const RENDER_SLOT = Symbol(`renderSlot` );
10347const CREATE_SLOTS = Symbol(`createSlots` );
10348const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
10349const MERGE_PROPS = Symbol(`mergeProps` );
10350const TO_HANDLERS = Symbol(`toHandlers` );
10351const CAMELIZE = Symbol(`camelize` );
10352const CAPITALIZE = Symbol(`capitalize` );
10353const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
10354const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
10355const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
10356const POP_SCOPE_ID = Symbol(`popScopeId` );
10357const WITH_SCOPE_ID = Symbol(`withScopeId` );
10358const WITH_CTX = Symbol(`withCtx` );
10359const UNREF = Symbol(`unref` );
10360const IS_REF = Symbol(`isRef` );
10361// Name mapping for runtime helpers that need to be imported from 'vue' in
10362// generated code. Make sure these are correctly exported in the runtime!
10363// Using `any` here because TS doesn't allow symbols as index type.
10364const helperNameMap = {
10365 [FRAGMENT]: `Fragment`,
10366 [TELEPORT]: `Teleport`,
10367 [SUSPENSE]: `Suspense`,
10368 [KEEP_ALIVE]: `KeepAlive`,
10369 [BASE_TRANSITION]: `BaseTransition`,
10370 [OPEN_BLOCK]: `openBlock`,
10371 [CREATE_BLOCK]: `createBlock`,
10372 [CREATE_VNODE]: `createVNode`,
10373 [CREATE_COMMENT]: `createCommentVNode`,
10374 [CREATE_TEXT]: `createTextVNode`,
10375 [CREATE_STATIC]: `createStaticVNode`,
10376 [RESOLVE_COMPONENT]: `resolveComponent`,
10377 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
10378 [RESOLVE_DIRECTIVE]: `resolveDirective`,
10379 [RESOLVE_FILTER]: `resolveFilter`,
10380 [WITH_DIRECTIVES]: `withDirectives`,
10381 [RENDER_LIST]: `renderList`,
10382 [RENDER_SLOT]: `renderSlot`,
10383 [CREATE_SLOTS]: `createSlots`,
10384 [TO_DISPLAY_STRING]: `toDisplayString`,
10385 [MERGE_PROPS]: `mergeProps`,
10386 [TO_HANDLERS]: `toHandlers`,
10387 [CAMELIZE]: `camelize`,
10388 [CAPITALIZE]: `capitalize`,
10389 [TO_HANDLER_KEY]: `toHandlerKey`,
10390 [SET_BLOCK_TRACKING]: `setBlockTracking`,
10391 [PUSH_SCOPE_ID]: `pushScopeId`,
10392 [POP_SCOPE_ID]: `popScopeId`,
10393 [WITH_SCOPE_ID]: `withScopeId`,
10394 [WITH_CTX]: `withCtx`,
10395 [UNREF]: `unref`,
10396 [IS_REF]: `isRef`
10397};
10398function registerRuntimeHelpers(helpers) {
10399 Object.getOwnPropertySymbols(helpers).forEach(s => {
10400 helperNameMap[s] = helpers[s];
10401 });
10402}
10403
10404// AST Utilities ---------------------------------------------------------------
10405// Some expressions, e.g. sequence and conditional expressions, are never
10406// associated with template nodes, so their source locations are just a stub.
10407// Container types like CompoundExpression also don't need a real location.
10408const locStub = {
10409 source: '',
10410 start: { line: 1, column: 1, offset: 0 },
10411 end: { line: 1, column: 1, offset: 0 }
10412};
10413function createRoot(children, loc = locStub) {
10414 return {
10415 type: 0 /* ROOT */,
10416 children,
10417 helpers: [],
10418 components: [],
10419 directives: [],
10420 hoists: [],
10421 imports: [],
10422 cached: 0,
10423 temps: 0,
10424 codegenNode: undefined,
10425 loc
10426 };
10427}
10428function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) {
10429 if (context) {
10430 if (isBlock) {
10431 context.helper(OPEN_BLOCK);
10432 context.helper(CREATE_BLOCK);
10433 }
10434 else {
10435 context.helper(CREATE_VNODE);
10436 }
10437 if (directives) {
10438 context.helper(WITH_DIRECTIVES);
10439 }
10440 }
10441 return {
10442 type: 13 /* VNODE_CALL */,
10443 tag,
10444 props,
10445 children,
10446 patchFlag,
10447 dynamicProps,
10448 directives,
10449 isBlock,
10450 disableTracking,
10451 loc
10452 };
10453}
10454function createArrayExpression(elements, loc = locStub) {
10455 return {
10456 type: 17 /* JS_ARRAY_EXPRESSION */,
10457 loc,
10458 elements
10459 };
10460}
10461function createObjectExpression(properties, loc = locStub) {
10462 return {
10463 type: 15 /* JS_OBJECT_EXPRESSION */,
10464 loc,
10465 properties
10466 };
10467}
10468function createObjectProperty(key, value) {
10469 return {
10470 type: 16 /* JS_PROPERTY */,
10471 loc: locStub,
10472 key: isString(key) ? createSimpleExpression(key, true) : key,
10473 value
10474 };
10475}
10476function createSimpleExpression(content, isStatic, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
10477 return {
10478 type: 4 /* SIMPLE_EXPRESSION */,
10479 loc,
10480 content,
10481 isStatic,
10482 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
10483 };
10484}
10485function createCompoundExpression(children, loc = locStub) {
10486 return {
10487 type: 8 /* COMPOUND_EXPRESSION */,
10488 loc,
10489 children
10490 };
10491}
10492function createCallExpression(callee, args = [], loc = locStub) {
10493 return {
10494 type: 14 /* JS_CALL_EXPRESSION */,
10495 loc,
10496 callee,
10497 arguments: args
10498 };
10499}
10500function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
10501 return {
10502 type: 18 /* JS_FUNCTION_EXPRESSION */,
10503 params,
10504 returns,
10505 newline,
10506 isSlot,
10507 loc
10508 };
10509}
10510function createConditionalExpression(test, consequent, alternate, newline = true) {
10511 return {
10512 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
10513 test,
10514 consequent,
10515 alternate,
10516 newline,
10517 loc: locStub
10518 };
10519}
10520function createCacheExpression(index, value, isVNode = false) {
10521 return {
10522 type: 20 /* JS_CACHE_EXPRESSION */,
10523 index,
10524 value,
10525 isVNode,
10526 loc: locStub
10527 };
10528}
10529
10530const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
10531const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
10532function isCoreComponent(tag) {
10533 if (isBuiltInType(tag, 'Teleport')) {
10534 return TELEPORT;
10535 }
10536 else if (isBuiltInType(tag, 'Suspense')) {
10537 return SUSPENSE;
10538 }
10539 else if (isBuiltInType(tag, 'KeepAlive')) {
10540 return KEEP_ALIVE;
10541 }
10542 else if (isBuiltInType(tag, 'BaseTransition')) {
10543 return BASE_TRANSITION;
10544 }
10545}
10546const nonIdentifierRE = /^\d|[^\$\w]/;
10547const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
10548const memberExpRE = /^[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*(?:\s*\.\s*[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*|\[(.+)\])*$/;
10549const isMemberExpression = (path) => {
10550 if (!path)
10551 return false;
10552 const matched = memberExpRE.exec(path.trim());
10553 if (!matched)
10554 return false;
10555 if (!matched[1])
10556 return true;
10557 if (!/[\[\]]/.test(matched[1]))
10558 return true;
10559 return isMemberExpression(matched[1].trim());
10560};
10561function getInnerRange(loc, offset, length) {
10562 const source = loc.source.substr(offset, length);
10563 const newLoc = {
10564 source,
10565 start: advancePositionWithClone(loc.start, loc.source, offset),
10566 end: loc.end
10567 };
10568 if (length != null) {
10569 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
10570 }
10571 return newLoc;
10572}
10573function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
10574 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
10575}
10576// advance by mutation without cloning (for performance reasons), since this
10577// gets called a lot in the parser
10578function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
10579 let linesCount = 0;
10580 let lastNewLinePos = -1;
10581 for (let i = 0; i < numberOfCharacters; i++) {
10582 if (source.charCodeAt(i) === 10 /* newline char code */) {
10583 linesCount++;
10584 lastNewLinePos = i;
10585 }
10586 }
10587 pos.offset += numberOfCharacters;
10588 pos.line += linesCount;
10589 pos.column =
10590 lastNewLinePos === -1
10591 ? pos.column + numberOfCharacters
10592 : numberOfCharacters - lastNewLinePos;
10593 return pos;
10594}
10595function assert(condition, msg) {
10596 /* istanbul ignore if */
10597 if (!condition) {
10598 throw new Error(msg || `unexpected compiler condition`);
10599 }
10600}
10601function findDir(node, name, allowEmpty = false) {
10602 for (let i = 0; i < node.props.length; i++) {
10603 const p = node.props[i];
10604 if (p.type === 7 /* DIRECTIVE */ &&
10605 (allowEmpty || p.exp) &&
10606 (isString(name) ? p.name === name : name.test(p.name))) {
10607 return p;
10608 }
10609 }
10610}
10611function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
10612 for (let i = 0; i < node.props.length; i++) {
10613 const p = node.props[i];
10614 if (p.type === 6 /* ATTRIBUTE */) {
10615 if (dynamicOnly)
10616 continue;
10617 if (p.name === name && (p.value || allowEmpty)) {
10618 return p;
10619 }
10620 }
10621 else if (p.name === 'bind' &&
10622 (p.exp || allowEmpty) &&
10623 isBindKey(p.arg, name)) {
10624 return p;
10625 }
10626 }
10627}
10628function isBindKey(arg, name) {
10629 return !!(arg && isStaticExp(arg) && arg.content === name);
10630}
10631function hasDynamicKeyVBind(node) {
10632 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
10633 p.name === 'bind' &&
10634 (!p.arg || // v-bind="obj"
10635 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
10636 !p.arg.isStatic) // v-bind:[foo]
10637 );
10638}
10639function isText(node) {
10640 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
10641}
10642function isVSlot(p) {
10643 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
10644}
10645function isTemplateNode(node) {
10646 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
10647}
10648function isSlotOutlet(node) {
10649 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
10650}
10651function injectProp(node, prop, context) {
10652 let propsWithInjection;
10653 const props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
10654 if (props == null || isString(props)) {
10655 propsWithInjection = createObjectExpression([prop]);
10656 }
10657 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
10658 // merged props... add ours
10659 // only inject key to object literal if it's the first argument so that
10660 // if doesn't override user provided keys
10661 const first = props.arguments[0];
10662 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
10663 first.properties.unshift(prop);
10664 }
10665 else {
10666 if (props.callee === TO_HANDLERS) {
10667 // #2366
10668 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
10669 createObjectExpression([prop]),
10670 props
10671 ]);
10672 }
10673 else {
10674 props.arguments.unshift(createObjectExpression([prop]));
10675 }
10676 }
10677 !propsWithInjection && (propsWithInjection = props);
10678 }
10679 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
10680 let alreadyExists = false;
10681 // check existing key to avoid overriding user provided keys
10682 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
10683 const propKeyName = prop.key.content;
10684 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
10685 p.key.content === propKeyName);
10686 }
10687 if (!alreadyExists) {
10688 props.properties.unshift(prop);
10689 }
10690 propsWithInjection = props;
10691 }
10692 else {
10693 // single v-bind with expression, return a merged replacement
10694 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
10695 createObjectExpression([prop]),
10696 props
10697 ]);
10698 }
10699 if (node.type === 13 /* VNODE_CALL */) {
10700 node.props = propsWithInjection;
10701 }
10702 else {
10703 node.arguments[2] = propsWithInjection;
10704 }
10705}
10706function toValidAssetId(name, type) {
10707 return `_${type}_${name.replace(/[^\w]/g, '_')}`;
10708}
10709
10710// The default decoder only provides escapes for characters reserved as part of
10711// the template syntax, and is only used if the custom renderer did not provide
10712// a platform-specific decoder.
10713const decodeRE = /&(gt|lt|amp|apos|quot);/g;
10714const decodeMap = {
10715 gt: '>',
10716 lt: '<',
10717 amp: '&',
10718 apos: "'",
10719 quot: '"'
10720};
10721const defaultParserOptions = {
10722 delimiters: [`{{`, `}}`],
10723 getNamespace: () => 0 /* HTML */,
10724 getTextMode: () => 0 /* DATA */,
10725 isVoidTag: NO,
10726 isPreTag: NO,
10727 isCustomElement: NO,
10728 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
10729 onError: defaultOnError,
10730 onWarn: defaultOnWarn,
10731 comments: false
10732};
10733function baseParse(content, options = {}) {
10734 const context = createParserContext(content, options);
10735 const start = getCursor(context);
10736 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
10737}
10738function createParserContext(content, rawOptions) {
10739 const options = extend({}, defaultParserOptions);
10740 for (const key in rawOptions) {
10741 // @ts-ignore
10742 options[key] = rawOptions[key] || defaultParserOptions[key];
10743 }
10744 return {
10745 options,
10746 column: 1,
10747 line: 1,
10748 offset: 0,
10749 originalSource: content,
10750 source: content,
10751 inPre: false,
10752 inVPre: false,
10753 onWarn: options.onWarn
10754 };
10755}
10756function parseChildren(context, mode, ancestors) {
10757 const parent = last(ancestors);
10758 const ns = parent ? parent.ns : 0 /* HTML */;
10759 const nodes = [];
10760 while (!isEnd(context, mode, ancestors)) {
10761 const s = context.source;
10762 let node = undefined;
10763 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
10764 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
10765 // '{{'
10766 node = parseInterpolation(context, mode);
10767 }
10768 else if (mode === 0 /* DATA */ && s[0] === '<') {
10769 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
10770 if (s.length === 1) {
10771 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
10772 }
10773 else if (s[1] === '!') {
10774 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
10775 if (startsWith(s, '<!--')) {
10776 node = parseComment(context);
10777 }
10778 else if (startsWith(s, '<!DOCTYPE')) {
10779 // Ignore DOCTYPE by a limitation.
10780 node = parseBogusComment(context);
10781 }
10782 else if (startsWith(s, '<![CDATA[')) {
10783 if (ns !== 0 /* HTML */) {
10784 node = parseCDATA(context, ancestors);
10785 }
10786 else {
10787 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
10788 node = parseBogusComment(context);
10789 }
10790 }
10791 else {
10792 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
10793 node = parseBogusComment(context);
10794 }
10795 }
10796 else if (s[1] === '/') {
10797 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
10798 if (s.length === 2) {
10799 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
10800 }
10801 else if (s[2] === '>') {
10802 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
10803 advanceBy(context, 3);
10804 continue;
10805 }
10806 else if (/[a-z]/i.test(s[2])) {
10807 emitError(context, 23 /* X_INVALID_END_TAG */);
10808 parseTag(context, 1 /* End */, parent);
10809 continue;
10810 }
10811 else {
10812 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
10813 node = parseBogusComment(context);
10814 }
10815 }
10816 else if (/[a-z]/i.test(s[1])) {
10817 node = parseElement(context, ancestors);
10818 }
10819 else if (s[1] === '?') {
10820 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
10821 node = parseBogusComment(context);
10822 }
10823 else {
10824 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
10825 }
10826 }
10827 }
10828 if (!node) {
10829 node = parseText(context, mode);
10830 }
10831 if (isArray(node)) {
10832 for (let i = 0; i < node.length; i++) {
10833 pushNode(nodes, node[i]);
10834 }
10835 }
10836 else {
10837 pushNode(nodes, node);
10838 }
10839 }
10840 // Whitespace handling strategy like v2
10841 let removedWhitespace = false;
10842 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
10843 const preserve = context.options.whitespace === 'preserve';
10844 for (let i = 0; i < nodes.length; i++) {
10845 const node = nodes[i];
10846 if (!context.inPre && node.type === 2 /* TEXT */) {
10847 if (!/[^\t\r\n\f ]/.test(node.content)) {
10848 const prev = nodes[i - 1];
10849 const next = nodes[i + 1];
10850 // Remove if:
10851 // - the whitespace is the first or last node, or:
10852 // - (condense mode) the whitespace is adjacent to a comment, or:
10853 // - (condense mode) the whitespace is between two elements AND contains newline
10854 if (!prev ||
10855 !next ||
10856 (!preserve &&
10857 (prev.type === 3 /* COMMENT */ ||
10858 next.type === 3 /* COMMENT */ ||
10859 (prev.type === 1 /* ELEMENT */ &&
10860 next.type === 1 /* ELEMENT */ &&
10861 /[\r\n]/.test(node.content))))) {
10862 removedWhitespace = true;
10863 nodes[i] = null;
10864 }
10865 else {
10866 // Otherwise, the whitespace is condensed into a single space
10867 node.content = ' ';
10868 }
10869 }
10870 else if (!preserve) {
10871 // in condense mode, consecutive whitespaces in text are condensed
10872 // down to a single space.
10873 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
10874 }
10875 }
10876 }
10877 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
10878 // remove leading newline per html spec
10879 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
10880 const first = nodes[0];
10881 if (first && first.type === 2 /* TEXT */) {
10882 first.content = first.content.replace(/^\r?\n/, '');
10883 }
10884 }
10885 }
10886 return removedWhitespace ? nodes.filter(Boolean) : nodes;
10887}
10888function pushNode(nodes, node) {
10889 if (node.type === 2 /* TEXT */) {
10890 const prev = last(nodes);
10891 // Merge if both this and the previous node are text and those are
10892 // consecutive. This happens for cases like "a < b".
10893 if (prev &&
10894 prev.type === 2 /* TEXT */ &&
10895 prev.loc.end.offset === node.loc.start.offset) {
10896 prev.content += node.content;
10897 prev.loc.end = node.loc.end;
10898 prev.loc.source += node.loc.source;
10899 return;
10900 }
10901 }
10902 nodes.push(node);
10903}
10904function parseCDATA(context, ancestors) {
10905 advanceBy(context, 9);
10906 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
10907 if (context.source.length === 0) {
10908 emitError(context, 6 /* EOF_IN_CDATA */);
10909 }
10910 else {
10911 advanceBy(context, 3);
10912 }
10913 return nodes;
10914}
10915function parseComment(context) {
10916 const start = getCursor(context);
10917 let content;
10918 // Regular comment.
10919 const match = /--(\!)?>/.exec(context.source);
10920 if (!match) {
10921 content = context.source.slice(4);
10922 advanceBy(context, context.source.length);
10923 emitError(context, 7 /* EOF_IN_COMMENT */);
10924 }
10925 else {
10926 if (match.index <= 3) {
10927 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
10928 }
10929 if (match[1]) {
10930 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
10931 }
10932 content = context.source.slice(4, match.index);
10933 // Advancing with reporting nested comments.
10934 const s = context.source.slice(0, match.index);
10935 let prevIndex = 1, nestedIndex = 0;
10936 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
10937 advanceBy(context, nestedIndex - prevIndex + 1);
10938 if (nestedIndex + 4 < s.length) {
10939 emitError(context, 16 /* NESTED_COMMENT */);
10940 }
10941 prevIndex = nestedIndex + 1;
10942 }
10943 advanceBy(context, match.index + match[0].length - prevIndex + 1);
10944 }
10945 return {
10946 type: 3 /* COMMENT */,
10947 content,
10948 loc: getSelection(context, start)
10949 };
10950}
10951function parseBogusComment(context) {
10952 const start = getCursor(context);
10953 const contentStart = context.source[1] === '?' ? 1 : 2;
10954 let content;
10955 const closeIndex = context.source.indexOf('>');
10956 if (closeIndex === -1) {
10957 content = context.source.slice(contentStart);
10958 advanceBy(context, context.source.length);
10959 }
10960 else {
10961 content = context.source.slice(contentStart, closeIndex);
10962 advanceBy(context, closeIndex + 1);
10963 }
10964 return {
10965 type: 3 /* COMMENT */,
10966 content,
10967 loc: getSelection(context, start)
10968 };
10969}
10970function parseElement(context, ancestors) {
10971 // Start tag.
10972 const wasInPre = context.inPre;
10973 const wasInVPre = context.inVPre;
10974 const parent = last(ancestors);
10975 const element = parseTag(context, 0 /* Start */, parent);
10976 const isPreBoundary = context.inPre && !wasInPre;
10977 const isVPreBoundary = context.inVPre && !wasInVPre;
10978 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
10979 return element;
10980 }
10981 // Children.
10982 ancestors.push(element);
10983 const mode = context.options.getTextMode(element, parent);
10984 const children = parseChildren(context, mode, ancestors);
10985 ancestors.pop();
10986 element.children = children;
10987 // End tag.
10988 if (startsWithEndTagOpen(context.source, element.tag)) {
10989 parseTag(context, 1 /* End */, parent);
10990 }
10991 else {
10992 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
10993 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
10994 const first = children[0];
10995 if (first && startsWith(first.loc.source, '<!--')) {
10996 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
10997 }
10998 }
10999 }
11000 element.loc = getSelection(context, element.loc.start);
11001 if (isPreBoundary) {
11002 context.inPre = false;
11003 }
11004 if (isVPreBoundary) {
11005 context.inVPre = false;
11006 }
11007 return element;
11008}
11009const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
11010function parseTag(context, type, parent) {
11011 // Tag open.
11012 const start = getCursor(context);
11013 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
11014 const tag = match[1];
11015 const ns = context.options.getNamespace(tag, parent);
11016 advanceBy(context, match[0].length);
11017 advanceSpaces(context);
11018 // save current state in case we need to re-parse attributes with v-pre
11019 const cursor = getCursor(context);
11020 const currentSource = context.source;
11021 // Attributes.
11022 let props = parseAttributes(context, type);
11023 // check <pre> tag
11024 if (context.options.isPreTag(tag)) {
11025 context.inPre = true;
11026 }
11027 // check v-pre
11028 if (type === 0 /* Start */ &&
11029 !context.inVPre &&
11030 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
11031 context.inVPre = true;
11032 // reset context
11033 extend(context, cursor);
11034 context.source = currentSource;
11035 // re-parse attrs and filter out v-pre itself
11036 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
11037 }
11038 // Tag close.
11039 let isSelfClosing = false;
11040 if (context.source.length === 0) {
11041 emitError(context, 9 /* EOF_IN_TAG */);
11042 }
11043 else {
11044 isSelfClosing = startsWith(context.source, '/>');
11045 if (type === 1 /* End */ && isSelfClosing) {
11046 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
11047 }
11048 advanceBy(context, isSelfClosing ? 2 : 1);
11049 }
11050 if (type === 1 /* End */) {
11051 return;
11052 }
11053 let tagType = 0 /* ELEMENT */;
11054 const options = context.options;
11055 if (!context.inVPre && !options.isCustomElement(tag)) {
11056 const hasVIs = props.some(p => {
11057 if (p.name !== 'is')
11058 return;
11059 // v-is="xxx" (TODO: deprecate)
11060 if (p.type === 7 /* DIRECTIVE */) {
11061 return true;
11062 }
11063 // is="vue:xxx"
11064 if (p.value && p.value.content.startsWith('vue:')) {
11065 return true;
11066 }
11067 });
11068 if (options.isNativeTag && !hasVIs) {
11069 if (!options.isNativeTag(tag))
11070 tagType = 1 /* COMPONENT */;
11071 }
11072 else if (hasVIs ||
11073 isCoreComponent(tag) ||
11074 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
11075 /^[A-Z]/.test(tag) ||
11076 tag === 'component') {
11077 tagType = 1 /* COMPONENT */;
11078 }
11079 if (tag === 'slot') {
11080 tagType = 2 /* SLOT */;
11081 }
11082 else if (tag === 'template' &&
11083 props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
11084 tagType = 3 /* TEMPLATE */;
11085 }
11086 }
11087 return {
11088 type: 1 /* ELEMENT */,
11089 ns,
11090 tag,
11091 tagType,
11092 props,
11093 isSelfClosing,
11094 children: [],
11095 loc: getSelection(context, start),
11096 codegenNode: undefined // to be created during transform phase
11097 };
11098}
11099function parseAttributes(context, type) {
11100 const props = [];
11101 const attributeNames = new Set();
11102 while (context.source.length > 0 &&
11103 !startsWith(context.source, '>') &&
11104 !startsWith(context.source, '/>')) {
11105 if (startsWith(context.source, '/')) {
11106 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
11107 advanceBy(context, 1);
11108 advanceSpaces(context);
11109 continue;
11110 }
11111 if (type === 1 /* End */) {
11112 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
11113 }
11114 const attr = parseAttribute(context, attributeNames);
11115 if (type === 0 /* Start */) {
11116 props.push(attr);
11117 }
11118 if (/^[^\t\r\n\f />]/.test(context.source)) {
11119 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
11120 }
11121 advanceSpaces(context);
11122 }
11123 return props;
11124}
11125function parseAttribute(context, nameSet) {
11126 // Name.
11127 const start = getCursor(context);
11128 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
11129 const name = match[0];
11130 if (nameSet.has(name)) {
11131 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
11132 }
11133 nameSet.add(name);
11134 if (name[0] === '=') {
11135 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
11136 }
11137 {
11138 const pattern = /["'<]/g;
11139 let m;
11140 while ((m = pattern.exec(name))) {
11141 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
11142 }
11143 }
11144 advanceBy(context, name.length);
11145 // Value
11146 let value = undefined;
11147 if (/^[\t\r\n\f ]*=/.test(context.source)) {
11148 advanceSpaces(context);
11149 advanceBy(context, 1);
11150 advanceSpaces(context);
11151 value = parseAttributeValue(context);
11152 if (!value) {
11153 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
11154 }
11155 }
11156 const loc = getSelection(context, start);
11157 if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {
11158 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
11159 let dirName = match[1] ||
11160 (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');
11161 let arg;
11162 if (match[2]) {
11163 const isSlot = dirName === 'slot';
11164 const startOffset = name.lastIndexOf(match[2]);
11165 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
11166 let content = match[2];
11167 let isStatic = true;
11168 if (content.startsWith('[')) {
11169 isStatic = false;
11170 if (!content.endsWith(']')) {
11171 emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
11172 }
11173 content = content.substr(1, content.length - 2);
11174 }
11175 else if (isSlot) {
11176 // #1241 special case for v-slot: vuetify relies extensively on slot
11177 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
11178 // supports such usage so we are keeping it consistent with 2.x.
11179 content += match[3] || '';
11180 }
11181 arg = {
11182 type: 4 /* SIMPLE_EXPRESSION */,
11183 content,
11184 isStatic,
11185 constType: isStatic
11186 ? 3 /* CAN_STRINGIFY */
11187 : 0 /* NOT_CONSTANT */,
11188 loc
11189 };
11190 }
11191 if (value && value.isQuoted) {
11192 const valueLoc = value.loc;
11193 valueLoc.start.offset++;
11194 valueLoc.start.column++;
11195 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
11196 valueLoc.source = valueLoc.source.slice(1, -1);
11197 }
11198 const modifiers = match[3] ? match[3].substr(1).split('.') : [];
11199 return {
11200 type: 7 /* DIRECTIVE */,
11201 name: dirName,
11202 exp: value && {
11203 type: 4 /* SIMPLE_EXPRESSION */,
11204 content: value.content,
11205 isStatic: false,
11206 // Treat as non-constant by default. This can be potentially set to
11207 // other values by `transformExpression` to make it eligible for hoisting.
11208 constType: 0 /* NOT_CONSTANT */,
11209 loc: value.loc
11210 },
11211 arg,
11212 modifiers,
11213 loc
11214 };
11215 }
11216 return {
11217 type: 6 /* ATTRIBUTE */,
11218 name,
11219 value: value && {
11220 type: 2 /* TEXT */,
11221 content: value.content,
11222 loc: value.loc
11223 },
11224 loc
11225 };
11226}
11227function parseAttributeValue(context) {
11228 const start = getCursor(context);
11229 let content;
11230 const quote = context.source[0];
11231 const isQuoted = quote === `"` || quote === `'`;
11232 if (isQuoted) {
11233 // Quoted value.
11234 advanceBy(context, 1);
11235 const endIndex = context.source.indexOf(quote);
11236 if (endIndex === -1) {
11237 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
11238 }
11239 else {
11240 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
11241 advanceBy(context, 1);
11242 }
11243 }
11244 else {
11245 // Unquoted
11246 const match = /^[^\t\r\n\f >]+/.exec(context.source);
11247 if (!match) {
11248 return undefined;
11249 }
11250 const unexpectedChars = /["'<=`]/g;
11251 let m;
11252 while ((m = unexpectedChars.exec(match[0]))) {
11253 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
11254 }
11255 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
11256 }
11257 return { content, isQuoted, loc: getSelection(context, start) };
11258}
11259function parseInterpolation(context, mode) {
11260 const [open, close] = context.options.delimiters;
11261 const closeIndex = context.source.indexOf(close, open.length);
11262 if (closeIndex === -1) {
11263 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
11264 return undefined;
11265 }
11266 const start = getCursor(context);
11267 advanceBy(context, open.length);
11268 const innerStart = getCursor(context);
11269 const innerEnd = getCursor(context);
11270 const rawContentLength = closeIndex - open.length;
11271 const rawContent = context.source.slice(0, rawContentLength);
11272 const preTrimContent = parseTextData(context, rawContentLength, mode);
11273 const content = preTrimContent.trim();
11274 const startOffset = preTrimContent.indexOf(content);
11275 if (startOffset > 0) {
11276 advancePositionWithMutation(innerStart, rawContent, startOffset);
11277 }
11278 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
11279 advancePositionWithMutation(innerEnd, rawContent, endOffset);
11280 advanceBy(context, close.length);
11281 return {
11282 type: 5 /* INTERPOLATION */,
11283 content: {
11284 type: 4 /* SIMPLE_EXPRESSION */,
11285 isStatic: false,
11286 // Set `isConstant` to false by default and will decide in transformExpression
11287 constType: 0 /* NOT_CONSTANT */,
11288 content,
11289 loc: getSelection(context, innerStart, innerEnd)
11290 },
11291 loc: getSelection(context, start)
11292 };
11293}
11294function parseText(context, mode) {
11295 const endTokens = ['<', context.options.delimiters[0]];
11296 if (mode === 3 /* CDATA */) {
11297 endTokens.push(']]>');
11298 }
11299 let endIndex = context.source.length;
11300 for (let i = 0; i < endTokens.length; i++) {
11301 const index = context.source.indexOf(endTokens[i], 1);
11302 if (index !== -1 && endIndex > index) {
11303 endIndex = index;
11304 }
11305 }
11306 const start = getCursor(context);
11307 const content = parseTextData(context, endIndex, mode);
11308 return {
11309 type: 2 /* TEXT */,
11310 content,
11311 loc: getSelection(context, start)
11312 };
11313}
11314/**
11315 * Get text data with a given length from the current location.
11316 * This translates HTML entities in the text data.
11317 */
11318function parseTextData(context, length, mode) {
11319 const rawText = context.source.slice(0, length);
11320 advanceBy(context, length);
11321 if (mode === 2 /* RAWTEXT */ ||
11322 mode === 3 /* CDATA */ ||
11323 rawText.indexOf('&') === -1) {
11324 return rawText;
11325 }
11326 else {
11327 // DATA or RCDATA containing "&"". Entity decoding required.
11328 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
11329 }
11330}
11331function getCursor(context) {
11332 const { column, line, offset } = context;
11333 return { column, line, offset };
11334}
11335function getSelection(context, start, end) {
11336 end = end || getCursor(context);
11337 return {
11338 start,
11339 end,
11340 source: context.originalSource.slice(start.offset, end.offset)
11341 };
11342}
11343function last(xs) {
11344 return xs[xs.length - 1];
11345}
11346function startsWith(source, searchString) {
11347 return source.startsWith(searchString);
11348}
11349function advanceBy(context, numberOfCharacters) {
11350 const { source } = context;
11351 advancePositionWithMutation(context, source, numberOfCharacters);
11352 context.source = source.slice(numberOfCharacters);
11353}
11354function advanceSpaces(context) {
11355 const match = /^[\t\r\n\f ]+/.exec(context.source);
11356 if (match) {
11357 advanceBy(context, match[0].length);
11358 }
11359}
11360function getNewPosition(context, start, numberOfCharacters) {
11361 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
11362}
11363function emitError(context, code, offset, loc = getCursor(context)) {
11364 if (offset) {
11365 loc.offset += offset;
11366 loc.column += offset;
11367 }
11368 context.options.onError(createCompilerError(code, {
11369 start: loc,
11370 end: loc,
11371 source: ''
11372 }));
11373}
11374function isEnd(context, mode, ancestors) {
11375 const s = context.source;
11376 switch (mode) {
11377 case 0 /* DATA */:
11378 if (startsWith(s, '</')) {
11379 // TODO: probably bad performance
11380 for (let i = ancestors.length - 1; i >= 0; --i) {
11381 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
11382 return true;
11383 }
11384 }
11385 }
11386 break;
11387 case 1 /* RCDATA */:
11388 case 2 /* RAWTEXT */: {
11389 const parent = last(ancestors);
11390 if (parent && startsWithEndTagOpen(s, parent.tag)) {
11391 return true;
11392 }
11393 break;
11394 }
11395 case 3 /* CDATA */:
11396 if (startsWith(s, ']]>')) {
11397 return true;
11398 }
11399 break;
11400 }
11401 return !s;
11402}
11403function startsWithEndTagOpen(source, tag) {
11404 return (startsWith(source, '</') &&
11405 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
11406 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
11407}
11408
11409function hoistStatic(root, context) {
11410 walk(root, context,
11411 // Root node is unfortunately non-hoistable due to potential parent
11412 // fallthrough attributes.
11413 isSingleElementRoot(root, root.children[0]));
11414}
11415function isSingleElementRoot(root, child) {
11416 const { children } = root;
11417 return (children.length === 1 &&
11418 child.type === 1 /* ELEMENT */ &&
11419 !isSlotOutlet(child));
11420}
11421function walk(node, context, doNotHoistNode = false) {
11422 let hasHoistedNode = false;
11423 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
11424 // static bindings with expressions. These expressions are guaranteed to be
11425 // constant so they are still eligible for hoisting, but they are only
11426 // available at runtime and therefore cannot be evaluated ahead of time.
11427 // This is only a concern for pre-stringification (via transformHoist by
11428 // @vue/compiler-dom), but doing it here allows us to perform only one full
11429 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
11430 // stringficiation threshold is met.
11431 let canStringify = true;
11432 const { children } = node;
11433 for (let i = 0; i < children.length; i++) {
11434 const child = children[i];
11435 // only plain elements & text calls are eligible for hoisting.
11436 if (child.type === 1 /* ELEMENT */ &&
11437 child.tagType === 0 /* ELEMENT */) {
11438 const constantType = doNotHoistNode
11439 ? 0 /* NOT_CONSTANT */
11440 : getConstantType(child, context);
11441 if (constantType > 0 /* NOT_CONSTANT */) {
11442 if (constantType < 3 /* CAN_STRINGIFY */) {
11443 canStringify = false;
11444 }
11445 if (constantType >= 2 /* CAN_HOIST */) {
11446 child.codegenNode.patchFlag =
11447 -1 /* HOISTED */ + (` /* HOISTED */` );
11448 child.codegenNode = context.hoist(child.codegenNode);
11449 hasHoistedNode = true;
11450 continue;
11451 }
11452 }
11453 else {
11454 // node may contain dynamic children, but its props may be eligible for
11455 // hoisting.
11456 const codegenNode = child.codegenNode;
11457 if (codegenNode.type === 13 /* VNODE_CALL */) {
11458 const flag = getPatchFlag(codegenNode);
11459 if ((!flag ||
11460 flag === 512 /* NEED_PATCH */ ||
11461 flag === 1 /* TEXT */) &&
11462 getGeneratedPropsConstantType(child, context) >=
11463 2 /* CAN_HOIST */) {
11464 const props = getNodeProps(child);
11465 if (props) {
11466 codegenNode.props = context.hoist(props);
11467 }
11468 }
11469 }
11470 }
11471 }
11472 else if (child.type === 12 /* TEXT_CALL */) {
11473 const contentType = getConstantType(child.content, context);
11474 if (contentType > 0) {
11475 if (contentType < 3 /* CAN_STRINGIFY */) {
11476 canStringify = false;
11477 }
11478 if (contentType >= 2 /* CAN_HOIST */) {
11479 child.codegenNode = context.hoist(child.codegenNode);
11480 hasHoistedNode = true;
11481 }
11482 }
11483 }
11484 // walk further
11485 if (child.type === 1 /* ELEMENT */) {
11486 const isComponent = child.tagType === 1 /* COMPONENT */;
11487 if (isComponent) {
11488 context.scopes.vSlot++;
11489 }
11490 walk(child, context);
11491 if (isComponent) {
11492 context.scopes.vSlot--;
11493 }
11494 }
11495 else if (child.type === 11 /* FOR */) {
11496 // Do not hoist v-for single child because it has to be a block
11497 walk(child, context, child.children.length === 1);
11498 }
11499 else if (child.type === 9 /* IF */) {
11500 for (let i = 0; i < child.branches.length; i++) {
11501 // Do not hoist v-if single child because it has to be a block
11502 walk(child.branches[i], context, child.branches[i].children.length === 1);
11503 }
11504 }
11505 }
11506 if (canStringify && hasHoistedNode && context.transformHoist) {
11507 context.transformHoist(children, context, node);
11508 }
11509}
11510function getConstantType(node, context) {
11511 const { constantCache } = context;
11512 switch (node.type) {
11513 case 1 /* ELEMENT */:
11514 if (node.tagType !== 0 /* ELEMENT */) {
11515 return 0 /* NOT_CONSTANT */;
11516 }
11517 const cached = constantCache.get(node);
11518 if (cached !== undefined) {
11519 return cached;
11520 }
11521 const codegenNode = node.codegenNode;
11522 if (codegenNode.type !== 13 /* VNODE_CALL */) {
11523 return 0 /* NOT_CONSTANT */;
11524 }
11525 const flag = getPatchFlag(codegenNode);
11526 if (!flag) {
11527 let returnType = 3 /* CAN_STRINGIFY */;
11528 // Element itself has no patch flag. However we still need to check:
11529 // 1. Even for a node with no patch flag, it is possible for it to contain
11530 // non-hoistable expressions that refers to scope variables, e.g. compiler
11531 // injected keys or cached event handlers. Therefore we need to always
11532 // check the codegenNode's props to be sure.
11533 const generatedPropsType = getGeneratedPropsConstantType(node, context);
11534 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
11535 constantCache.set(node, 0 /* NOT_CONSTANT */);
11536 return 0 /* NOT_CONSTANT */;
11537 }
11538 if (generatedPropsType < returnType) {
11539 returnType = generatedPropsType;
11540 }
11541 // 2. its children.
11542 for (let i = 0; i < node.children.length; i++) {
11543 const childType = getConstantType(node.children[i], context);
11544 if (childType === 0 /* NOT_CONSTANT */) {
11545 constantCache.set(node, 0 /* NOT_CONSTANT */);
11546 return 0 /* NOT_CONSTANT */;
11547 }
11548 if (childType < returnType) {
11549 returnType = childType;
11550 }
11551 }
11552 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
11553 // type, check if any of the props can cause the type to be lowered
11554 // we can skip can_patch because it's guaranteed by the absence of a
11555 // patchFlag.
11556 if (returnType > 1 /* CAN_SKIP_PATCH */) {
11557 for (let i = 0; i < node.props.length; i++) {
11558 const p = node.props[i];
11559 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
11560 const expType = getConstantType(p.exp, context);
11561 if (expType === 0 /* NOT_CONSTANT */) {
11562 constantCache.set(node, 0 /* NOT_CONSTANT */);
11563 return 0 /* NOT_CONSTANT */;
11564 }
11565 if (expType < returnType) {
11566 returnType = expType;
11567 }
11568 }
11569 }
11570 }
11571 // only svg/foreignObject could be block here, however if they are
11572 // static then they don't need to be blocks since there will be no
11573 // nested updates.
11574 if (codegenNode.isBlock) {
11575 context.removeHelper(OPEN_BLOCK);
11576 context.removeHelper(CREATE_BLOCK);
11577 codegenNode.isBlock = false;
11578 context.helper(CREATE_VNODE);
11579 }
11580 constantCache.set(node, returnType);
11581 return returnType;
11582 }
11583 else {
11584 constantCache.set(node, 0 /* NOT_CONSTANT */);
11585 return 0 /* NOT_CONSTANT */;
11586 }
11587 case 2 /* TEXT */:
11588 case 3 /* COMMENT */:
11589 return 3 /* CAN_STRINGIFY */;
11590 case 9 /* IF */:
11591 case 11 /* FOR */:
11592 case 10 /* IF_BRANCH */:
11593 return 0 /* NOT_CONSTANT */;
11594 case 5 /* INTERPOLATION */:
11595 case 12 /* TEXT_CALL */:
11596 return getConstantType(node.content, context);
11597 case 4 /* SIMPLE_EXPRESSION */:
11598 return node.constType;
11599 case 8 /* COMPOUND_EXPRESSION */:
11600 let returnType = 3 /* CAN_STRINGIFY */;
11601 for (let i = 0; i < node.children.length; i++) {
11602 const child = node.children[i];
11603 if (isString(child) || isSymbol(child)) {
11604 continue;
11605 }
11606 const childType = getConstantType(child, context);
11607 if (childType === 0 /* NOT_CONSTANT */) {
11608 return 0 /* NOT_CONSTANT */;
11609 }
11610 else if (childType < returnType) {
11611 returnType = childType;
11612 }
11613 }
11614 return returnType;
11615 default:
11616 return 0 /* NOT_CONSTANT */;
11617 }
11618}
11619function getGeneratedPropsConstantType(node, context) {
11620 let returnType = 3 /* CAN_STRINGIFY */;
11621 const props = getNodeProps(node);
11622 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
11623 const { properties } = props;
11624 for (let i = 0; i < properties.length; i++) {
11625 const { key, value } = properties[i];
11626 const keyType = getConstantType(key, context);
11627 if (keyType === 0 /* NOT_CONSTANT */) {
11628 return keyType;
11629 }
11630 if (keyType < returnType) {
11631 returnType = keyType;
11632 }
11633 if (value.type !== 4 /* SIMPLE_EXPRESSION */) {
11634 return 0 /* NOT_CONSTANT */;
11635 }
11636 const valueType = getConstantType(value, context);
11637 if (valueType === 0 /* NOT_CONSTANT */) {
11638 return valueType;
11639 }
11640 if (valueType < returnType) {
11641 returnType = valueType;
11642 }
11643 }
11644 }
11645 return returnType;
11646}
11647function getNodeProps(node) {
11648 const codegenNode = node.codegenNode;
11649 if (codegenNode.type === 13 /* VNODE_CALL */) {
11650 return codegenNode.props;
11651 }
11652}
11653function getPatchFlag(node) {
11654 const flag = node.patchFlag;
11655 return flag ? parseInt(flag, 10) : undefined;
11656}
11657
11658function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
11659 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
11660 const context = {
11661 // options
11662 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
11663 prefixIdentifiers,
11664 hoistStatic,
11665 cacheHandlers,
11666 nodeTransforms,
11667 directiveTransforms,
11668 transformHoist,
11669 isBuiltInComponent,
11670 isCustomElement,
11671 expressionPlugins,
11672 scopeId,
11673 slotted,
11674 ssr,
11675 ssrCssVars,
11676 bindingMetadata,
11677 inline,
11678 isTS,
11679 onError,
11680 onWarn,
11681 compatConfig,
11682 // state
11683 root,
11684 helpers: new Map(),
11685 components: new Set(),
11686 directives: new Set(),
11687 hoists: [],
11688 imports: [],
11689 constantCache: new Map(),
11690 temps: 0,
11691 cached: 0,
11692 identifiers: Object.create(null),
11693 scopes: {
11694 vFor: 0,
11695 vSlot: 0,
11696 vPre: 0,
11697 vOnce: 0
11698 },
11699 parent: null,
11700 currentNode: root,
11701 childIndex: 0,
11702 // methods
11703 helper(name) {
11704 const count = context.helpers.get(name) || 0;
11705 context.helpers.set(name, count + 1);
11706 return name;
11707 },
11708 removeHelper(name) {
11709 const count = context.helpers.get(name);
11710 if (count) {
11711 const currentCount = count - 1;
11712 if (!currentCount) {
11713 context.helpers.delete(name);
11714 }
11715 else {
11716 context.helpers.set(name, currentCount);
11717 }
11718 }
11719 },
11720 helperString(name) {
11721 return `_${helperNameMap[context.helper(name)]}`;
11722 },
11723 replaceNode(node) {
11724 /* istanbul ignore if */
11725 {
11726 if (!context.currentNode) {
11727 throw new Error(`Node being replaced is already removed.`);
11728 }
11729 if (!context.parent) {
11730 throw new Error(`Cannot replace root node.`);
11731 }
11732 }
11733 context.parent.children[context.childIndex] = context.currentNode = node;
11734 },
11735 removeNode(node) {
11736 if (!context.parent) {
11737 throw new Error(`Cannot remove root node.`);
11738 }
11739 const list = context.parent.children;
11740 const removalIndex = node
11741 ? list.indexOf(node)
11742 : context.currentNode
11743 ? context.childIndex
11744 : -1;
11745 /* istanbul ignore if */
11746 if (removalIndex < 0) {
11747 throw new Error(`node being removed is not a child of current parent`);
11748 }
11749 if (!node || node === context.currentNode) {
11750 // current node removed
11751 context.currentNode = null;
11752 context.onNodeRemoved();
11753 }
11754 else {
11755 // sibling node removed
11756 if (context.childIndex > removalIndex) {
11757 context.childIndex--;
11758 context.onNodeRemoved();
11759 }
11760 }
11761 context.parent.children.splice(removalIndex, 1);
11762 },
11763 onNodeRemoved: () => { },
11764 addIdentifiers(exp) {
11765 },
11766 removeIdentifiers(exp) {
11767 },
11768 hoist(exp) {
11769 context.hoists.push(exp);
11770 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
11771 identifier.hoisted = exp;
11772 return identifier;
11773 },
11774 cache(exp, isVNode = false) {
11775 return createCacheExpression(++context.cached, exp, isVNode);
11776 }
11777 };
11778 return context;
11779}
11780function transform(root, options) {
11781 const context = createTransformContext(root, options);
11782 traverseNode(root, context);
11783 if (options.hoistStatic) {
11784 hoistStatic(root, context);
11785 }
11786 if (!options.ssr) {
11787 createRootCodegen(root, context);
11788 }
11789 // finalize meta information
11790 root.helpers = [...context.helpers.keys()];
11791 root.components = [...context.components];
11792 root.directives = [...context.directives];
11793 root.imports = context.imports;
11794 root.hoists = context.hoists;
11795 root.temps = context.temps;
11796 root.cached = context.cached;
11797}
11798function createRootCodegen(root, context) {
11799 const { helper, removeHelper } = context;
11800 const { children } = root;
11801 if (children.length === 1) {
11802 const child = children[0];
11803 // if the single child is an element, turn it into a block.
11804 if (isSingleElementRoot(root, child) && child.codegenNode) {
11805 // single element root is never hoisted so codegenNode will never be
11806 // SimpleExpressionNode
11807 const codegenNode = child.codegenNode;
11808 if (codegenNode.type === 13 /* VNODE_CALL */) {
11809 if (!codegenNode.isBlock) {
11810 removeHelper(CREATE_VNODE);
11811 codegenNode.isBlock = true;
11812 helper(OPEN_BLOCK);
11813 helper(CREATE_BLOCK);
11814 }
11815 }
11816 root.codegenNode = codegenNode;
11817 }
11818 else {
11819 // - single <slot/>, IfNode, ForNode: already blocks.
11820 // - single text node: always patched.
11821 // root codegen falls through via genNode()
11822 root.codegenNode = child;
11823 }
11824 }
11825 else if (children.length > 1) {
11826 // root has multiple nodes - return a fragment block.
11827 let patchFlag = 64 /* STABLE_FRAGMENT */;
11828 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
11829 // check if the fragment actually contains a single valid child with
11830 // the rest being comments
11831 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
11832 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
11833 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
11834 }
11835 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true);
11836 }
11837 else ;
11838}
11839function traverseChildren(parent, context) {
11840 let i = 0;
11841 const nodeRemoved = () => {
11842 i--;
11843 };
11844 for (; i < parent.children.length; i++) {
11845 const child = parent.children[i];
11846 if (isString(child))
11847 continue;
11848 context.parent = parent;
11849 context.childIndex = i;
11850 context.onNodeRemoved = nodeRemoved;
11851 traverseNode(child, context);
11852 }
11853}
11854function traverseNode(node, context) {
11855 context.currentNode = node;
11856 // apply transform plugins
11857 const { nodeTransforms } = context;
11858 const exitFns = [];
11859 for (let i = 0; i < nodeTransforms.length; i++) {
11860 const onExit = nodeTransforms[i](node, context);
11861 if (onExit) {
11862 if (isArray(onExit)) {
11863 exitFns.push(...onExit);
11864 }
11865 else {
11866 exitFns.push(onExit);
11867 }
11868 }
11869 if (!context.currentNode) {
11870 // node was removed
11871 return;
11872 }
11873 else {
11874 // node may have been replaced
11875 node = context.currentNode;
11876 }
11877 }
11878 switch (node.type) {
11879 case 3 /* COMMENT */:
11880 if (!context.ssr) {
11881 // inject import for the Comment symbol, which is needed for creating
11882 // comment nodes with `createVNode`
11883 context.helper(CREATE_COMMENT);
11884 }
11885 break;
11886 case 5 /* INTERPOLATION */:
11887 // no need to traverse, but we need to inject toString helper
11888 if (!context.ssr) {
11889 context.helper(TO_DISPLAY_STRING);
11890 }
11891 break;
11892 // for container types, further traverse downwards
11893 case 9 /* IF */:
11894 for (let i = 0; i < node.branches.length; i++) {
11895 traverseNode(node.branches[i], context);
11896 }
11897 break;
11898 case 10 /* IF_BRANCH */:
11899 case 11 /* FOR */:
11900 case 1 /* ELEMENT */:
11901 case 0 /* ROOT */:
11902 traverseChildren(node, context);
11903 break;
11904 }
11905 // exit transforms
11906 context.currentNode = node;
11907 let i = exitFns.length;
11908 while (i--) {
11909 exitFns[i]();
11910 }
11911}
11912function createStructuralDirectiveTransform(name, fn) {
11913 const matches = isString(name)
11914 ? (n) => n === name
11915 : (n) => name.test(n);
11916 return (node, context) => {
11917 if (node.type === 1 /* ELEMENT */) {
11918 const { props } = node;
11919 // structural directive transforms are not concerned with slots
11920 // as they are handled separately in vSlot.ts
11921 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
11922 return;
11923 }
11924 const exitFns = [];
11925 for (let i = 0; i < props.length; i++) {
11926 const prop = props[i];
11927 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
11928 // structural directives are removed to avoid infinite recursion
11929 // also we remove them *before* applying so that it can further
11930 // traverse itself in case it moves the node around
11931 props.splice(i, 1);
11932 i--;
11933 const onExit = fn(node, prop, context);
11934 if (onExit)
11935 exitFns.push(onExit);
11936 }
11937 }
11938 return exitFns;
11939 }
11940 };
11941}
11942
11943const PURE_ANNOTATION = `/*#__PURE__*/`;
11944function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
11945 const context = {
11946 mode,
11947 prefixIdentifiers,
11948 sourceMap,
11949 filename,
11950 scopeId,
11951 optimizeImports,
11952 runtimeGlobalName,
11953 runtimeModuleName,
11954 ssr,
11955 source: ast.loc.source,
11956 code: ``,
11957 column: 1,
11958 line: 1,
11959 offset: 0,
11960 indentLevel: 0,
11961 pure: false,
11962 map: undefined,
11963 helper(key) {
11964 return `_${helperNameMap[key]}`;
11965 },
11966 push(code, node) {
11967 context.code += code;
11968 },
11969 indent() {
11970 newline(++context.indentLevel);
11971 },
11972 deindent(withoutNewLine = false) {
11973 if (withoutNewLine) {
11974 --context.indentLevel;
11975 }
11976 else {
11977 newline(--context.indentLevel);
11978 }
11979 },
11980 newline() {
11981 newline(context.indentLevel);
11982 }
11983 };
11984 function newline(n) {
11985 context.push('\n' + ` `.repeat(n));
11986 }
11987 return context;
11988}
11989function generate(ast, options = {}) {
11990 const context = createCodegenContext(ast, options);
11991 if (options.onContextCreated)
11992 options.onContextCreated(context);
11993 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
11994 const hasHelpers = ast.helpers.length > 0;
11995 const useWithBlock = !prefixIdentifiers && mode !== 'module';
11996 // preambles
11997 // in setup() inline mode, the preamble is generated in a sub context
11998 // and returned separately.
11999 const preambleContext = context;
12000 {
12001 genFunctionPreamble(ast, preambleContext);
12002 }
12003 // enter render function
12004 const functionName = ssr ? `ssrRender` : `render`;
12005 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
12006 const signature = args.join(', ');
12007 {
12008 push(`function ${functionName}(${signature}) {`);
12009 }
12010 indent();
12011 if (useWithBlock) {
12012 push(`with (_ctx) {`);
12013 indent();
12014 // function mode const declarations should be inside with block
12015 // also they should be renamed to avoid collision with user properties
12016 if (hasHelpers) {
12017 push(`const { ${ast.helpers
12018 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
12019 .join(', ')} } = _Vue`);
12020 push(`\n`);
12021 newline();
12022 }
12023 }
12024 // generate asset resolution statements
12025 if (ast.components.length) {
12026 genAssets(ast.components, 'component', context);
12027 if (ast.directives.length || ast.temps > 0) {
12028 newline();
12029 }
12030 }
12031 if (ast.directives.length) {
12032 genAssets(ast.directives, 'directive', context);
12033 if (ast.temps > 0) {
12034 newline();
12035 }
12036 }
12037 if (ast.temps > 0) {
12038 push(`let `);
12039 for (let i = 0; i < ast.temps; i++) {
12040 push(`${i > 0 ? `, ` : ``}_temp${i}`);
12041 }
12042 }
12043 if (ast.components.length || ast.directives.length || ast.temps) {
12044 push(`\n`);
12045 newline();
12046 }
12047 // generate the VNode tree expression
12048 if (!ssr) {
12049 push(`return `);
12050 }
12051 if (ast.codegenNode) {
12052 genNode(ast.codegenNode, context);
12053 }
12054 else {
12055 push(`null`);
12056 }
12057 if (useWithBlock) {
12058 deindent();
12059 push(`}`);
12060 }
12061 deindent();
12062 push(`}`);
12063 return {
12064 ast,
12065 code: context.code,
12066 preamble: ``,
12067 // SourceMapGenerator does have toJSON() method but it's not in the types
12068 map: context.map ? context.map.toJSON() : undefined
12069 };
12070}
12071function genFunctionPreamble(ast, context) {
12072 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;
12073 const VueBinding = runtimeGlobalName;
12074 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
12075 // Generate const declaration for helpers
12076 // In prefix mode, we place the const declaration at top so it's done
12077 // only once; But if we not prefixing, we place the declaration inside the
12078 // with block so it doesn't incur the `in` check cost for every helper access.
12079 if (ast.helpers.length > 0) {
12080 {
12081 // "with" mode.
12082 // save Vue in a separate variable to avoid collision
12083 push(`const _Vue = ${VueBinding}\n`);
12084 // in "with" mode, helpers are declared inside the with block to avoid
12085 // has check cost, but hoists are lifted out of the function - we need
12086 // to provide the helper here.
12087 if (ast.hoists.length) {
12088 const staticHelpers = [
12089 CREATE_VNODE,
12090 CREATE_COMMENT,
12091 CREATE_TEXT,
12092 CREATE_STATIC
12093 ]
12094 .filter(helper => ast.helpers.includes(helper))
12095 .map(aliasHelper)
12096 .join(', ');
12097 push(`const { ${staticHelpers} } = _Vue\n`);
12098 }
12099 }
12100 }
12101 genHoists(ast.hoists, context);
12102 newline();
12103 push(`return `);
12104}
12105function genAssets(assets, type, { helper, push, newline }) {
12106 const resolver = helper(type === 'component'
12107 ? RESOLVE_COMPONENT
12108 : RESOLVE_DIRECTIVE);
12109 for (let i = 0; i < assets.length; i++) {
12110 let id = assets[i];
12111 // potential component implicit self-reference inferred from SFC filename
12112 const maybeSelfReference = id.endsWith('__self');
12113 if (maybeSelfReference) {
12114 id = id.slice(0, -6);
12115 }
12116 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})`);
12117 if (i < assets.length - 1) {
12118 newline();
12119 }
12120 }
12121}
12122function genHoists(hoists, context) {
12123 if (!hoists.length) {
12124 return;
12125 }
12126 context.pure = true;
12127 const { push, newline, helper, scopeId, mode } = context;
12128 newline();
12129 hoists.forEach((exp, i) => {
12130 if (exp) {
12131 push(`const _hoisted_${i + 1} = `);
12132 genNode(exp, context);
12133 newline();
12134 }
12135 });
12136 context.pure = false;
12137}
12138function isText$1(n) {
12139 return (isString(n) ||
12140 n.type === 4 /* SIMPLE_EXPRESSION */ ||
12141 n.type === 2 /* TEXT */ ||
12142 n.type === 5 /* INTERPOLATION */ ||
12143 n.type === 8 /* COMPOUND_EXPRESSION */);
12144}
12145function genNodeListAsArray(nodes, context) {
12146 const multilines = nodes.length > 3 ||
12147 (nodes.some(n => isArray(n) || !isText$1(n)));
12148 context.push(`[`);
12149 multilines && context.indent();
12150 genNodeList(nodes, context, multilines);
12151 multilines && context.deindent();
12152 context.push(`]`);
12153}
12154function genNodeList(nodes, context, multilines = false, comma = true) {
12155 const { push, newline } = context;
12156 for (let i = 0; i < nodes.length; i++) {
12157 const node = nodes[i];
12158 if (isString(node)) {
12159 push(node);
12160 }
12161 else if (isArray(node)) {
12162 genNodeListAsArray(node, context);
12163 }
12164 else {
12165 genNode(node, context);
12166 }
12167 if (i < nodes.length - 1) {
12168 if (multilines) {
12169 comma && push(',');
12170 newline();
12171 }
12172 else {
12173 comma && push(', ');
12174 }
12175 }
12176 }
12177}
12178function genNode(node, context) {
12179 if (isString(node)) {
12180 context.push(node);
12181 return;
12182 }
12183 if (isSymbol(node)) {
12184 context.push(context.helper(node));
12185 return;
12186 }
12187 switch (node.type) {
12188 case 1 /* ELEMENT */:
12189 case 9 /* IF */:
12190 case 11 /* FOR */:
12191 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
12192 `Apply appropriate transforms first.`);
12193 genNode(node.codegenNode, context);
12194 break;
12195 case 2 /* TEXT */:
12196 genText(node, context);
12197 break;
12198 case 4 /* SIMPLE_EXPRESSION */:
12199 genExpression(node, context);
12200 break;
12201 case 5 /* INTERPOLATION */:
12202 genInterpolation(node, context);
12203 break;
12204 case 12 /* TEXT_CALL */:
12205 genNode(node.codegenNode, context);
12206 break;
12207 case 8 /* COMPOUND_EXPRESSION */:
12208 genCompoundExpression(node, context);
12209 break;
12210 case 3 /* COMMENT */:
12211 genComment(node, context);
12212 break;
12213 case 13 /* VNODE_CALL */:
12214 genVNodeCall(node, context);
12215 break;
12216 case 14 /* JS_CALL_EXPRESSION */:
12217 genCallExpression(node, context);
12218 break;
12219 case 15 /* JS_OBJECT_EXPRESSION */:
12220 genObjectExpression(node, context);
12221 break;
12222 case 17 /* JS_ARRAY_EXPRESSION */:
12223 genArrayExpression(node, context);
12224 break;
12225 case 18 /* JS_FUNCTION_EXPRESSION */:
12226 genFunctionExpression(node, context);
12227 break;
12228 case 19 /* JS_CONDITIONAL_EXPRESSION */:
12229 genConditionalExpression(node, context);
12230 break;
12231 case 20 /* JS_CACHE_EXPRESSION */:
12232 genCacheExpression(node, context);
12233 break;
12234 // SSR only types
12235 case 21 /* JS_BLOCK_STATEMENT */:
12236 break;
12237 case 22 /* JS_TEMPLATE_LITERAL */:
12238 break;
12239 case 23 /* JS_IF_STATEMENT */:
12240 break;
12241 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
12242 break;
12243 case 25 /* JS_SEQUENCE_EXPRESSION */:
12244 break;
12245 case 26 /* JS_RETURN_STATEMENT */:
12246 break;
12247 /* istanbul ignore next */
12248 case 10 /* IF_BRANCH */:
12249 // noop
12250 break;
12251 default:
12252 {
12253 assert(false, `unhandled codegen node type: ${node.type}`);
12254 // make sure we exhaust all possible types
12255 const exhaustiveCheck = node;
12256 return exhaustiveCheck;
12257 }
12258 }
12259}
12260function genText(node, context) {
12261 context.push(JSON.stringify(node.content), node);
12262}
12263function genExpression(node, context) {
12264 const { content, isStatic } = node;
12265 context.push(isStatic ? JSON.stringify(content) : content, node);
12266}
12267function genInterpolation(node, context) {
12268 const { push, helper, pure } = context;
12269 if (pure)
12270 push(PURE_ANNOTATION);
12271 push(`${helper(TO_DISPLAY_STRING)}(`);
12272 genNode(node.content, context);
12273 push(`)`);
12274}
12275function genCompoundExpression(node, context) {
12276 for (let i = 0; i < node.children.length; i++) {
12277 const child = node.children[i];
12278 if (isString(child)) {
12279 context.push(child);
12280 }
12281 else {
12282 genNode(child, context);
12283 }
12284 }
12285}
12286function genExpressionAsPropertyKey(node, context) {
12287 const { push } = context;
12288 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
12289 push(`[`);
12290 genCompoundExpression(node, context);
12291 push(`]`);
12292 }
12293 else if (node.isStatic) {
12294 // only quote keys if necessary
12295 const text = isSimpleIdentifier(node.content)
12296 ? node.content
12297 : JSON.stringify(node.content);
12298 push(text, node);
12299 }
12300 else {
12301 push(`[${node.content}]`, node);
12302 }
12303}
12304function genComment(node, context) {
12305 const { push, helper, pure } = context;
12306 if (pure) {
12307 push(PURE_ANNOTATION);
12308 }
12309 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
12310}
12311function genVNodeCall(node, context) {
12312 const { push, helper, pure } = context;
12313 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;
12314 if (directives) {
12315 push(helper(WITH_DIRECTIVES) + `(`);
12316 }
12317 if (isBlock) {
12318 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
12319 }
12320 if (pure) {
12321 push(PURE_ANNOTATION);
12322 }
12323 push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);
12324 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
12325 push(`)`);
12326 if (isBlock) {
12327 push(`)`);
12328 }
12329 if (directives) {
12330 push(`, `);
12331 genNode(directives, context);
12332 push(`)`);
12333 }
12334}
12335function genNullableArgs(args) {
12336 let i = args.length;
12337 while (i--) {
12338 if (args[i] != null)
12339 break;
12340 }
12341 return args.slice(0, i + 1).map(arg => arg || `null`);
12342}
12343// JavaScript
12344function genCallExpression(node, context) {
12345 const { push, helper, pure } = context;
12346 const callee = isString(node.callee) ? node.callee : helper(node.callee);
12347 if (pure) {
12348 push(PURE_ANNOTATION);
12349 }
12350 push(callee + `(`, node);
12351 genNodeList(node.arguments, context);
12352 push(`)`);
12353}
12354function genObjectExpression(node, context) {
12355 const { push, indent, deindent, newline } = context;
12356 const { properties } = node;
12357 if (!properties.length) {
12358 push(`{}`, node);
12359 return;
12360 }
12361 const multilines = properties.length > 1 ||
12362 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
12363 push(multilines ? `{` : `{ `);
12364 multilines && indent();
12365 for (let i = 0; i < properties.length; i++) {
12366 const { key, value } = properties[i];
12367 // key
12368 genExpressionAsPropertyKey(key, context);
12369 push(`: `);
12370 // value
12371 genNode(value, context);
12372 if (i < properties.length - 1) {
12373 // will only reach this if it's multilines
12374 push(`,`);
12375 newline();
12376 }
12377 }
12378 multilines && deindent();
12379 push(multilines ? `}` : ` }`);
12380}
12381function genArrayExpression(node, context) {
12382 genNodeListAsArray(node.elements, context);
12383}
12384function genFunctionExpression(node, context) {
12385 const { push, indent, deindent, scopeId, mode } = context;
12386 const { params, returns, body, newline, isSlot } = node;
12387 if (isSlot) {
12388 // wrap slot functions with owner context
12389 push(`_${helperNameMap[WITH_CTX]}(`);
12390 }
12391 push(`(`, node);
12392 if (isArray(params)) {
12393 genNodeList(params, context);
12394 }
12395 else if (params) {
12396 genNode(params, context);
12397 }
12398 push(`) => `);
12399 if (newline || body) {
12400 push(`{`);
12401 indent();
12402 }
12403 if (returns) {
12404 if (newline) {
12405 push(`return `);
12406 }
12407 if (isArray(returns)) {
12408 genNodeListAsArray(returns, context);
12409 }
12410 else {
12411 genNode(returns, context);
12412 }
12413 }
12414 else if (body) {
12415 genNode(body, context);
12416 }
12417 if (newline || body) {
12418 deindent();
12419 push(`}`);
12420 }
12421 if (isSlot) {
12422 push(`)`);
12423 }
12424}
12425function genConditionalExpression(node, context) {
12426 const { test, consequent, alternate, newline: needNewline } = node;
12427 const { push, indent, deindent, newline } = context;
12428 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
12429 const needsParens = !isSimpleIdentifier(test.content);
12430 needsParens && push(`(`);
12431 genExpression(test, context);
12432 needsParens && push(`)`);
12433 }
12434 else {
12435 push(`(`);
12436 genNode(test, context);
12437 push(`)`);
12438 }
12439 needNewline && indent();
12440 context.indentLevel++;
12441 needNewline || push(` `);
12442 push(`? `);
12443 genNode(consequent, context);
12444 context.indentLevel--;
12445 needNewline && newline();
12446 needNewline || push(` `);
12447 push(`: `);
12448 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
12449 if (!isNested) {
12450 context.indentLevel++;
12451 }
12452 genNode(alternate, context);
12453 if (!isNested) {
12454 context.indentLevel--;
12455 }
12456 needNewline && deindent(true /* without newline */);
12457}
12458function genCacheExpression(node, context) {
12459 const { push, helper, indent, deindent, newline } = context;
12460 push(`_cache[${node.index}] || (`);
12461 if (node.isVNode) {
12462 indent();
12463 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
12464 newline();
12465 }
12466 push(`_cache[${node.index}] = `);
12467 genNode(node.value, context);
12468 if (node.isVNode) {
12469 push(`,`);
12470 newline();
12471 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
12472 newline();
12473 push(`_cache[${node.index}]`);
12474 deindent();
12475 }
12476 push(`)`);
12477}
12478
12479// these keywords should not appear inside expressions, but operators like
12480// typeof, instanceof and in are allowed
12481const prohibitedKeywordRE = new RegExp('\\b' +
12482 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
12483 'super,throw,while,yield,delete,export,import,return,switch,default,' +
12484 'extends,finally,continue,debugger,function,arguments,typeof,void')
12485 .split(',')
12486 .join('\\b|\\b') +
12487 '\\b');
12488// strip strings in expressions
12489const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
12490/**
12491 * Validate a non-prefixed expression.
12492 * This is only called when using the in-browser runtime compiler since it
12493 * doesn't prefix expressions.
12494 */
12495function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
12496 const exp = node.content;
12497 // empty expressions are validated per-directive since some directives
12498 // do allow empty expressions.
12499 if (!exp.trim()) {
12500 return;
12501 }
12502 try {
12503 new Function(asRawStatements
12504 ? ` ${exp} `
12505 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
12506 }
12507 catch (e) {
12508 let message = e.message;
12509 const keywordMatch = exp
12510 .replace(stripStringRE, '')
12511 .match(prohibitedKeywordRE);
12512 if (keywordMatch) {
12513 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
12514 }
12515 context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
12516 }
12517}
12518
12519const transformExpression = (node, context) => {
12520 if (node.type === 5 /* INTERPOLATION */) {
12521 node.content = processExpression(node.content, context);
12522 }
12523 else if (node.type === 1 /* ELEMENT */) {
12524 // handle directives on element
12525 for (let i = 0; i < node.props.length; i++) {
12526 const dir = node.props[i];
12527 // do not process for v-on & v-for since they are special handled
12528 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
12529 const exp = dir.exp;
12530 const arg = dir.arg;
12531 // do not process exp if this is v-on:arg - we need special handling
12532 // for wrapping inline statements.
12533 if (exp &&
12534 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
12535 !(dir.name === 'on' && arg)) {
12536 dir.exp = processExpression(exp, context,
12537 // slot args must be processed as function params
12538 dir.name === 'slot');
12539 }
12540 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
12541 dir.arg = processExpression(arg, context);
12542 }
12543 }
12544 }
12545 }
12546};
12547// Important: since this function uses Node.js only dependencies, it should
12548// always be used with a leading !true check so that it can be
12549// tree-shaken from the browser build.
12550function processExpression(node, context,
12551// some expressions like v-slot props & v-for aliases should be parsed as
12552// function params
12553asParams = false,
12554// v-on handler values may contain multiple statements
12555asRawStatements = false) {
12556 {
12557 {
12558 // simple in-browser validation (same logic in 2.x)
12559 validateBrowserExpression(node, context, asParams, asRawStatements);
12560 }
12561 return node;
12562 }
12563}
12564
12565const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
12566 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
12567 // #1587: We need to dynamically increment the key based on the current
12568 // node's sibling nodes, since chained v-if/else branches are
12569 // rendered at the same depth
12570 const siblings = context.parent.children;
12571 let i = siblings.indexOf(ifNode);
12572 let key = 0;
12573 while (i-- >= 0) {
12574 const sibling = siblings[i];
12575 if (sibling && sibling.type === 9 /* IF */) {
12576 key += sibling.branches.length;
12577 }
12578 }
12579 // Exit callback. Complete the codegenNode when all children have been
12580 // transformed.
12581 return () => {
12582 if (isRoot) {
12583 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
12584 }
12585 else {
12586 // attach this branch's codegen node to the v-if root.
12587 const parentCondition = getParentCondition(ifNode.codegenNode);
12588 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
12589 }
12590 };
12591 });
12592});
12593// target-agnostic transform used for both Client and SSR
12594function processIf(node, dir, context, processCodegen) {
12595 if (dir.name !== 'else' &&
12596 (!dir.exp || !dir.exp.content.trim())) {
12597 const loc = dir.exp ? dir.exp.loc : node.loc;
12598 context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));
12599 dir.exp = createSimpleExpression(`true`, false, loc);
12600 }
12601 if (dir.exp) {
12602 validateBrowserExpression(dir.exp, context);
12603 }
12604 if (dir.name === 'if') {
12605 const branch = createIfBranch(node, dir);
12606 const ifNode = {
12607 type: 9 /* IF */,
12608 loc: node.loc,
12609 branches: [branch]
12610 };
12611 context.replaceNode(ifNode);
12612 if (processCodegen) {
12613 return processCodegen(ifNode, branch, true);
12614 }
12615 }
12616 else {
12617 // locate the adjacent v-if
12618 const siblings = context.parent.children;
12619 const comments = [];
12620 let i = siblings.indexOf(node);
12621 while (i-- >= -1) {
12622 const sibling = siblings[i];
12623 if (sibling && sibling.type === 3 /* COMMENT */) {
12624 context.removeNode(sibling);
12625 comments.unshift(sibling);
12626 continue;
12627 }
12628 if (sibling &&
12629 sibling.type === 2 /* TEXT */ &&
12630 !sibling.content.trim().length) {
12631 context.removeNode(sibling);
12632 continue;
12633 }
12634 if (sibling && sibling.type === 9 /* IF */) {
12635 // move the node to the if node's branches
12636 context.removeNode();
12637 const branch = createIfBranch(node, dir);
12638 if (comments.length &&
12639 // #3619 ignore comments if the v-if is direct child of <transition>
12640 !(context.parent &&
12641 context.parent.type === 1 /* ELEMENT */ &&
12642 isBuiltInType(context.parent.tag, 'transition'))) {
12643 branch.children = [...comments, ...branch.children];
12644 }
12645 // check if user is forcing same key on different branches
12646 {
12647 const key = branch.userKey;
12648 if (key) {
12649 sibling.branches.forEach(({ userKey }) => {
12650 if (isSameKey(userKey, key)) {
12651 context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
12652 }
12653 });
12654 }
12655 }
12656 sibling.branches.push(branch);
12657 const onExit = processCodegen && processCodegen(sibling, branch, false);
12658 // since the branch was removed, it will not be traversed.
12659 // make sure to traverse here.
12660 traverseNode(branch, context);
12661 // call on exit
12662 if (onExit)
12663 onExit();
12664 // make sure to reset currentNode after traversal to indicate this
12665 // node has been removed.
12666 context.currentNode = null;
12667 }
12668 else {
12669 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
12670 }
12671 break;
12672 }
12673 }
12674}
12675function createIfBranch(node, dir) {
12676 return {
12677 type: 10 /* IF_BRANCH */,
12678 loc: node.loc,
12679 condition: dir.name === 'else' ? undefined : dir.exp,
12680 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
12681 ? node.children
12682 : [node],
12683 userKey: findProp(node, `key`)
12684 };
12685}
12686function createCodegenNodeForBranch(branch, keyIndex, context) {
12687 if (branch.condition) {
12688 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
12689 // make sure to pass in asBlock: true so that the comment node call
12690 // closes the current block.
12691 createCallExpression(context.helper(CREATE_COMMENT), [
12692 '"v-if"' ,
12693 'true'
12694 ]));
12695 }
12696 else {
12697 return createChildrenCodegenNode(branch, keyIndex, context);
12698 }
12699}
12700function createChildrenCodegenNode(branch, keyIndex, context) {
12701 const { helper, removeHelper } = context;
12702 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
12703 const { children } = branch;
12704 const firstChild = children[0];
12705 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
12706 if (needFragmentWrapper) {
12707 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
12708 // optimize away nested fragments when child is a ForNode
12709 const vnodeCall = firstChild.codegenNode;
12710 injectProp(vnodeCall, keyProperty, context);
12711 return vnodeCall;
12712 }
12713 else {
12714 let patchFlag = 64 /* STABLE_FRAGMENT */;
12715 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
12716 // check if the fragment actually contains a single valid child with
12717 // the rest being comments
12718 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
12719 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
12720 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
12721 }
12722 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, branch.loc);
12723 }
12724 }
12725 else {
12726 const vnodeCall = firstChild
12727 .codegenNode;
12728 // Change createVNode to createBlock.
12729 if (vnodeCall.type === 13 /* VNODE_CALL */ && !vnodeCall.isBlock) {
12730 removeHelper(CREATE_VNODE);
12731 vnodeCall.isBlock = true;
12732 helper(OPEN_BLOCK);
12733 helper(CREATE_BLOCK);
12734 }
12735 // inject branch key
12736 injectProp(vnodeCall, keyProperty, context);
12737 return vnodeCall;
12738 }
12739}
12740function isSameKey(a, b) {
12741 if (!a || a.type !== b.type) {
12742 return false;
12743 }
12744 if (a.type === 6 /* ATTRIBUTE */) {
12745 if (a.value.content !== b.value.content) {
12746 return false;
12747 }
12748 }
12749 else {
12750 // directive
12751 const exp = a.exp;
12752 const branchExp = b.exp;
12753 if (exp.type !== branchExp.type) {
12754 return false;
12755 }
12756 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
12757 (exp.isStatic !== branchExp.isStatic ||
12758 exp.content !== branchExp.content)) {
12759 return false;
12760 }
12761 }
12762 return true;
12763}
12764function getParentCondition(node) {
12765 while (true) {
12766 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12767 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12768 node = node.alternate;
12769 }
12770 else {
12771 return node;
12772 }
12773 }
12774 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
12775 node = node.value;
12776 }
12777 }
12778}
12779
12780const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
12781 const { helper, removeHelper } = context;
12782 return processFor(node, dir, context, forNode => {
12783 // create the loop render function expression now, and add the
12784 // iterator on exit after all children have been traversed
12785 const renderExp = createCallExpression(helper(RENDER_LIST), [
12786 forNode.source
12787 ]);
12788 const keyProp = findProp(node, `key`);
12789 const keyProperty = keyProp
12790 ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */
12791 ? createSimpleExpression(keyProp.value.content, true)
12792 : keyProp.exp)
12793 : null;
12794 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
12795 forNode.source.constType > 0 /* NOT_CONSTANT */;
12796 const fragmentFlag = isStableFragment
12797 ? 64 /* STABLE_FRAGMENT */
12798 : keyProp
12799 ? 128 /* KEYED_FRAGMENT */
12800 : 256 /* UNKEYED_FRAGMENT */;
12801 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
12802 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);
12803 return () => {
12804 // finish the codegen now that all children have been traversed
12805 let childBlock;
12806 const isTemplate = isTemplateNode(node);
12807 const { children } = forNode;
12808 // check <template v-for> key placement
12809 if (isTemplate) {
12810 node.children.some(c => {
12811 if (c.type === 1 /* ELEMENT */) {
12812 const key = findProp(c, 'key');
12813 if (key) {
12814 context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
12815 return true;
12816 }
12817 }
12818 });
12819 }
12820 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
12821 const slotOutlet = isSlotOutlet(node)
12822 ? node
12823 : isTemplate &&
12824 node.children.length === 1 &&
12825 isSlotOutlet(node.children[0])
12826 ? node.children[0] // api-extractor somehow fails to infer this
12827 : null;
12828 if (slotOutlet) {
12829 // <slot v-for="..."> or <template v-for="..."><slot/></template>
12830 childBlock = slotOutlet.codegenNode;
12831 if (isTemplate && keyProperty) {
12832 // <template v-for="..." :key="..."><slot/></template>
12833 // we need to inject the key to the renderSlot() call.
12834 // the props for renderSlot is passed as the 3rd argument.
12835 injectProp(childBlock, keyProperty, context);
12836 }
12837 }
12838 else if (needFragmentWrapper) {
12839 // <template v-for="..."> with text or multi-elements
12840 // should generate a fragment block for each loop
12841 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
12842 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
12843 ), undefined, undefined, true);
12844 }
12845 else {
12846 // Normal element v-for. Directly use the child's codegenNode
12847 // but mark it as a block.
12848 childBlock = children[0]
12849 .codegenNode;
12850 if (isTemplate && keyProperty) {
12851 injectProp(childBlock, keyProperty, context);
12852 }
12853 if (childBlock.isBlock !== !isStableFragment) {
12854 if (childBlock.isBlock) {
12855 // switch from block to vnode
12856 removeHelper(OPEN_BLOCK);
12857 removeHelper(CREATE_BLOCK);
12858 }
12859 else {
12860 // switch from vnode to block
12861 removeHelper(CREATE_VNODE);
12862 }
12863 }
12864 childBlock.isBlock = !isStableFragment;
12865 if (childBlock.isBlock) {
12866 helper(OPEN_BLOCK);
12867 helper(CREATE_BLOCK);
12868 }
12869 else {
12870 helper(CREATE_VNODE);
12871 }
12872 }
12873 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
12874 };
12875 });
12876});
12877// target-agnostic transform used for both Client and SSR
12878function processFor(node, dir, context, processCodegen) {
12879 if (!dir.exp) {
12880 context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
12881 return;
12882 }
12883 const parseResult = parseForExpression(
12884 // can only be simple expression because vFor transform is applied
12885 // before expression transform.
12886 dir.exp, context);
12887 if (!parseResult) {
12888 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
12889 return;
12890 }
12891 const { addIdentifiers, removeIdentifiers, scopes } = context;
12892 const { source, value, key, index } = parseResult;
12893 const forNode = {
12894 type: 11 /* FOR */,
12895 loc: dir.loc,
12896 source,
12897 valueAlias: value,
12898 keyAlias: key,
12899 objectIndexAlias: index,
12900 parseResult,
12901 children: isTemplateNode(node) ? node.children : [node]
12902 };
12903 context.replaceNode(forNode);
12904 // bookkeeping
12905 scopes.vFor++;
12906 const onExit = processCodegen && processCodegen(forNode);
12907 return () => {
12908 scopes.vFor--;
12909 if (onExit)
12910 onExit();
12911 };
12912}
12913const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
12914// This regex doesn't cover the case if key or index aliases have destructuring,
12915// but those do not make sense in the first place, so this works in practice.
12916const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
12917const stripParensRE = /^\(|\)$/g;
12918function parseForExpression(input, context) {
12919 const loc = input.loc;
12920 const exp = input.content;
12921 const inMatch = exp.match(forAliasRE);
12922 if (!inMatch)
12923 return;
12924 const [, LHS, RHS] = inMatch;
12925 const result = {
12926 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
12927 value: undefined,
12928 key: undefined,
12929 index: undefined
12930 };
12931 {
12932 validateBrowserExpression(result.source, context);
12933 }
12934 let valueContent = LHS.trim()
12935 .replace(stripParensRE, '')
12936 .trim();
12937 const trimmedOffset = LHS.indexOf(valueContent);
12938 const iteratorMatch = valueContent.match(forIteratorRE);
12939 if (iteratorMatch) {
12940 valueContent = valueContent.replace(forIteratorRE, '').trim();
12941 const keyContent = iteratorMatch[1].trim();
12942 let keyOffset;
12943 if (keyContent) {
12944 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
12945 result.key = createAliasExpression(loc, keyContent, keyOffset);
12946 {
12947 validateBrowserExpression(result.key, context, true);
12948 }
12949 }
12950 if (iteratorMatch[2]) {
12951 const indexContent = iteratorMatch[2].trim();
12952 if (indexContent) {
12953 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
12954 ? keyOffset + keyContent.length
12955 : trimmedOffset + valueContent.length));
12956 {
12957 validateBrowserExpression(result.index, context, true);
12958 }
12959 }
12960 }
12961 }
12962 if (valueContent) {
12963 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
12964 {
12965 validateBrowserExpression(result.value, context, true);
12966 }
12967 }
12968 return result;
12969}
12970function createAliasExpression(range, content, offset) {
12971 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
12972}
12973function createForLoopParams({ value, key, index }) {
12974 const params = [];
12975 if (value) {
12976 params.push(value);
12977 }
12978 if (key) {
12979 if (!value) {
12980 params.push(createSimpleExpression(`_`, false));
12981 }
12982 params.push(key);
12983 }
12984 if (index) {
12985 if (!key) {
12986 if (!value) {
12987 params.push(createSimpleExpression(`_`, false));
12988 }
12989 params.push(createSimpleExpression(`__`, false));
12990 }
12991 params.push(index);
12992 }
12993 return params;
12994}
12995
12996const defaultFallback = createSimpleExpression(`undefined`, false);
12997// A NodeTransform that:
12998// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
12999// by transformExpression. This is only applied in non-browser builds with
13000// { prefixIdentifiers: true }.
13001// 2. Track v-slot depths so that we know a slot is inside another slot.
13002// Note the exit callback is executed before buildSlots() on the same node,
13003// so only nested slots see positive numbers.
13004const trackSlotScopes = (node, context) => {
13005 if (node.type === 1 /* ELEMENT */ &&
13006 (node.tagType === 1 /* COMPONENT */ ||
13007 node.tagType === 3 /* TEMPLATE */)) {
13008 // We are only checking non-empty v-slot here
13009 // since we only care about slots that introduce scope variables.
13010 const vSlot = findDir(node, 'slot');
13011 if (vSlot) {
13012 vSlot.exp;
13013 context.scopes.vSlot++;
13014 return () => {
13015 context.scopes.vSlot--;
13016 };
13017 }
13018 }
13019};
13020const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
13021// Instead of being a DirectiveTransform, v-slot processing is called during
13022// transformElement to build the slots object for a component.
13023function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
13024 context.helper(WITH_CTX);
13025 const { children, loc } = node;
13026 const slotsProperties = [];
13027 const dynamicSlots = [];
13028 // If the slot is inside a v-for or another v-slot, force it to be dynamic
13029 // since it likely uses a scope variable.
13030 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
13031 // 1. Check for slot with slotProps on component itself.
13032 // <Comp v-slot="{ prop }"/>
13033 const onComponentSlot = findDir(node, 'slot', true);
13034 if (onComponentSlot) {
13035 const { arg, exp } = onComponentSlot;
13036 if (arg && !isStaticExp(arg)) {
13037 hasDynamicSlots = true;
13038 }
13039 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
13040 }
13041 // 2. Iterate through children and check for template slots
13042 // <template v-slot:foo="{ prop }">
13043 let hasTemplateSlots = false;
13044 let hasNamedDefaultSlot = false;
13045 const implicitDefaultChildren = [];
13046 const seenSlotNames = new Set();
13047 for (let i = 0; i < children.length; i++) {
13048 const slotElement = children[i];
13049 let slotDir;
13050 if (!isTemplateNode(slotElement) ||
13051 !(slotDir = findDir(slotElement, 'slot', true))) {
13052 // not a <template v-slot>, skip.
13053 if (slotElement.type !== 3 /* COMMENT */) {
13054 implicitDefaultChildren.push(slotElement);
13055 }
13056 continue;
13057 }
13058 if (onComponentSlot) {
13059 // already has on-component slot - this is incorrect usage.
13060 context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
13061 break;
13062 }
13063 hasTemplateSlots = true;
13064 const { children: slotChildren, loc: slotLoc } = slotElement;
13065 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
13066 // check if name is dynamic.
13067 let staticSlotName;
13068 if (isStaticExp(slotName)) {
13069 staticSlotName = slotName ? slotName.content : `default`;
13070 }
13071 else {
13072 hasDynamicSlots = true;
13073 }
13074 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
13075 // check if this slot is conditional (v-if/v-for)
13076 let vIf;
13077 let vElse;
13078 let vFor;
13079 if ((vIf = findDir(slotElement, 'if'))) {
13080 hasDynamicSlots = true;
13081 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
13082 }
13083 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
13084 // find adjacent v-if
13085 let j = i;
13086 let prev;
13087 while (j--) {
13088 prev = children[j];
13089 if (prev.type !== 3 /* COMMENT */) {
13090 break;
13091 }
13092 }
13093 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
13094 // remove node
13095 children.splice(i, 1);
13096 i--;
13097 // attach this slot to previous conditional
13098 let conditional = dynamicSlots[dynamicSlots.length - 1];
13099 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13100 conditional = conditional.alternate;
13101 }
13102 conditional.alternate = vElse.exp
13103 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
13104 : buildDynamicSlot(slotName, slotFunction);
13105 }
13106 else {
13107 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
13108 }
13109 }
13110 else if ((vFor = findDir(slotElement, 'for'))) {
13111 hasDynamicSlots = true;
13112 const parseResult = vFor.parseResult ||
13113 parseForExpression(vFor.exp, context);
13114 if (parseResult) {
13115 // Render the dynamic slots as an array and add it to the createSlot()
13116 // args. The runtime knows how to handle it appropriately.
13117 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
13118 parseResult.source,
13119 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
13120 ]));
13121 }
13122 else {
13123 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
13124 }
13125 }
13126 else {
13127 // check duplicate static names
13128 if (staticSlotName) {
13129 if (seenSlotNames.has(staticSlotName)) {
13130 context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
13131 continue;
13132 }
13133 seenSlotNames.add(staticSlotName);
13134 if (staticSlotName === 'default') {
13135 hasNamedDefaultSlot = true;
13136 }
13137 }
13138 slotsProperties.push(createObjectProperty(slotName, slotFunction));
13139 }
13140 }
13141 if (!onComponentSlot) {
13142 const buildDefaultSlotProperty = (props, children) => {
13143 const fn = buildSlotFn(props, children, loc);
13144 return createObjectProperty(`default`, fn);
13145 };
13146 if (!hasTemplateSlots) {
13147 // implicit default slot (on component)
13148 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
13149 }
13150 else if (implicitDefaultChildren.length &&
13151 // #3766
13152 // with whitespace: 'preserve', whitespaces between slots will end up in
13153 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
13154 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
13155 // implicit default slot (mixed with named slots)
13156 if (hasNamedDefaultSlot) {
13157 context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
13158 }
13159 else {
13160 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
13161 }
13162 }
13163 }
13164 const slotFlag = hasDynamicSlots
13165 ? 2 /* DYNAMIC */
13166 : hasForwardedSlots(node.children)
13167 ? 3 /* FORWARDED */
13168 : 1 /* STABLE */;
13169 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
13170 // 2 = compiled but dynamic = can skip normalization, but must run diff
13171 // 1 = compiled and static = can skip normalization AND diff as optimized
13172 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
13173 if (dynamicSlots.length) {
13174 slots = createCallExpression(context.helper(CREATE_SLOTS), [
13175 slots,
13176 createArrayExpression(dynamicSlots)
13177 ]);
13178 }
13179 return {
13180 slots,
13181 hasDynamicSlots
13182 };
13183}
13184function buildDynamicSlot(name, fn) {
13185 return createObjectExpression([
13186 createObjectProperty(`name`, name),
13187 createObjectProperty(`fn`, fn)
13188 ]);
13189}
13190function hasForwardedSlots(children) {
13191 for (let i = 0; i < children.length; i++) {
13192 const child = children[i];
13193 switch (child.type) {
13194 case 1 /* ELEMENT */:
13195 if (child.tagType === 2 /* SLOT */ ||
13196 (child.tagType === 0 /* ELEMENT */ &&
13197 hasForwardedSlots(child.children))) {
13198 return true;
13199 }
13200 break;
13201 case 9 /* IF */:
13202 if (hasForwardedSlots(child.branches))
13203 return true;
13204 break;
13205 case 10 /* IF_BRANCH */:
13206 case 11 /* FOR */:
13207 if (hasForwardedSlots(child.children))
13208 return true;
13209 break;
13210 }
13211 }
13212 return false;
13213}
13214function isNonWhitespaceContent(node) {
13215 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
13216 return true;
13217 return node.type === 2 /* TEXT */
13218 ? !!node.content.trim()
13219 : isNonWhitespaceContent(node.content);
13220}
13221
13222// some directive transforms (e.g. v-model) may return a symbol for runtime
13223// import, which should be used instead of a resolveDirective call.
13224const directiveImportMap = new WeakMap();
13225// generate a JavaScript AST for this element's codegen
13226const transformElement = (node, context) => {
13227 // perform the work on exit, after all child expressions have been
13228 // processed and merged.
13229 return function postTransformElement() {
13230 node = context.currentNode;
13231 if (!(node.type === 1 /* ELEMENT */ &&
13232 (node.tagType === 0 /* ELEMENT */ ||
13233 node.tagType === 1 /* COMPONENT */))) {
13234 return;
13235 }
13236 const { tag, props } = node;
13237 const isComponent = node.tagType === 1 /* COMPONENT */;
13238 // The goal of the transform is to create a codegenNode implementing the
13239 // VNodeCall interface.
13240 let vnodeTag = isComponent
13241 ? resolveComponentType(node, context)
13242 : `"${tag}"`;
13243 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
13244 let vnodeProps;
13245 let vnodeChildren;
13246 let vnodePatchFlag;
13247 let patchFlag = 0;
13248 let vnodeDynamicProps;
13249 let dynamicPropNames;
13250 let vnodeDirectives;
13251 let shouldUseBlock =
13252 // dynamic component may resolve to plain elements
13253 isDynamicComponent ||
13254 vnodeTag === TELEPORT ||
13255 vnodeTag === SUSPENSE ||
13256 (!isComponent &&
13257 // <svg> and <foreignObject> must be forced into blocks so that block
13258 // updates inside get proper isSVG flag at runtime. (#639, #643)
13259 // This is technically web-specific, but splitting the logic out of core
13260 // leads to too much unnecessary complexity.
13261 (tag === 'svg' ||
13262 tag === 'foreignObject' ||
13263 // #938: elements with dynamic keys should be forced into blocks
13264 findProp(node, 'key', true)));
13265 // props
13266 if (props.length > 0) {
13267 const propsBuildResult = buildProps(node, context);
13268 vnodeProps = propsBuildResult.props;
13269 patchFlag = propsBuildResult.patchFlag;
13270 dynamicPropNames = propsBuildResult.dynamicPropNames;
13271 const directives = propsBuildResult.directives;
13272 vnodeDirectives =
13273 directives && directives.length
13274 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
13275 : undefined;
13276 }
13277 // children
13278 if (node.children.length > 0) {
13279 if (vnodeTag === KEEP_ALIVE) {
13280 // Although a built-in component, we compile KeepAlive with raw children
13281 // instead of slot functions so that it can be used inside Transition
13282 // or other Transition-wrapping HOCs.
13283 // To ensure correct updates with block optimizations, we need to:
13284 // 1. Force keep-alive into a block. This avoids its children being
13285 // collected by a parent block.
13286 shouldUseBlock = true;
13287 // 2. Force keep-alive to always be updated, since it uses raw children.
13288 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
13289 if (node.children.length > 1) {
13290 context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
13291 start: node.children[0].loc.start,
13292 end: node.children[node.children.length - 1].loc.end,
13293 source: ''
13294 }));
13295 }
13296 }
13297 const shouldBuildAsSlots = isComponent &&
13298 // Teleport is not a real component and has dedicated runtime handling
13299 vnodeTag !== TELEPORT &&
13300 // explained above.
13301 vnodeTag !== KEEP_ALIVE;
13302 if (shouldBuildAsSlots) {
13303 const { slots, hasDynamicSlots } = buildSlots(node, context);
13304 vnodeChildren = slots;
13305 if (hasDynamicSlots) {
13306 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
13307 }
13308 }
13309 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
13310 const child = node.children[0];
13311 const type = child.type;
13312 // check for dynamic text children
13313 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
13314 type === 8 /* COMPOUND_EXPRESSION */;
13315 if (hasDynamicTextChild &&
13316 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
13317 patchFlag |= 1 /* TEXT */;
13318 }
13319 // pass directly if the only child is a text node
13320 // (plain / interpolation / expression)
13321 if (hasDynamicTextChild || type === 2 /* TEXT */) {
13322 vnodeChildren = child;
13323 }
13324 else {
13325 vnodeChildren = node.children;
13326 }
13327 }
13328 else {
13329 vnodeChildren = node.children;
13330 }
13331 }
13332 // patchFlag & dynamicPropNames
13333 if (patchFlag !== 0) {
13334 {
13335 if (patchFlag < 0) {
13336 // special flags (negative and mutually exclusive)
13337 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
13338 }
13339 else {
13340 // bitwise flags
13341 const flagNames = Object.keys(PatchFlagNames)
13342 .map(Number)
13343 .filter(n => n > 0 && patchFlag & n)
13344 .map(n => PatchFlagNames[n])
13345 .join(`, `);
13346 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
13347 }
13348 }
13349 if (dynamicPropNames && dynamicPropNames.length) {
13350 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
13351 }
13352 }
13353 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);
13354 };
13355};
13356function resolveComponentType(node, context, ssr = false) {
13357 let { tag } = node;
13358 // 1. dynamic component
13359 const isExplicitDynamic = isComponentTag(tag);
13360 const isProp = findProp(node, 'is') || (!isExplicitDynamic && findDir(node, 'is'));
13361 if (isProp) {
13362 if (!isExplicitDynamic && isProp.type === 6 /* ATTRIBUTE */) {
13363 // <button is="vue:xxx">
13364 // if not <component>, only is value that starts with "vue:" will be
13365 // treated as component by the parse phase and reach here, unless it's
13366 // compat mode where all is values are considered components
13367 tag = isProp.value.content.replace(/^vue:/, '');
13368 }
13369 else {
13370 const exp = isProp.type === 6 /* ATTRIBUTE */
13371 ? isProp.value && createSimpleExpression(isProp.value.content, true)
13372 : isProp.exp;
13373 if (exp) {
13374 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
13375 exp
13376 ]);
13377 }
13378 }
13379 }
13380 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
13381 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
13382 if (builtIn) {
13383 // built-ins are simply fallthroughs / have special handling during ssr
13384 // so we don't need to import their runtime equivalents
13385 if (!ssr)
13386 context.helper(builtIn);
13387 return builtIn;
13388 }
13389 // 5. user component (resolve)
13390 context.helper(RESOLVE_COMPONENT);
13391 context.components.add(tag);
13392 return toValidAssetId(tag, `component`);
13393}
13394function buildProps(node, context, props = node.props, ssr = false) {
13395 const { tag, loc: elementLoc } = node;
13396 const isComponent = node.tagType === 1 /* COMPONENT */;
13397 let properties = [];
13398 const mergeArgs = [];
13399 const runtimeDirectives = [];
13400 // patchFlag analysis
13401 let patchFlag = 0;
13402 let hasRef = false;
13403 let hasClassBinding = false;
13404 let hasStyleBinding = false;
13405 let hasHydrationEventBinding = false;
13406 let hasDynamicKeys = false;
13407 let hasVnodeHook = false;
13408 const dynamicPropNames = [];
13409 const analyzePatchFlag = ({ key, value }) => {
13410 if (isStaticExp(key)) {
13411 const name = key.content;
13412 const isEventHandler = isOn(name);
13413 if (!isComponent &&
13414 isEventHandler &&
13415 // omit the flag for click handlers because hydration gives click
13416 // dedicated fast path.
13417 name.toLowerCase() !== 'onclick' &&
13418 // omit v-model handlers
13419 name !== 'onUpdate:modelValue' &&
13420 // omit onVnodeXXX hooks
13421 !isReservedProp(name)) {
13422 hasHydrationEventBinding = true;
13423 }
13424 if (isEventHandler && isReservedProp(name)) {
13425 hasVnodeHook = true;
13426 }
13427 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
13428 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
13429 value.type === 8 /* COMPOUND_EXPRESSION */) &&
13430 getConstantType(value, context) > 0)) {
13431 // skip if the prop is a cached handler or has constant value
13432 return;
13433 }
13434 if (name === 'ref') {
13435 hasRef = true;
13436 }
13437 else if (name === 'class' && !isComponent) {
13438 hasClassBinding = true;
13439 }
13440 else if (name === 'style' && !isComponent) {
13441 hasStyleBinding = true;
13442 }
13443 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
13444 dynamicPropNames.push(name);
13445 }
13446 }
13447 else {
13448 hasDynamicKeys = true;
13449 }
13450 };
13451 for (let i = 0; i < props.length; i++) {
13452 // static attribute
13453 const prop = props[i];
13454 if (prop.type === 6 /* ATTRIBUTE */) {
13455 const { loc, name, value } = prop;
13456 let isStatic = true;
13457 if (name === 'ref') {
13458 hasRef = true;
13459 }
13460 // skip is on <component>, or is="vue:xxx"
13461 if (name === 'is' &&
13462 (isComponentTag(tag) || (value && value.content.startsWith('vue:')))) {
13463 continue;
13464 }
13465 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
13466 }
13467 else {
13468 // directives
13469 const { name, arg, exp, loc } = prop;
13470 const isVBind = name === 'bind';
13471 const isVOn = name === 'on';
13472 // skip v-slot - it is handled by its dedicated transform.
13473 if (name === 'slot') {
13474 if (!isComponent) {
13475 context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));
13476 }
13477 continue;
13478 }
13479 // skip v-once - it is handled by its dedicated transform.
13480 if (name === 'once') {
13481 continue;
13482 }
13483 // skip v-is and :is on <component>
13484 if (name === 'is' ||
13485 (isVBind && isComponentTag(tag) && isBindKey(arg, 'is'))) {
13486 continue;
13487 }
13488 // skip v-on in SSR compilation
13489 if (isVOn && ssr) {
13490 continue;
13491 }
13492 // special case for v-bind and v-on with no argument
13493 if (!arg && (isVBind || isVOn)) {
13494 hasDynamicKeys = true;
13495 if (exp) {
13496 if (properties.length) {
13497 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
13498 properties = [];
13499 }
13500 if (isVBind) {
13501 mergeArgs.push(exp);
13502 }
13503 else {
13504 // v-on="obj" -> toHandlers(obj)
13505 mergeArgs.push({
13506 type: 14 /* JS_CALL_EXPRESSION */,
13507 loc,
13508 callee: context.helper(TO_HANDLERS),
13509 arguments: [exp]
13510 });
13511 }
13512 }
13513 else {
13514 context.onError(createCompilerError(isVBind
13515 ? 33 /* X_V_BIND_NO_EXPRESSION */
13516 : 34 /* X_V_ON_NO_EXPRESSION */, loc));
13517 }
13518 continue;
13519 }
13520 const directiveTransform = context.directiveTransforms[name];
13521 if (directiveTransform) {
13522 // has built-in directive transform.
13523 const { props, needRuntime } = directiveTransform(prop, node, context);
13524 !ssr && props.forEach(analyzePatchFlag);
13525 properties.push(...props);
13526 if (needRuntime) {
13527 runtimeDirectives.push(prop);
13528 if (isSymbol(needRuntime)) {
13529 directiveImportMap.set(prop, needRuntime);
13530 }
13531 }
13532 }
13533 else {
13534 // no built-in transform, this is a user custom directive.
13535 runtimeDirectives.push(prop);
13536 }
13537 }
13538 }
13539 let propsExpression = undefined;
13540 // has v-bind="object" or v-on="object", wrap with mergeProps
13541 if (mergeArgs.length) {
13542 if (properties.length) {
13543 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
13544 }
13545 if (mergeArgs.length > 1) {
13546 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
13547 }
13548 else {
13549 // single v-bind with nothing else - no need for a mergeProps call
13550 propsExpression = mergeArgs[0];
13551 }
13552 }
13553 else if (properties.length) {
13554 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
13555 }
13556 // patchFlag analysis
13557 if (hasDynamicKeys) {
13558 patchFlag |= 16 /* FULL_PROPS */;
13559 }
13560 else {
13561 if (hasClassBinding) {
13562 patchFlag |= 2 /* CLASS */;
13563 }
13564 if (hasStyleBinding) {
13565 patchFlag |= 4 /* STYLE */;
13566 }
13567 if (dynamicPropNames.length) {
13568 patchFlag |= 8 /* PROPS */;
13569 }
13570 if (hasHydrationEventBinding) {
13571 patchFlag |= 32 /* HYDRATE_EVENTS */;
13572 }
13573 }
13574 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
13575 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
13576 patchFlag |= 512 /* NEED_PATCH */;
13577 }
13578 return {
13579 props: propsExpression,
13580 directives: runtimeDirectives,
13581 patchFlag,
13582 dynamicPropNames
13583 };
13584}
13585// Dedupe props in an object literal.
13586// Literal duplicated attributes would have been warned during the parse phase,
13587// however, it's possible to encounter duplicated `onXXX` handlers with different
13588// modifiers. We also need to merge static and dynamic class / style attributes.
13589// - onXXX handlers / style: merge into array
13590// - class: merge into single expression with concatenation
13591function dedupeProperties(properties) {
13592 const knownProps = new Map();
13593 const deduped = [];
13594 for (let i = 0; i < properties.length; i++) {
13595 const prop = properties[i];
13596 // dynamic keys are always allowed
13597 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
13598 deduped.push(prop);
13599 continue;
13600 }
13601 const name = prop.key.content;
13602 const existing = knownProps.get(name);
13603 if (existing) {
13604 if (name === 'style' || name === 'class' || name.startsWith('on')) {
13605 mergeAsArray(existing, prop);
13606 }
13607 // unexpected duplicate, should have emitted error during parse
13608 }
13609 else {
13610 knownProps.set(name, prop);
13611 deduped.push(prop);
13612 }
13613 }
13614 return deduped;
13615}
13616function mergeAsArray(existing, incoming) {
13617 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
13618 existing.value.elements.push(incoming.value);
13619 }
13620 else {
13621 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
13622 }
13623}
13624function buildDirectiveArgs(dir, context) {
13625 const dirArgs = [];
13626 const runtime = directiveImportMap.get(dir);
13627 if (runtime) {
13628 // built-in directive with runtime
13629 dirArgs.push(context.helperString(runtime));
13630 }
13631 else {
13632 {
13633 // inject statement for resolving directive
13634 context.helper(RESOLVE_DIRECTIVE);
13635 context.directives.add(dir.name);
13636 dirArgs.push(toValidAssetId(dir.name, `directive`));
13637 }
13638 }
13639 const { loc } = dir;
13640 if (dir.exp)
13641 dirArgs.push(dir.exp);
13642 if (dir.arg) {
13643 if (!dir.exp) {
13644 dirArgs.push(`void 0`);
13645 }
13646 dirArgs.push(dir.arg);
13647 }
13648 if (Object.keys(dir.modifiers).length) {
13649 if (!dir.arg) {
13650 if (!dir.exp) {
13651 dirArgs.push(`void 0`);
13652 }
13653 dirArgs.push(`void 0`);
13654 }
13655 const trueExpression = createSimpleExpression(`true`, false, loc);
13656 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
13657 }
13658 return createArrayExpression(dirArgs, dir.loc);
13659}
13660function stringifyDynamicPropNames(props) {
13661 let propsNamesString = `[`;
13662 for (let i = 0, l = props.length; i < l; i++) {
13663 propsNamesString += JSON.stringify(props[i]);
13664 if (i < l - 1)
13665 propsNamesString += ', ';
13666 }
13667 return propsNamesString + `]`;
13668}
13669function isComponentTag(tag) {
13670 return tag[0].toLowerCase() + tag.slice(1) === 'component';
13671}
13672
13673const transformSlotOutlet = (node, context) => {
13674 if (isSlotOutlet(node)) {
13675 const { children, loc } = node;
13676 const { slotName, slotProps } = processSlotOutlet(node, context);
13677 const slotArgs = [
13678 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
13679 slotName
13680 ];
13681 if (slotProps) {
13682 slotArgs.push(slotProps);
13683 }
13684 if (children.length) {
13685 if (!slotProps) {
13686 slotArgs.push(`{}`);
13687 }
13688 slotArgs.push(createFunctionExpression([], children, false, false, loc));
13689 }
13690 if (context.scopeId && !context.slotted) {
13691 if (!slotProps) {
13692 slotArgs.push(`{}`);
13693 }
13694 if (!children.length) {
13695 slotArgs.push(`undefined`);
13696 }
13697 slotArgs.push(`true`);
13698 }
13699 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
13700 }
13701};
13702function processSlotOutlet(node, context) {
13703 let slotName = `"default"`;
13704 let slotProps = undefined;
13705 const nonNameProps = [];
13706 for (let i = 0; i < node.props.length; i++) {
13707 const p = node.props[i];
13708 if (p.type === 6 /* ATTRIBUTE */) {
13709 if (p.value) {
13710 if (p.name === 'name') {
13711 slotName = JSON.stringify(p.value.content);
13712 }
13713 else {
13714 p.name = camelize(p.name);
13715 nonNameProps.push(p);
13716 }
13717 }
13718 }
13719 else {
13720 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
13721 if (p.exp)
13722 slotName = p.exp;
13723 }
13724 else {
13725 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
13726 p.arg.content = camelize(p.arg.content);
13727 }
13728 nonNameProps.push(p);
13729 }
13730 }
13731 }
13732 if (nonNameProps.length > 0) {
13733 const { props, directives } = buildProps(node, context, nonNameProps);
13734 slotProps = props;
13735 if (directives.length) {
13736 context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
13737 }
13738 }
13739 return {
13740 slotName,
13741 slotProps
13742 };
13743}
13744
13745const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;
13746const transformOn = (dir, node, context, augmentor) => {
13747 const { loc, modifiers, arg } = dir;
13748 if (!dir.exp && !modifiers.length) {
13749 context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));
13750 }
13751 let eventName;
13752 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13753 if (arg.isStatic) {
13754 const rawName = arg.content;
13755 // for all event listeners, auto convert it to camelCase. See issue #2249
13756 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
13757 }
13758 else {
13759 // #2388
13760 eventName = createCompoundExpression([
13761 `${context.helperString(TO_HANDLER_KEY)}(`,
13762 arg,
13763 `)`
13764 ]);
13765 }
13766 }
13767 else {
13768 // already a compound expression.
13769 eventName = arg;
13770 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
13771 eventName.children.push(`)`);
13772 }
13773 // handler processing
13774 let exp = dir.exp;
13775 if (exp && !exp.content.trim()) {
13776 exp = undefined;
13777 }
13778 let shouldCache = context.cacheHandlers && !exp;
13779 if (exp) {
13780 const isMemberExp = isMemberExpression(exp.content);
13781 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
13782 const hasMultipleStatements = exp.content.includes(`;`);
13783 {
13784 validateBrowserExpression(exp, context, false, hasMultipleStatements);
13785 }
13786 if (isInlineStatement || (shouldCache && isMemberExp)) {
13787 // wrap inline statement in a function expression
13788 exp = createCompoundExpression([
13789 `${isInlineStatement
13790 ? `$event`
13791 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
13792 exp,
13793 hasMultipleStatements ? `}` : `)`
13794 ]);
13795 }
13796 }
13797 let ret = {
13798 props: [
13799 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
13800 ]
13801 };
13802 // apply extended compiler augmentor
13803 if (augmentor) {
13804 ret = augmentor(ret);
13805 }
13806 if (shouldCache) {
13807 // cache handlers so that it's always the same handler being passed down.
13808 // this avoids unnecessary re-renders when users use inline handlers on
13809 // components.
13810 ret.props[0].value = context.cache(ret.props[0].value);
13811 }
13812 return ret;
13813};
13814
13815// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
13816// codegen for the entire props object. This transform here is only for v-bind
13817// *with* args.
13818const transformBind = (dir, _node, context) => {
13819 const { exp, modifiers, loc } = dir;
13820 const arg = dir.arg;
13821 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
13822 arg.children.unshift(`(`);
13823 arg.children.push(`) || ""`);
13824 }
13825 else if (!arg.isStatic) {
13826 arg.content = `${arg.content} || ""`;
13827 }
13828 // .prop is no longer necessary due to new patch behavior
13829 // .sync is replaced by v-model:arg
13830 if (modifiers.includes('camel')) {
13831 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13832 if (arg.isStatic) {
13833 arg.content = camelize(arg.content);
13834 }
13835 else {
13836 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
13837 }
13838 }
13839 else {
13840 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
13841 arg.children.push(`)`);
13842 }
13843 }
13844 if (!exp ||
13845 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
13846 context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));
13847 return {
13848 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
13849 };
13850 }
13851 return {
13852 props: [createObjectProperty(arg, exp)]
13853 };
13854};
13855
13856// Merge adjacent text nodes and expressions into a single expression
13857// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
13858const transformText = (node, context) => {
13859 if (node.type === 0 /* ROOT */ ||
13860 node.type === 1 /* ELEMENT */ ||
13861 node.type === 11 /* FOR */ ||
13862 node.type === 10 /* IF_BRANCH */) {
13863 // perform the transform on node exit so that all expressions have already
13864 // been processed.
13865 return () => {
13866 const children = node.children;
13867 let currentContainer = undefined;
13868 let hasText = false;
13869 for (let i = 0; i < children.length; i++) {
13870 const child = children[i];
13871 if (isText(child)) {
13872 hasText = true;
13873 for (let j = i + 1; j < children.length; j++) {
13874 const next = children[j];
13875 if (isText(next)) {
13876 if (!currentContainer) {
13877 currentContainer = children[i] = {
13878 type: 8 /* COMPOUND_EXPRESSION */,
13879 loc: child.loc,
13880 children: [child]
13881 };
13882 }
13883 // merge adjacent text node into current
13884 currentContainer.children.push(` + `, next);
13885 children.splice(j, 1);
13886 j--;
13887 }
13888 else {
13889 currentContainer = undefined;
13890 break;
13891 }
13892 }
13893 }
13894 }
13895 if (!hasText ||
13896 // if this is a plain element with a single text child, leave it
13897 // as-is since the runtime has dedicated fast path for this by directly
13898 // setting textContent of the element.
13899 // for component root it's always normalized anyway.
13900 (children.length === 1 &&
13901 (node.type === 0 /* ROOT */ ||
13902 (node.type === 1 /* ELEMENT */ &&
13903 node.tagType === 0 /* ELEMENT */ &&
13904 // #3756
13905 // custom directives can potentially add DOM elements arbitrarily,
13906 // we need to avoid setting textContent of the element at runtime
13907 // to avoid accidentally overwriting the DOM elements added
13908 // by the user through custom directives.
13909 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
13910 !context.directiveTransforms[p.name]) &&
13911 // in compat mode, <template> tags with no special directives
13912 // will be rendered as a fragment so its children must be
13913 // converted into vnodes.
13914 !(false ))))) {
13915 return;
13916 }
13917 // pre-convert text nodes into createTextVNode(text) calls to avoid
13918 // runtime normalization.
13919 for (let i = 0; i < children.length; i++) {
13920 const child = children[i];
13921 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
13922 const callArgs = [];
13923 // createTextVNode defaults to single whitespace, so if it is a
13924 // single space the code could be an empty call to save bytes.
13925 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
13926 callArgs.push(child);
13927 }
13928 // mark dynamic text with flag so it gets patched inside a block
13929 if (!context.ssr &&
13930 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
13931 callArgs.push(1 /* TEXT */ +
13932 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
13933 }
13934 children[i] = {
13935 type: 12 /* TEXT_CALL */,
13936 content: child,
13937 loc: child.loc,
13938 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
13939 };
13940 }
13941 }
13942 };
13943 }
13944};
13945
13946const seen = new WeakSet();
13947const transformOnce = (node, context) => {
13948 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
13949 if (seen.has(node)) {
13950 return;
13951 }
13952 seen.add(node);
13953 context.helper(SET_BLOCK_TRACKING);
13954 return () => {
13955 const cur = context.currentNode;
13956 if (cur.codegenNode) {
13957 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
13958 }
13959 };
13960 }
13961};
13962
13963const transformModel = (dir, node, context) => {
13964 const { exp, arg } = dir;
13965 if (!exp) {
13966 context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
13967 return createTransformProps();
13968 }
13969 const rawExp = exp.loc.source;
13970 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
13971 // im SFC <script setup> inline mode, the exp may have been transformed into
13972 // _unref(exp)
13973 context.bindingMetadata[rawExp];
13974 const maybeRef = !true /* SETUP_CONST */;
13975 if (!isMemberExpression(expString) && !maybeRef) {
13976 context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
13977 return createTransformProps();
13978 }
13979 const propName = arg ? arg : createSimpleExpression('modelValue', true);
13980 const eventName = arg
13981 ? isStaticExp(arg)
13982 ? `onUpdate:${arg.content}`
13983 : createCompoundExpression(['"onUpdate:" + ', arg])
13984 : `onUpdate:modelValue`;
13985 let assignmentExp;
13986 const eventArg = context.isTS ? `($event: any)` : `$event`;
13987 {
13988 assignmentExp = createCompoundExpression([
13989 `${eventArg} => (`,
13990 exp,
13991 ` = $event)`
13992 ]);
13993 }
13994 const props = [
13995 // modelValue: foo
13996 createObjectProperty(propName, dir.exp),
13997 // "onUpdate:modelValue": $event => (foo = $event)
13998 createObjectProperty(eventName, assignmentExp)
13999 ];
14000 // modelModifiers: { foo: true, "bar-baz": true }
14001 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
14002 const modifiers = dir.modifiers
14003 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
14004 .join(`, `);
14005 const modifiersKey = arg
14006 ? isStaticExp(arg)
14007 ? `${arg.content}Modifiers`
14008 : createCompoundExpression([arg, ' + "Modifiers"'])
14009 : `modelModifiers`;
14010 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
14011 }
14012 return createTransformProps(props);
14013};
14014function createTransformProps(props = []) {
14015 return { props };
14016}
14017
14018function getBaseTransformPreset(prefixIdentifiers) {
14019 return [
14020 [
14021 transformOnce,
14022 transformIf,
14023 transformFor,
14024 ...([]),
14025 ...([transformExpression]
14026 ),
14027 transformSlotOutlet,
14028 transformElement,
14029 trackSlotScopes,
14030 transformText
14031 ],
14032 {
14033 on: transformOn,
14034 bind: transformBind,
14035 model: transformModel
14036 }
14037 ];
14038}
14039// we name it `baseCompile` so that higher order compilers like
14040// @vue/compiler-dom can export `compile` while re-exporting everything else.
14041function baseCompile(template, options = {}) {
14042 const onError = options.onError || defaultOnError;
14043 const isModuleMode = options.mode === 'module';
14044 /* istanbul ignore if */
14045 {
14046 if (options.prefixIdentifiers === true) {
14047 onError(createCompilerError(45 /* X_PREFIX_ID_NOT_SUPPORTED */));
14048 }
14049 else if (isModuleMode) {
14050 onError(createCompilerError(46 /* X_MODULE_MODE_NOT_SUPPORTED */));
14051 }
14052 }
14053 const prefixIdentifiers = !true ;
14054 if (options.cacheHandlers) {
14055 onError(createCompilerError(47 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
14056 }
14057 if (options.scopeId && !isModuleMode) {
14058 onError(createCompilerError(48 /* X_SCOPE_ID_NOT_SUPPORTED */));
14059 }
14060 const ast = isString(template) ? baseParse(template, options) : template;
14061 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
14062 transform(ast, extend({}, options, {
14063 prefixIdentifiers,
14064 nodeTransforms: [
14065 ...nodeTransforms,
14066 ...(options.nodeTransforms || []) // user transforms
14067 ],
14068 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
14069 )
14070 }));
14071 return generate(ast, extend({}, options, {
14072 prefixIdentifiers
14073 }));
14074}
14075
14076const noopDirectiveTransform = () => ({ props: [] });
14077
14078const V_MODEL_RADIO = Symbol(`vModelRadio` );
14079const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
14080const V_MODEL_TEXT = Symbol(`vModelText` );
14081const V_MODEL_SELECT = Symbol(`vModelSelect` );
14082const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
14083const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
14084const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
14085const V_SHOW = Symbol(`vShow` );
14086const TRANSITION$1 = Symbol(`Transition` );
14087const TRANSITION_GROUP = Symbol(`TransitionGroup` );
14088registerRuntimeHelpers({
14089 [V_MODEL_RADIO]: `vModelRadio`,
14090 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
14091 [V_MODEL_TEXT]: `vModelText`,
14092 [V_MODEL_SELECT]: `vModelSelect`,
14093 [V_MODEL_DYNAMIC]: `vModelDynamic`,
14094 [V_ON_WITH_MODIFIERS]: `withModifiers`,
14095 [V_ON_WITH_KEYS]: `withKeys`,
14096 [V_SHOW]: `vShow`,
14097 [TRANSITION$1]: `Transition`,
14098 [TRANSITION_GROUP]: `TransitionGroup`
14099});
14100
14101/* eslint-disable no-restricted-globals */
14102let decoder;
14103function decodeHtmlBrowser(raw, asAttr = false) {
14104 if (!decoder) {
14105 decoder = document.createElement('div');
14106 }
14107 if (asAttr) {
14108 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
14109 return decoder.children[0].getAttribute('foo');
14110 }
14111 else {
14112 decoder.innerHTML = raw;
14113 return decoder.textContent;
14114 }
14115}
14116
14117const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
14118const parserOptions = {
14119 isVoidTag,
14120 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
14121 isPreTag: tag => tag === 'pre',
14122 decodeEntities: decodeHtmlBrowser ,
14123 isBuiltInComponent: (tag) => {
14124 if (isBuiltInType(tag, `Transition`)) {
14125 return TRANSITION$1;
14126 }
14127 else if (isBuiltInType(tag, `TransitionGroup`)) {
14128 return TRANSITION_GROUP;
14129 }
14130 },
14131 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
14132 getNamespace(tag, parent) {
14133 let ns = parent ? parent.ns : 0 /* HTML */;
14134 if (parent && ns === 2 /* MATH_ML */) {
14135 if (parent.tag === 'annotation-xml') {
14136 if (tag === 'svg') {
14137 return 1 /* SVG */;
14138 }
14139 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
14140 a.name === 'encoding' &&
14141 a.value != null &&
14142 (a.value.content === 'text/html' ||
14143 a.value.content === 'application/xhtml+xml'))) {
14144 ns = 0 /* HTML */;
14145 }
14146 }
14147 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
14148 tag !== 'mglyph' &&
14149 tag !== 'malignmark') {
14150 ns = 0 /* HTML */;
14151 }
14152 }
14153 else if (parent && ns === 1 /* SVG */) {
14154 if (parent.tag === 'foreignObject' ||
14155 parent.tag === 'desc' ||
14156 parent.tag === 'title') {
14157 ns = 0 /* HTML */;
14158 }
14159 }
14160 if (ns === 0 /* HTML */) {
14161 if (tag === 'svg') {
14162 return 1 /* SVG */;
14163 }
14164 if (tag === 'math') {
14165 return 2 /* MATH_ML */;
14166 }
14167 }
14168 return ns;
14169 },
14170 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
14171 getTextMode({ tag, ns }) {
14172 if (ns === 0 /* HTML */) {
14173 if (tag === 'textarea' || tag === 'title') {
14174 return 1 /* RCDATA */;
14175 }
14176 if (isRawTextContainer(tag)) {
14177 return 2 /* RAWTEXT */;
14178 }
14179 }
14180 return 0 /* DATA */;
14181 }
14182};
14183
14184// Parse inline CSS strings for static style attributes into an object.
14185// This is a NodeTransform since it works on the static `style` attribute and
14186// converts it into a dynamic equivalent:
14187// style="color: red" -> :style='{ "color": "red" }'
14188// It is then processed by `transformElement` and included in the generated
14189// props.
14190const transformStyle = node => {
14191 if (node.type === 1 /* ELEMENT */) {
14192 node.props.forEach((p, i) => {
14193 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
14194 // replace p with an expression node
14195 node.props[i] = {
14196 type: 7 /* DIRECTIVE */,
14197 name: `bind`,
14198 arg: createSimpleExpression(`style`, true, p.loc),
14199 exp: parseInlineCSS(p.value.content, p.loc),
14200 modifiers: [],
14201 loc: p.loc
14202 };
14203 }
14204 });
14205 }
14206};
14207const parseInlineCSS = (cssText, loc) => {
14208 const normalized = parseStringStyle(cssText);
14209 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
14210};
14211
14212function createDOMCompilerError(code, loc) {
14213 return createCompilerError(code, loc, DOMErrorMessages );
14214}
14215const DOMErrorMessages = {
14216 [49 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
14217 [50 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
14218 [51 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
14219 [52 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
14220 [53 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
14221 [54 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
14222 [55 /* 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.`,
14223 [56 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
14224 [57 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
14225 [58 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
14226 [59 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
14227};
14228
14229const transformVHtml = (dir, node, context) => {
14230 const { exp, loc } = dir;
14231 if (!exp) {
14232 context.onError(createDOMCompilerError(49 /* X_V_HTML_NO_EXPRESSION */, loc));
14233 }
14234 if (node.children.length) {
14235 context.onError(createDOMCompilerError(50 /* X_V_HTML_WITH_CHILDREN */, loc));
14236 node.children.length = 0;
14237 }
14238 return {
14239 props: [
14240 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
14241 ]
14242 };
14243};
14244
14245const transformVText = (dir, node, context) => {
14246 const { exp, loc } = dir;
14247 if (!exp) {
14248 context.onError(createDOMCompilerError(51 /* X_V_TEXT_NO_EXPRESSION */, loc));
14249 }
14250 if (node.children.length) {
14251 context.onError(createDOMCompilerError(52 /* X_V_TEXT_WITH_CHILDREN */, loc));
14252 node.children.length = 0;
14253 }
14254 return {
14255 props: [
14256 createObjectProperty(createSimpleExpression(`textContent`, true), exp
14257 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
14258 : createSimpleExpression('', true))
14259 ]
14260 };
14261};
14262
14263const transformModel$1 = (dir, node, context) => {
14264 const baseResult = transformModel(dir, node, context);
14265 // base transform has errors OR component v-model (only need props)
14266 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
14267 return baseResult;
14268 }
14269 if (dir.arg) {
14270 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
14271 }
14272 function checkDuplicatedValue() {
14273 const value = findProp(node, 'value');
14274 if (value) {
14275 context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
14276 }
14277 }
14278 const { tag } = node;
14279 const isCustomElement = context.isCustomElement(tag);
14280 if (tag === 'input' ||
14281 tag === 'textarea' ||
14282 tag === 'select' ||
14283 isCustomElement) {
14284 let directiveToUse = V_MODEL_TEXT;
14285 let isInvalidType = false;
14286 if (tag === 'input' || isCustomElement) {
14287 const type = findProp(node, `type`);
14288 if (type) {
14289 if (type.type === 7 /* DIRECTIVE */) {
14290 // :type="foo"
14291 directiveToUse = V_MODEL_DYNAMIC;
14292 }
14293 else if (type.value) {
14294 switch (type.value.content) {
14295 case 'radio':
14296 directiveToUse = V_MODEL_RADIO;
14297 break;
14298 case 'checkbox':
14299 directiveToUse = V_MODEL_CHECKBOX;
14300 break;
14301 case 'file':
14302 isInvalidType = true;
14303 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
14304 break;
14305 default:
14306 // text type
14307 checkDuplicatedValue();
14308 break;
14309 }
14310 }
14311 }
14312 else if (hasDynamicKeyVBind(node)) {
14313 // element has bindings with dynamic keys, which can possibly contain
14314 // "type".
14315 directiveToUse = V_MODEL_DYNAMIC;
14316 }
14317 else {
14318 // text type
14319 checkDuplicatedValue();
14320 }
14321 }
14322 else if (tag === 'select') {
14323 directiveToUse = V_MODEL_SELECT;
14324 }
14325 else {
14326 // textarea
14327 checkDuplicatedValue();
14328 }
14329 // inject runtime directive
14330 // by returning the helper symbol via needRuntime
14331 // the import will replaced a resolveDirective call.
14332 if (!isInvalidType) {
14333 baseResult.needRuntime = context.helper(directiveToUse);
14334 }
14335 }
14336 else {
14337 context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
14338 }
14339 // native vmodel doesn't need the `modelValue` props since they are also
14340 // passed to the runtime as `binding.value`. removing it reduces code size.
14341 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
14342 p.key.content === 'modelValue'));
14343 return baseResult;
14344};
14345
14346const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
14347const isNonKeyModifier = /*#__PURE__*/ makeMap(
14348// event propagation management
14349`stop,prevent,self,` +
14350 // system modifiers + exact
14351 `ctrl,shift,alt,meta,exact,` +
14352 // mouse
14353 `middle`);
14354// left & right could be mouse or key modifiers based on event type
14355const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
14356const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
14357const resolveModifiers = (key, modifiers, context, loc) => {
14358 const keyModifiers = [];
14359 const nonKeyModifiers = [];
14360 const eventOptionModifiers = [];
14361 for (let i = 0; i < modifiers.length; i++) {
14362 const modifier = modifiers[i];
14363 if (isEventOptionModifier(modifier)) {
14364 // eventOptionModifiers: modifiers for addEventListener() options,
14365 // e.g. .passive & .capture
14366 eventOptionModifiers.push(modifier);
14367 }
14368 else {
14369 // runtimeModifiers: modifiers that needs runtime guards
14370 if (maybeKeyModifier(modifier)) {
14371 if (isStaticExp(key)) {
14372 if (isKeyboardEvent(key.content)) {
14373 keyModifiers.push(modifier);
14374 }
14375 else {
14376 nonKeyModifiers.push(modifier);
14377 }
14378 }
14379 else {
14380 keyModifiers.push(modifier);
14381 nonKeyModifiers.push(modifier);
14382 }
14383 }
14384 else {
14385 if (isNonKeyModifier(modifier)) {
14386 nonKeyModifiers.push(modifier);
14387 }
14388 else {
14389 keyModifiers.push(modifier);
14390 }
14391 }
14392 }
14393 }
14394 return {
14395 keyModifiers,
14396 nonKeyModifiers,
14397 eventOptionModifiers
14398 };
14399};
14400const transformClick = (key, event) => {
14401 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
14402 return isStaticClick
14403 ? createSimpleExpression(event, true)
14404 : key.type !== 4 /* SIMPLE_EXPRESSION */
14405 ? createCompoundExpression([
14406 `(`,
14407 key,
14408 `) === "onClick" ? "${event}" : (`,
14409 key,
14410 `)`
14411 ])
14412 : key;
14413};
14414const transformOn$1 = (dir, node, context) => {
14415 return transformOn(dir, node, context, baseResult => {
14416 const { modifiers } = dir;
14417 if (!modifiers.length)
14418 return baseResult;
14419 let { key, value: handlerExp } = baseResult.props[0];
14420 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
14421 // normalize click.right and click.middle since they don't actually fire
14422 if (nonKeyModifiers.includes('right')) {
14423 key = transformClick(key, `onContextmenu`);
14424 }
14425 if (nonKeyModifiers.includes('middle')) {
14426 key = transformClick(key, `onMouseup`);
14427 }
14428 if (nonKeyModifiers.length) {
14429 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
14430 handlerExp,
14431 JSON.stringify(nonKeyModifiers)
14432 ]);
14433 }
14434 if (keyModifiers.length &&
14435 // if event name is dynamic, always wrap with keys guard
14436 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
14437 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
14438 handlerExp,
14439 JSON.stringify(keyModifiers)
14440 ]);
14441 }
14442 if (eventOptionModifiers.length) {
14443 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
14444 key = isStaticExp(key)
14445 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
14446 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
14447 }
14448 return {
14449 props: [createObjectProperty(key, handlerExp)]
14450 };
14451 });
14452};
14453
14454const transformShow = (dir, node, context) => {
14455 const { exp, loc } = dir;
14456 if (!exp) {
14457 context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */, loc));
14458 }
14459 return {
14460 props: [],
14461 needRuntime: context.helper(V_SHOW)
14462 };
14463};
14464
14465const warnTransitionChildren = (node, context) => {
14466 if (node.type === 1 /* ELEMENT */ &&
14467 node.tagType === 1 /* COMPONENT */) {
14468 const component = context.isBuiltInComponent(node.tag);
14469 if (component === TRANSITION$1) {
14470 return () => {
14471 if (node.children.length && hasMultipleChildren(node)) {
14472 context.onError(createDOMCompilerError(58 /* X_TRANSITION_INVALID_CHILDREN */, {
14473 start: node.children[0].loc.start,
14474 end: node.children[node.children.length - 1].loc.end,
14475 source: ''
14476 }));
14477 }
14478 };
14479 }
14480 }
14481};
14482function hasMultipleChildren(node) {
14483 // #1352 filter out potential comment nodes.
14484 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */));
14485 const child = children[0];
14486 return (children.length !== 1 ||
14487 child.type === 11 /* FOR */ ||
14488 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
14489}
14490
14491const ignoreSideEffectTags = (node, context) => {
14492 if (node.type === 1 /* ELEMENT */ &&
14493 node.tagType === 0 /* ELEMENT */ &&
14494 (node.tag === 'script' || node.tag === 'style')) {
14495 context.onError(createDOMCompilerError(59 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
14496 context.removeNode();
14497 }
14498};
14499
14500const DOMNodeTransforms = [
14501 transformStyle,
14502 ...([warnTransitionChildren] )
14503];
14504const DOMDirectiveTransforms = {
14505 cloak: noopDirectiveTransform,
14506 html: transformVHtml,
14507 text: transformVText,
14508 model: transformModel$1,
14509 on: transformOn$1,
14510 show: transformShow
14511};
14512function compile$1(template, options = {}) {
14513 return baseCompile(template, extend({}, parserOptions, options, {
14514 nodeTransforms: [
14515 // ignore <script> and <tag>
14516 // this is not put inside DOMNodeTransforms because that list is used
14517 // by compiler-ssr to generate vnode fallback branches
14518 ignoreSideEffectTags,
14519 ...DOMNodeTransforms,
14520 ...(options.nodeTransforms || [])
14521 ],
14522 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
14523 transformHoist: null
14524 }));
14525}
14526
14527// This entry is the "full-build" that includes both the runtime
14528{
14529 initDev();
14530}
14531const compileCache = Object.create(null);
14532function compileToFunction(template, options) {
14533 if (!isString(template)) {
14534 if (template.nodeType) {
14535 template = template.innerHTML;
14536 }
14537 else {
14538 warn(`invalid template option: `, template);
14539 return NOOP;
14540 }
14541 }
14542 const key = template;
14543 const cached = compileCache[key];
14544 if (cached) {
14545 return cached;
14546 }
14547 if (template[0] === '#') {
14548 const el = document.querySelector(template);
14549 if (!el) {
14550 warn(`Template element not found or is empty: ${template}`);
14551 }
14552 // __UNSAFE__
14553 // Reason: potential execution of JS expressions in in-DOM template.
14554 // The user must make sure the in-DOM template is trusted. If it's rendered
14555 // by the server, the template should not contain any user data.
14556 template = el ? el.innerHTML : ``;
14557 }
14558 const { code } = compile$1(template, extend({
14559 hoistStatic: true,
14560 onError: onError ,
14561 onWarn: e => onError(e, true)
14562 }, options));
14563 function onError(err, asWarning = false) {
14564 const message = asWarning
14565 ? err.message
14566 : `Template compilation error: ${err.message}`;
14567 const codeFrame = err.loc &&
14568 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
14569 warn(codeFrame ? `${message}\n${codeFrame}` : message);
14570 }
14571 // The wildcard import results in a huge object with every export
14572 // with keys that cannot be mangled, and can be quite heavy size-wise.
14573 // In the global build we know `Vue` is available globally so we can avoid
14574 // the wildcard object.
14575 const render = (new Function('Vue', code)(runtimeDom));
14576 render._rc = true;
14577 return (compileCache[key] = render);
14578}
14579registerRuntimeCompiler(compileToFunction);
14580
14581export { BaseTransition, Comment$1 as Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, Transition, TransitionGroup, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compileToFunction as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createHydrationRenderer, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineEmit, defineProps, devtools, getCurrentInstance, getTransitionRawChildren, h, handleError, hydrate, initCustomFormatter, inject, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, 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, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useContext, useCssModule, useCssVars, useSSRContext, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers, withScopeId };