UNPKG

530 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 options.scheduler ? undefined : 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)
618 ? builtInSymbols.has(key)
619 : isNonTrackableKeys(key)) {
620 return res;
621 }
622 if (!isReadonly) {
623 track(target, "get" /* GET */, key);
624 }
625 if (shallow) {
626 return res;
627 }
628 if (isRef(res)) {
629 // ref unwrapping - does not apply for Array + integer key.
630 const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
631 return shouldUnwrap ? res.value : res;
632 }
633 if (isObject(res)) {
634 // Convert returned value into a proxy as well. we do the isObject check
635 // here to avoid invalid value warning. Also need to lazy access readonly
636 // and reactive here to avoid circular dependency.
637 return isReadonly ? readonly(res) : reactive(res);
638 }
639 return res;
640 };
641}
642const set = /*#__PURE__*/ createSetter();
643const shallowSet = /*#__PURE__*/ createSetter(true);
644function createSetter(shallow = false) {
645 return function set(target, key, value, receiver) {
646 let oldValue = target[key];
647 if (!shallow) {
648 value = toRaw(value);
649 oldValue = toRaw(oldValue);
650 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
651 oldValue.value = value;
652 return true;
653 }
654 }
655 const hadKey = isArray(target) && isIntegerKey(key)
656 ? Number(key) < target.length
657 : hasOwn(target, key);
658 const result = Reflect.set(target, key, value, receiver);
659 // don't trigger if target is something up in the prototype chain of original
660 if (target === toRaw(receiver)) {
661 if (!hadKey) {
662 trigger(target, "add" /* ADD */, key, value);
663 }
664 else if (hasChanged(value, oldValue)) {
665 trigger(target, "set" /* SET */, key, value, oldValue);
666 }
667 }
668 return result;
669 };
670}
671function deleteProperty(target, key) {
672 const hadKey = hasOwn(target, key);
673 const oldValue = target[key];
674 const result = Reflect.deleteProperty(target, key);
675 if (result && hadKey) {
676 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
677 }
678 return result;
679}
680function has(target, key) {
681 const result = Reflect.has(target, key);
682 if (!isSymbol(key) || !builtInSymbols.has(key)) {
683 track(target, "has" /* HAS */, key);
684 }
685 return result;
686}
687function ownKeys(target) {
688 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
689 return Reflect.ownKeys(target);
690}
691const mutableHandlers = {
692 get,
693 set,
694 deleteProperty,
695 has,
696 ownKeys
697};
698const readonlyHandlers = {
699 get: readonlyGet,
700 set(target, key) {
701 {
702 console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
703 }
704 return true;
705 },
706 deleteProperty(target, key) {
707 {
708 console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
709 }
710 return true;
711 }
712};
713const shallowReactiveHandlers = extend({}, mutableHandlers, {
714 get: shallowGet,
715 set: shallowSet
716});
717// Props handlers are special in the sense that it should not unwrap top-level
718// refs (in order to allow refs to be explicitly passed down), but should
719// retain the reactivity of the normal readonly object.
720const shallowReadonlyHandlers = extend({}, readonlyHandlers, {
721 get: shallowReadonlyGet
722});
723
724const toReactive = (value) => isObject(value) ? reactive(value) : value;
725const toReadonly = (value) => isObject(value) ? readonly(value) : value;
726const toShallow = (value) => value;
727const getProto = (v) => Reflect.getPrototypeOf(v);
728function get$1(target, key, isReadonly = false, isShallow = false) {
729 // #1772: readonly(reactive(Map)) should return readonly + reactive version
730 // of the value
731 target = target["__v_raw" /* RAW */];
732 const rawTarget = toRaw(target);
733 const rawKey = toRaw(key);
734 if (key !== rawKey) {
735 !isReadonly && track(rawTarget, "get" /* GET */, key);
736 }
737 !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
738 const { has } = getProto(rawTarget);
739 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
740 if (has.call(rawTarget, key)) {
741 return wrap(target.get(key));
742 }
743 else if (has.call(rawTarget, rawKey)) {
744 return wrap(target.get(rawKey));
745 }
746}
747function has$1(key, isReadonly = false) {
748 const target = this["__v_raw" /* RAW */];
749 const rawTarget = toRaw(target);
750 const rawKey = toRaw(key);
751 if (key !== rawKey) {
752 !isReadonly && track(rawTarget, "has" /* HAS */, key);
753 }
754 !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
755 return key === rawKey
756 ? target.has(key)
757 : target.has(key) || target.has(rawKey);
758}
759function size(target, isReadonly = false) {
760 target = target["__v_raw" /* RAW */];
761 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
762 return Reflect.get(target, 'size', target);
763}
764function add(value) {
765 value = toRaw(value);
766 const target = toRaw(this);
767 const proto = getProto(target);
768 const hadKey = proto.has.call(target, value);
769 if (!hadKey) {
770 target.add(value);
771 trigger(target, "add" /* ADD */, value, value);
772 }
773 return this;
774}
775function set$1(key, value) {
776 value = toRaw(value);
777 const target = toRaw(this);
778 const { has, get } = getProto(target);
779 let hadKey = has.call(target, key);
780 if (!hadKey) {
781 key = toRaw(key);
782 hadKey = has.call(target, key);
783 }
784 else {
785 checkIdentityKeys(target, has, key);
786 }
787 const oldValue = get.call(target, key);
788 target.set(key, value);
789 if (!hadKey) {
790 trigger(target, "add" /* ADD */, key, value);
791 }
792 else if (hasChanged(value, oldValue)) {
793 trigger(target, "set" /* SET */, key, value, oldValue);
794 }
795 return this;
796}
797function deleteEntry(key) {
798 const target = toRaw(this);
799 const { has, get } = getProto(target);
800 let hadKey = has.call(target, key);
801 if (!hadKey) {
802 key = toRaw(key);
803 hadKey = has.call(target, key);
804 }
805 else {
806 checkIdentityKeys(target, has, key);
807 }
808 const oldValue = get ? get.call(target, key) : undefined;
809 // forward the operation before queueing reactions
810 const result = target.delete(key);
811 if (hadKey) {
812 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
813 }
814 return result;
815}
816function clear() {
817 const target = toRaw(this);
818 const hadItems = target.size !== 0;
819 const oldTarget = isMap(target)
820 ? new Map(target)
821 : new Set(target)
822 ;
823 // forward the operation before queueing reactions
824 const result = target.clear();
825 if (hadItems) {
826 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
827 }
828 return result;
829}
830function createForEach(isReadonly, isShallow) {
831 return function forEach(callback, thisArg) {
832 const observed = this;
833 const target = observed["__v_raw" /* RAW */];
834 const rawTarget = toRaw(target);
835 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
836 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
837 return target.forEach((value, key) => {
838 // important: make sure the callback is
839 // 1. invoked with the reactive map as `this` and 3rd arg
840 // 2. the value received should be a corresponding reactive/readonly.
841 return callback.call(thisArg, wrap(value), wrap(key), observed);
842 });
843 };
844}
845function createIterableMethod(method, isReadonly, isShallow) {
846 return function (...args) {
847 const target = this["__v_raw" /* RAW */];
848 const rawTarget = toRaw(target);
849 const targetIsMap = isMap(rawTarget);
850 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
851 const isKeyOnly = method === 'keys' && targetIsMap;
852 const innerIterator = target[method](...args);
853 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
854 !isReadonly &&
855 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
856 // return a wrapped iterator which returns observed versions of the
857 // values emitted from the real iterator
858 return {
859 // iterator protocol
860 next() {
861 const { value, done } = innerIterator.next();
862 return done
863 ? { value, done }
864 : {
865 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
866 done
867 };
868 },
869 // iterable protocol
870 [Symbol.iterator]() {
871 return this;
872 }
873 };
874 };
875}
876function createReadonlyMethod(type) {
877 return function (...args) {
878 {
879 const key = args[0] ? `on key "${args[0]}" ` : ``;
880 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
881 }
882 return type === "delete" /* DELETE */ ? false : this;
883 };
884}
885const mutableInstrumentations = {
886 get(key) {
887 return get$1(this, key);
888 },
889 get size() {
890 return size(this);
891 },
892 has: has$1,
893 add,
894 set: set$1,
895 delete: deleteEntry,
896 clear,
897 forEach: createForEach(false, false)
898};
899const shallowInstrumentations = {
900 get(key) {
901 return get$1(this, key, false, true);
902 },
903 get size() {
904 return size(this);
905 },
906 has: has$1,
907 add,
908 set: set$1,
909 delete: deleteEntry,
910 clear,
911 forEach: createForEach(false, true)
912};
913const readonlyInstrumentations = {
914 get(key) {
915 return get$1(this, key, true);
916 },
917 get size() {
918 return size(this, true);
919 },
920 has(key) {
921 return has$1.call(this, key, true);
922 },
923 add: createReadonlyMethod("add" /* ADD */),
924 set: createReadonlyMethod("set" /* SET */),
925 delete: createReadonlyMethod("delete" /* DELETE */),
926 clear: createReadonlyMethod("clear" /* CLEAR */),
927 forEach: createForEach(true, false)
928};
929const shallowReadonlyInstrumentations = {
930 get(key) {
931 return get$1(this, key, true, true);
932 },
933 get size() {
934 return size(this, true);
935 },
936 has(key) {
937 return has$1.call(this, key, true);
938 },
939 add: createReadonlyMethod("add" /* ADD */),
940 set: createReadonlyMethod("set" /* SET */),
941 delete: createReadonlyMethod("delete" /* DELETE */),
942 clear: createReadonlyMethod("clear" /* CLEAR */),
943 forEach: createForEach(true, true)
944};
945const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
946iteratorMethods.forEach(method => {
947 mutableInstrumentations[method] = createIterableMethod(method, false, false);
948 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
949 shallowInstrumentations[method] = createIterableMethod(method, false, true);
950 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
951});
952function createInstrumentationGetter(isReadonly, shallow) {
953 const instrumentations = shallow
954 ? isReadonly
955 ? shallowReadonlyInstrumentations
956 : shallowInstrumentations
957 : isReadonly
958 ? readonlyInstrumentations
959 : mutableInstrumentations;
960 return (target, key, receiver) => {
961 if (key === "__v_isReactive" /* IS_REACTIVE */) {
962 return !isReadonly;
963 }
964 else if (key === "__v_isReadonly" /* IS_READONLY */) {
965 return isReadonly;
966 }
967 else if (key === "__v_raw" /* RAW */) {
968 return target;
969 }
970 return Reflect.get(hasOwn(instrumentations, key) && key in target
971 ? instrumentations
972 : target, key, receiver);
973 };
974}
975const mutableCollectionHandlers = {
976 get: createInstrumentationGetter(false, false)
977};
978const shallowCollectionHandlers = {
979 get: createInstrumentationGetter(false, true)
980};
981const readonlyCollectionHandlers = {
982 get: createInstrumentationGetter(true, false)
983};
984const shallowReadonlyCollectionHandlers = {
985 get: createInstrumentationGetter(true, true)
986};
987function checkIdentityKeys(target, has, key) {
988 const rawKey = toRaw(key);
989 if (rawKey !== key && has.call(target, rawKey)) {
990 const type = toRawType(target);
991 console.warn(`Reactive ${type} contains both the raw and reactive ` +
992 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
993 `which can lead to inconsistencies. ` +
994 `Avoid differentiating between the raw and reactive versions ` +
995 `of an object and only use the reactive version if possible.`);
996 }
997}
998
999const reactiveMap = new WeakMap();
1000const shallowReactiveMap = new WeakMap();
1001const readonlyMap = new WeakMap();
1002const shallowReadonlyMap = new WeakMap();
1003function targetTypeMap(rawType) {
1004 switch (rawType) {
1005 case 'Object':
1006 case 'Array':
1007 return 1 /* COMMON */;
1008 case 'Map':
1009 case 'Set':
1010 case 'WeakMap':
1011 case 'WeakSet':
1012 return 2 /* COLLECTION */;
1013 default:
1014 return 0 /* INVALID */;
1015 }
1016}
1017function getTargetType(value) {
1018 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1019 ? 0 /* INVALID */
1020 : targetTypeMap(toRawType(value));
1021}
1022function reactive(target) {
1023 // if trying to observe a readonly proxy, return the readonly version.
1024 if (target && target["__v_isReadonly" /* IS_READONLY */]) {
1025 return target;
1026 }
1027 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1028}
1029/**
1030 * Return a shallowly-reactive copy of the original object, where only the root
1031 * level properties are reactive. It also does not auto-unwrap refs (even at the
1032 * root level).
1033 */
1034function shallowReactive(target) {
1035 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1036}
1037/**
1038 * Creates a readonly copy of the original object. Note the returned copy is not
1039 * made reactive, but `readonly` can be called on an already reactive object.
1040 */
1041function readonly(target) {
1042 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1043}
1044/**
1045 * Returns a reactive-copy of the original object, where only the root level
1046 * properties are readonly, and does NOT unwrap refs nor recursively convert
1047 * returned properties.
1048 * This is used for creating the props proxy object for stateful components.
1049 */
1050function shallowReadonly(target) {
1051 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1052}
1053function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1054 if (!isObject(target)) {
1055 {
1056 console.warn(`value cannot be made reactive: ${String(target)}`);
1057 }
1058 return target;
1059 }
1060 // target is already a Proxy, return it.
1061 // exception: calling readonly() on a reactive object
1062 if (target["__v_raw" /* RAW */] &&
1063 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1064 return target;
1065 }
1066 // target already has corresponding Proxy
1067 const existingProxy = proxyMap.get(target);
1068 if (existingProxy) {
1069 return existingProxy;
1070 }
1071 // only a whitelist of value types can be observed.
1072 const targetType = getTargetType(target);
1073 if (targetType === 0 /* INVALID */) {
1074 return target;
1075 }
1076 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1077 proxyMap.set(target, proxy);
1078 return proxy;
1079}
1080function isReactive(value) {
1081 if (isReadonly(value)) {
1082 return isReactive(value["__v_raw" /* RAW */]);
1083 }
1084 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1085}
1086function isReadonly(value) {
1087 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1088}
1089function isProxy(value) {
1090 return isReactive(value) || isReadonly(value);
1091}
1092function toRaw(observed) {
1093 return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed);
1094}
1095function markRaw(value) {
1096 def(value, "__v_skip" /* SKIP */, true);
1097 return value;
1098}
1099
1100const convert = (val) => isObject(val) ? reactive(val) : val;
1101function isRef(r) {
1102 return Boolean(r && r.__v_isRef === true);
1103}
1104function ref(value) {
1105 return createRef(value);
1106}
1107function shallowRef(value) {
1108 return createRef(value, true);
1109}
1110class RefImpl {
1111 constructor(_rawValue, _shallow = false) {
1112 this._rawValue = _rawValue;
1113 this._shallow = _shallow;
1114 this.__v_isRef = true;
1115 this._value = _shallow ? _rawValue : convert(_rawValue);
1116 }
1117 get value() {
1118 track(toRaw(this), "get" /* GET */, 'value');
1119 return this._value;
1120 }
1121 set value(newVal) {
1122 if (hasChanged(toRaw(newVal), this._rawValue)) {
1123 this._rawValue = newVal;
1124 this._value = this._shallow ? newVal : convert(newVal);
1125 trigger(toRaw(this), "set" /* SET */, 'value', newVal);
1126 }
1127 }
1128}
1129function createRef(rawValue, shallow = false) {
1130 if (isRef(rawValue)) {
1131 return rawValue;
1132 }
1133 return new RefImpl(rawValue, shallow);
1134}
1135function triggerRef(ref) {
1136 trigger(toRaw(ref), "set" /* SET */, 'value', ref.value );
1137}
1138function unref(ref) {
1139 return isRef(ref) ? ref.value : ref;
1140}
1141const shallowUnwrapHandlers = {
1142 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1143 set: (target, key, value, receiver) => {
1144 const oldValue = target[key];
1145 if (isRef(oldValue) && !isRef(value)) {
1146 oldValue.value = value;
1147 return true;
1148 }
1149 else {
1150 return Reflect.set(target, key, value, receiver);
1151 }
1152 }
1153};
1154function proxyRefs(objectWithRefs) {
1155 return isReactive(objectWithRefs)
1156 ? objectWithRefs
1157 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1158}
1159class CustomRefImpl {
1160 constructor(factory) {
1161 this.__v_isRef = true;
1162 const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value'));
1163 this._get = get;
1164 this._set = set;
1165 }
1166 get value() {
1167 return this._get();
1168 }
1169 set value(newVal) {
1170 this._set(newVal);
1171 }
1172}
1173function customRef(factory) {
1174 return new CustomRefImpl(factory);
1175}
1176function toRefs(object) {
1177 if (!isProxy(object)) {
1178 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1179 }
1180 const ret = isArray(object) ? new Array(object.length) : {};
1181 for (const key in object) {
1182 ret[key] = toRef(object, key);
1183 }
1184 return ret;
1185}
1186class ObjectRefImpl {
1187 constructor(_object, _key) {
1188 this._object = _object;
1189 this._key = _key;
1190 this.__v_isRef = true;
1191 }
1192 get value() {
1193 return this._object[this._key];
1194 }
1195 set value(newVal) {
1196 this._object[this._key] = newVal;
1197 }
1198}
1199function toRef(object, key) {
1200 return isRef(object[key])
1201 ? object[key]
1202 : new ObjectRefImpl(object, key);
1203}
1204
1205class ComputedRefImpl {
1206 constructor(getter, _setter, isReadonly) {
1207 this._setter = _setter;
1208 this._dirty = true;
1209 this.__v_isRef = true;
1210 this.effect = effect(getter, {
1211 lazy: true,
1212 scheduler: () => {
1213 if (!this._dirty) {
1214 this._dirty = true;
1215 trigger(toRaw(this), "set" /* SET */, 'value');
1216 }
1217 }
1218 });
1219 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1220 }
1221 get value() {
1222 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1223 const self = toRaw(this);
1224 if (self._dirty) {
1225 self._value = this.effect();
1226 self._dirty = false;
1227 }
1228 track(self, "get" /* GET */, 'value');
1229 return self._value;
1230 }
1231 set value(newValue) {
1232 this._setter(newValue);
1233 }
1234}
1235function computed(getterOrOptions) {
1236 let getter;
1237 let setter;
1238 if (isFunction(getterOrOptions)) {
1239 getter = getterOrOptions;
1240 setter = () => {
1241 console.warn('Write operation failed: computed value is readonly');
1242 }
1243 ;
1244 }
1245 else {
1246 getter = getterOrOptions.get;
1247 setter = getterOrOptions.set;
1248 }
1249 return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);
1250}
1251
1252const stack = [];
1253function pushWarningContext(vnode) {
1254 stack.push(vnode);
1255}
1256function popWarningContext() {
1257 stack.pop();
1258}
1259function warn(msg, ...args) {
1260 // avoid props formatting or warn handler tracking deps that might be mutated
1261 // during patch, leading to infinite recursion.
1262 pauseTracking();
1263 const instance = stack.length ? stack[stack.length - 1].component : null;
1264 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1265 const trace = getComponentTrace();
1266 if (appWarnHandler) {
1267 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1268 msg + args.join(''),
1269 instance && instance.proxy,
1270 trace
1271 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1272 .join('\n'),
1273 trace
1274 ]);
1275 }
1276 else {
1277 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1278 /* istanbul ignore if */
1279 if (trace.length &&
1280 // avoid spamming console during tests
1281 !false) {
1282 warnArgs.push(`\n`, ...formatTrace(trace));
1283 }
1284 console.warn(...warnArgs);
1285 }
1286 resetTracking();
1287}
1288function getComponentTrace() {
1289 let currentVNode = stack[stack.length - 1];
1290 if (!currentVNode) {
1291 return [];
1292 }
1293 // we can't just use the stack because it will be incomplete during updates
1294 // that did not start from the root. Re-construct the parent chain using
1295 // instance parent pointers.
1296 const normalizedStack = [];
1297 while (currentVNode) {
1298 const last = normalizedStack[0];
1299 if (last && last.vnode === currentVNode) {
1300 last.recurseCount++;
1301 }
1302 else {
1303 normalizedStack.push({
1304 vnode: currentVNode,
1305 recurseCount: 0
1306 });
1307 }
1308 const parentInstance = currentVNode.component && currentVNode.component.parent;
1309 currentVNode = parentInstance && parentInstance.vnode;
1310 }
1311 return normalizedStack;
1312}
1313/* istanbul ignore next */
1314function formatTrace(trace) {
1315 const logs = [];
1316 trace.forEach((entry, i) => {
1317 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1318 });
1319 return logs;
1320}
1321function formatTraceEntry({ vnode, recurseCount }) {
1322 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1323 const isRoot = vnode.component ? vnode.component.parent == null : false;
1324 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1325 const close = `>` + postfix;
1326 return vnode.props
1327 ? [open, ...formatProps(vnode.props), close]
1328 : [open + close];
1329}
1330/* istanbul ignore next */
1331function formatProps(props) {
1332 const res = [];
1333 const keys = Object.keys(props);
1334 keys.slice(0, 3).forEach(key => {
1335 res.push(...formatProp(key, props[key]));
1336 });
1337 if (keys.length > 3) {
1338 res.push(` ...`);
1339 }
1340 return res;
1341}
1342/* istanbul ignore next */
1343function formatProp(key, value, raw) {
1344 if (isString(value)) {
1345 value = JSON.stringify(value);
1346 return raw ? value : [`${key}=${value}`];
1347 }
1348 else if (typeof value === 'number' ||
1349 typeof value === 'boolean' ||
1350 value == null) {
1351 return raw ? value : [`${key}=${value}`];
1352 }
1353 else if (isRef(value)) {
1354 value = formatProp(key, toRaw(value.value), true);
1355 return raw ? value : [`${key}=Ref<`, value, `>`];
1356 }
1357 else if (isFunction(value)) {
1358 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1359 }
1360 else {
1361 value = toRaw(value);
1362 return raw ? value : [`${key}=`, value];
1363 }
1364}
1365
1366const ErrorTypeStrings = {
1367 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1368 ["c" /* CREATED */]: 'created hook',
1369 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1370 ["m" /* MOUNTED */]: 'mounted hook',
1371 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1372 ["u" /* UPDATED */]: 'updated',
1373 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1374 ["um" /* UNMOUNTED */]: 'unmounted hook',
1375 ["a" /* ACTIVATED */]: 'activated hook',
1376 ["da" /* DEACTIVATED */]: 'deactivated hook',
1377 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1378 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1379 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1380 [0 /* SETUP_FUNCTION */]: 'setup function',
1381 [1 /* RENDER_FUNCTION */]: 'render function',
1382 [2 /* WATCH_GETTER */]: 'watcher getter',
1383 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1384 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1385 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1386 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1387 [7 /* VNODE_HOOK */]: 'vnode hook',
1388 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1389 [9 /* TRANSITION_HOOK */]: 'transition hook',
1390 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1391 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1392 [12 /* FUNCTION_REF */]: 'ref function',
1393 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1394 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1395 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
1396};
1397function callWithErrorHandling(fn, instance, type, args) {
1398 let res;
1399 try {
1400 res = args ? fn(...args) : fn();
1401 }
1402 catch (err) {
1403 handleError(err, instance, type);
1404 }
1405 return res;
1406}
1407function callWithAsyncErrorHandling(fn, instance, type, args) {
1408 if (isFunction(fn)) {
1409 const res = callWithErrorHandling(fn, instance, type, args);
1410 if (res && isPromise(res)) {
1411 res.catch(err => {
1412 handleError(err, instance, type);
1413 });
1414 }
1415 return res;
1416 }
1417 const values = [];
1418 for (let i = 0; i < fn.length; i++) {
1419 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1420 }
1421 return values;
1422}
1423function handleError(err, instance, type, throwInDev = true) {
1424 const contextVNode = instance ? instance.vnode : null;
1425 if (instance) {
1426 let cur = instance.parent;
1427 // the exposed instance is the render proxy to keep it consistent with 2.x
1428 const exposedInstance = instance.proxy;
1429 // in production the hook receives only the error code
1430 const errorInfo = ErrorTypeStrings[type] ;
1431 while (cur) {
1432 const errorCapturedHooks = cur.ec;
1433 if (errorCapturedHooks) {
1434 for (let i = 0; i < errorCapturedHooks.length; i++) {
1435 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1436 return;
1437 }
1438 }
1439 }
1440 cur = cur.parent;
1441 }
1442 // app-level handling
1443 const appErrorHandler = instance.appContext.config.errorHandler;
1444 if (appErrorHandler) {
1445 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1446 return;
1447 }
1448 }
1449 logError(err, type, contextVNode, throwInDev);
1450}
1451function logError(err, type, contextVNode, throwInDev = true) {
1452 {
1453 const info = ErrorTypeStrings[type];
1454 if (contextVNode) {
1455 pushWarningContext(contextVNode);
1456 }
1457 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1458 if (contextVNode) {
1459 popWarningContext();
1460 }
1461 // crash in dev by default so it's more noticeable
1462 if (throwInDev) {
1463 throw err;
1464 }
1465 else {
1466 console.error(err);
1467 }
1468 }
1469}
1470
1471let isFlushing = false;
1472let isFlushPending = false;
1473const queue = [];
1474let flushIndex = 0;
1475const pendingPreFlushCbs = [];
1476let activePreFlushCbs = null;
1477let preFlushIndex = 0;
1478const pendingPostFlushCbs = [];
1479let activePostFlushCbs = null;
1480let postFlushIndex = 0;
1481const resolvedPromise = Promise.resolve();
1482let currentFlushPromise = null;
1483let currentPreFlushParentJob = null;
1484const RECURSION_LIMIT = 100;
1485function nextTick(fn) {
1486 const p = currentFlushPromise || resolvedPromise;
1487 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1488}
1489// #2768
1490// Use binary-search to find a suitable position in the queue,
1491// so that the queue maintains the increasing order of job's id,
1492// which can prevent the job from being skipped and also can avoid repeated patching.
1493function findInsertionIndex(job) {
1494 // the start index should be `flushIndex + 1`
1495 let start = flushIndex + 1;
1496 let end = queue.length;
1497 const jobId = getId(job);
1498 while (start < end) {
1499 const middle = (start + end) >>> 1;
1500 const middleJobId = getId(queue[middle]);
1501 middleJobId < jobId ? (start = middle + 1) : (end = middle);
1502 }
1503 return start;
1504}
1505function queueJob(job) {
1506 // the dedupe search uses the startIndex argument of Array.includes()
1507 // by default the search index includes the current job that is being run
1508 // so it cannot recursively trigger itself again.
1509 // if the job is a watch() callback, the search will start with a +1 index to
1510 // allow it recursively trigger itself - it is the user's responsibility to
1511 // ensure it doesn't end up in an infinite loop.
1512 if ((!queue.length ||
1513 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1514 job !== currentPreFlushParentJob) {
1515 const pos = findInsertionIndex(job);
1516 if (pos > -1) {
1517 queue.splice(pos, 0, job);
1518 }
1519 else {
1520 queue.push(job);
1521 }
1522 queueFlush();
1523 }
1524}
1525function queueFlush() {
1526 if (!isFlushing && !isFlushPending) {
1527 isFlushPending = true;
1528 currentFlushPromise = resolvedPromise.then(flushJobs);
1529 }
1530}
1531function invalidateJob(job) {
1532 const i = queue.indexOf(job);
1533 if (i > flushIndex) {
1534 queue.splice(i, 1);
1535 }
1536}
1537function queueCb(cb, activeQueue, pendingQueue, index) {
1538 if (!isArray(cb)) {
1539 if (!activeQueue ||
1540 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1541 pendingQueue.push(cb);
1542 }
1543 }
1544 else {
1545 // if cb is an array, it is a component lifecycle hook which can only be
1546 // triggered by a job, which is already deduped in the main queue, so
1547 // we can skip duplicate check here to improve perf
1548 pendingQueue.push(...cb);
1549 }
1550 queueFlush();
1551}
1552function queuePreFlushCb(cb) {
1553 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1554}
1555function queuePostFlushCb(cb) {
1556 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1557}
1558function flushPreFlushCbs(seen, parentJob = null) {
1559 if (pendingPreFlushCbs.length) {
1560 currentPreFlushParentJob = parentJob;
1561 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1562 pendingPreFlushCbs.length = 0;
1563 {
1564 seen = seen || new Map();
1565 }
1566 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1567 {
1568 checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex]);
1569 }
1570 activePreFlushCbs[preFlushIndex]();
1571 }
1572 activePreFlushCbs = null;
1573 preFlushIndex = 0;
1574 currentPreFlushParentJob = null;
1575 // recursively flush until it drains
1576 flushPreFlushCbs(seen, parentJob);
1577 }
1578}
1579function flushPostFlushCbs(seen) {
1580 if (pendingPostFlushCbs.length) {
1581 const deduped = [...new Set(pendingPostFlushCbs)];
1582 pendingPostFlushCbs.length = 0;
1583 // #1947 already has active queue, nested flushPostFlushCbs call
1584 if (activePostFlushCbs) {
1585 activePostFlushCbs.push(...deduped);
1586 return;
1587 }
1588 activePostFlushCbs = deduped;
1589 {
1590 seen = seen || new Map();
1591 }
1592 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1593 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1594 {
1595 checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex]);
1596 }
1597 activePostFlushCbs[postFlushIndex]();
1598 }
1599 activePostFlushCbs = null;
1600 postFlushIndex = 0;
1601 }
1602}
1603const getId = (job) => job.id == null ? Infinity : job.id;
1604function flushJobs(seen) {
1605 isFlushPending = false;
1606 isFlushing = true;
1607 {
1608 seen = seen || new Map();
1609 }
1610 flushPreFlushCbs(seen);
1611 // Sort queue before flush.
1612 // This ensures that:
1613 // 1. Components are updated from parent to child. (because parent is always
1614 // created before the child so its render effect will have smaller
1615 // priority number)
1616 // 2. If a component is unmounted during a parent component's update,
1617 // its update can be skipped.
1618 queue.sort((a, b) => getId(a) - getId(b));
1619 try {
1620 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1621 const job = queue[flushIndex];
1622 if (job) {
1623 if (true) {
1624 checkRecursiveUpdates(seen, job);
1625 }
1626 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1627 }
1628 }
1629 }
1630 finally {
1631 flushIndex = 0;
1632 queue.length = 0;
1633 flushPostFlushCbs(seen);
1634 isFlushing = false;
1635 currentFlushPromise = null;
1636 // some postFlushCb queued jobs!
1637 // keep flushing until it drains.
1638 if (queue.length || pendingPostFlushCbs.length) {
1639 flushJobs(seen);
1640 }
1641 }
1642}
1643function checkRecursiveUpdates(seen, fn) {
1644 if (!seen.has(fn)) {
1645 seen.set(fn, 1);
1646 }
1647 else {
1648 const count = seen.get(fn);
1649 if (count > RECURSION_LIMIT) {
1650 throw new Error(`Maximum recursive updates exceeded. ` +
1651 `This means you have a reactive effect that is mutating its own ` +
1652 `dependencies and thus recursively triggering itself. Possible sources ` +
1653 `include component template, render function, updated hook or ` +
1654 `watcher source function.`);
1655 }
1656 else {
1657 seen.set(fn, count + 1);
1658 }
1659 }
1660}
1661
1662/* eslint-disable no-restricted-globals */
1663let isHmrUpdating = false;
1664const hmrDirtyComponents = new Set();
1665// Expose the HMR runtime on the global object
1666// This makes it entirely tree-shakable without polluting the exports and makes
1667// it easier to be used in toolings like vue-loader
1668// Note: for a component to be eligible for HMR it also needs the __hmrId option
1669// to be set so that its instances can be registered / removed.
1670{
1671 const globalObject = typeof global !== 'undefined'
1672 ? global
1673 : typeof self !== 'undefined'
1674 ? self
1675 : typeof window !== 'undefined'
1676 ? window
1677 : {};
1678 globalObject.__VUE_HMR_RUNTIME__ = {
1679 createRecord: tryWrap(createRecord),
1680 rerender: tryWrap(rerender),
1681 reload: tryWrap(reload)
1682 };
1683}
1684const map = new Map();
1685function registerHMR(instance) {
1686 const id = instance.type.__hmrId;
1687 let record = map.get(id);
1688 if (!record) {
1689 createRecord(id, instance.type);
1690 record = map.get(id);
1691 }
1692 record.instances.add(instance);
1693}
1694function unregisterHMR(instance) {
1695 map.get(instance.type.__hmrId).instances.delete(instance);
1696}
1697function createRecord(id, component) {
1698 if (!component) {
1699 warn(`HMR API usage is out of date.\n` +
1700 `Please upgrade vue-loader/vite/rollup-plugin-vue or other relevant ` +
1701 `dependency that handles Vue SFC compilation.`);
1702 component = {};
1703 }
1704 if (map.has(id)) {
1705 return false;
1706 }
1707 map.set(id, {
1708 component: isClassComponent(component) ? component.__vccOpts : component,
1709 instances: new Set()
1710 });
1711 return true;
1712}
1713function rerender(id, newRender) {
1714 const record = map.get(id);
1715 if (!record)
1716 return;
1717 if (newRender)
1718 record.component.render = newRender;
1719 // Array.from creates a snapshot which avoids the set being mutated during
1720 // updates
1721 Array.from(record.instances).forEach(instance => {
1722 if (newRender) {
1723 instance.render = newRender;
1724 }
1725 instance.renderCache = [];
1726 // this flag forces child components with slot content to update
1727 isHmrUpdating = true;
1728 instance.update();
1729 isHmrUpdating = false;
1730 });
1731}
1732function reload(id, newComp) {
1733 const record = map.get(id);
1734 if (!record)
1735 return;
1736 // Array.from creates a snapshot which avoids the set being mutated during
1737 // updates
1738 const { component, instances } = record;
1739 if (!hmrDirtyComponents.has(component)) {
1740 // 1. Update existing comp definition to match new one
1741 newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp;
1742 extend(component, newComp);
1743 for (const key in component) {
1744 if (!(key in newComp)) {
1745 delete component[key];
1746 }
1747 }
1748 // 2. Mark component dirty. This forces the renderer to replace the component
1749 // on patch.
1750 hmrDirtyComponents.add(component);
1751 // 3. Make sure to unmark the component after the reload.
1752 queuePostFlushCb(() => {
1753 hmrDirtyComponents.delete(component);
1754 });
1755 }
1756 Array.from(instances).forEach(instance => {
1757 if (instance.parent) {
1758 // 4. Force the parent instance to re-render. This will cause all updated
1759 // components to be unmounted and re-mounted. Queue the update so that we
1760 // don't end up forcing the same parent to re-render multiple times.
1761 queueJob(instance.parent.update);
1762 }
1763 else if (instance.appContext.reload) {
1764 // root instance mounted via createApp() has a reload method
1765 instance.appContext.reload();
1766 }
1767 else if (typeof window !== 'undefined') {
1768 // root instance inside tree created via raw render(). Force reload.
1769 window.location.reload();
1770 }
1771 else {
1772 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
1773 }
1774 });
1775}
1776function tryWrap(fn) {
1777 return (id, arg) => {
1778 try {
1779 return fn(id, arg);
1780 }
1781 catch (e) {
1782 console.error(e);
1783 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
1784 `Full reload required.`);
1785 }
1786 };
1787}
1788
1789let devtools;
1790function setDevtoolsHook(hook) {
1791 devtools = hook;
1792}
1793function devtoolsInitApp(app, version) {
1794 // TODO queue if devtools is undefined
1795 if (!devtools)
1796 return;
1797 devtools.emit("app:init" /* APP_INIT */, app, version, {
1798 Fragment,
1799 Text,
1800 Comment,
1801 Static
1802 });
1803}
1804function devtoolsUnmountApp(app) {
1805 if (!devtools)
1806 return;
1807 devtools.emit("app:unmount" /* APP_UNMOUNT */, app);
1808}
1809const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
1810const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
1811const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
1812function createDevtoolsComponentHook(hook) {
1813 return (component) => {
1814 if (!devtools)
1815 return;
1816 devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
1817 };
1818}
1819function devtoolsComponentEmit(component, event, params) {
1820 if (!devtools)
1821 return;
1822 devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
1823}
1824
1825function emit(instance, event, ...rawArgs) {
1826 const props = instance.vnode.props || EMPTY_OBJ;
1827 {
1828 const { emitsOptions, propsOptions: [propsOptions] } = instance;
1829 if (emitsOptions) {
1830 if (!(event in emitsOptions)) {
1831 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
1832 warn(`Component emitted event "${event}" but it is neither declared in ` +
1833 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
1834 }
1835 }
1836 else {
1837 const validator = emitsOptions[event];
1838 if (isFunction(validator)) {
1839 const isValid = validator(...rawArgs);
1840 if (!isValid) {
1841 warn(`Invalid event arguments: event validation failed for event "${event}".`);
1842 }
1843 }
1844 }
1845 }
1846 }
1847 let args = rawArgs;
1848 const isModelListener = event.startsWith('update:');
1849 // for v-model update:xxx events, apply modifiers on args
1850 const modelArg = isModelListener && event.slice(7);
1851 if (modelArg && modelArg in props) {
1852 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
1853 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
1854 if (trim) {
1855 args = rawArgs.map(a => a.trim());
1856 }
1857 else if (number) {
1858 args = rawArgs.map(toNumber);
1859 }
1860 }
1861 {
1862 devtoolsComponentEmit(instance, event, args);
1863 }
1864 {
1865 const lowerCaseEvent = event.toLowerCase();
1866 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
1867 warn(`Event "${lowerCaseEvent}" is emitted in component ` +
1868 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
1869 `Note that HTML attributes are case-insensitive and you cannot use ` +
1870 `v-on to listen to camelCase events when using in-DOM templates. ` +
1871 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
1872 }
1873 }
1874 let handlerName;
1875 let handler = props[(handlerName = toHandlerKey(event))] ||
1876 // also try camelCase event handler (#2249)
1877 props[(handlerName = toHandlerKey(camelize(event)))];
1878 // for v-model update:xxx events, also trigger kebab-case equivalent
1879 // for props passed via kebab-case
1880 if (!handler && isModelListener) {
1881 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
1882 }
1883 if (handler) {
1884 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1885 }
1886 const onceHandler = props[handlerName + `Once`];
1887 if (onceHandler) {
1888 if (!instance.emitted) {
1889 (instance.emitted = {})[handlerName] = true;
1890 }
1891 else if (instance.emitted[handlerName]) {
1892 return;
1893 }
1894 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1895 }
1896}
1897function normalizeEmitsOptions(comp, appContext, asMixin = false) {
1898 if (!appContext.deopt && comp.__emits !== undefined) {
1899 return comp.__emits;
1900 }
1901 const raw = comp.emits;
1902 let normalized = {};
1903 // apply mixin/extends props
1904 let hasExtends = false;
1905 if (!isFunction(comp)) {
1906 const extendEmits = (raw) => {
1907 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
1908 if (normalizedFromExtend) {
1909 hasExtends = true;
1910 extend(normalized, normalizedFromExtend);
1911 }
1912 };
1913 if (!asMixin && appContext.mixins.length) {
1914 appContext.mixins.forEach(extendEmits);
1915 }
1916 if (comp.extends) {
1917 extendEmits(comp.extends);
1918 }
1919 if (comp.mixins) {
1920 comp.mixins.forEach(extendEmits);
1921 }
1922 }
1923 if (!raw && !hasExtends) {
1924 return (comp.__emits = null);
1925 }
1926 if (isArray(raw)) {
1927 raw.forEach(key => (normalized[key] = null));
1928 }
1929 else {
1930 extend(normalized, raw);
1931 }
1932 return (comp.__emits = normalized);
1933}
1934// Check if an incoming prop key is a declared emit event listener.
1935// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
1936// both considered matched listeners.
1937function isEmitListener(options, key) {
1938 if (!options || !isOn(key)) {
1939 return false;
1940 }
1941 key = key.slice(2).replace(/Once$/, '');
1942 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
1943 hasOwn(options, hyphenate(key)) ||
1944 hasOwn(options, key));
1945}
1946
1947let isRenderingCompiledSlot = 0;
1948const setCompiledSlotRendering = (n) => (isRenderingCompiledSlot += n);
1949/**
1950 * Compiler runtime helper for rendering `<slot/>`
1951 * @private
1952 */
1953function renderSlot(slots, name, props = {},
1954// this is not a user-facing function, so the fallback is always generated by
1955// the compiler and guaranteed to be a function returning an array
1956fallback, noSlotted) {
1957 let slot = slots[name];
1958 if (slot && slot.length > 1) {
1959 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
1960 `function. You need to mark this component with $dynamic-slots in the ` +
1961 `parent template.`);
1962 slot = () => [];
1963 }
1964 // a compiled slot disables block tracking by default to avoid manual
1965 // invocation interfering with template-based block tracking, but in
1966 // `renderSlot` we can be sure that it's template-based so we can force
1967 // enable it.
1968 isRenderingCompiledSlot++;
1969 openBlock();
1970 const validSlotContent = slot && ensureValidVNode(slot(props));
1971 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
1972 ? 64 /* STABLE_FRAGMENT */
1973 : -2 /* BAIL */);
1974 if (!noSlotted && rendered.scopeId) {
1975 rendered.slotScopeIds = [rendered.scopeId + '-s'];
1976 }
1977 isRenderingCompiledSlot--;
1978 return rendered;
1979}
1980function ensureValidVNode(vnodes) {
1981 return vnodes.some(child => {
1982 if (!isVNode(child))
1983 return true;
1984 if (child.type === Comment)
1985 return false;
1986 if (child.type === Fragment &&
1987 !ensureValidVNode(child.children))
1988 return false;
1989 return true;
1990 })
1991 ? vnodes
1992 : null;
1993}
1994
1995/**
1996 * mark the current rendering instance for asset resolution (e.g.
1997 * resolveComponent, resolveDirective) during render
1998 */
1999let currentRenderingInstance = null;
2000let currentScopeId = null;
2001/**
2002 * Note: rendering calls maybe nested. The function returns the parent rendering
2003 * instance if present, which should be restored after the render is done:
2004 *
2005 * ```js
2006 * const prev = setCurrentRenderingInstance(i)
2007 * // ...render
2008 * setCurrentRenderingInstance(prev)
2009 * ```
2010 */
2011function setCurrentRenderingInstance(instance) {
2012 const prev = currentRenderingInstance;
2013 currentRenderingInstance = instance;
2014 currentScopeId = (instance && instance.type.__scopeId) || null;
2015 return prev;
2016}
2017/**
2018 * Set scope id when creating hoisted vnodes.
2019 * @private compiler helper
2020 */
2021function pushScopeId(id) {
2022 currentScopeId = id;
2023}
2024/**
2025 * Technically we no longer need this after 3.0.8 but we need to keep the same
2026 * API for backwards compat w/ code generated by compilers.
2027 * @private
2028 */
2029function popScopeId() {
2030 currentScopeId = null;
2031}
2032/**
2033 * Only for backwards compat
2034 * @private
2035 */
2036const withScopeId = (_id) => withCtx;
2037/**
2038 * Wrap a slot function to memoize current rendering instance
2039 * @private compiler helper
2040 */
2041function withCtx(fn, ctx = currentRenderingInstance) {
2042 if (!ctx)
2043 return fn;
2044 const renderFnWithContext = (...args) => {
2045 // If a user calls a compiled slot inside a template expression (#1745), it
2046 // can mess up block tracking, so by default we need to push a null block to
2047 // avoid that. This isn't necessary if rendering a compiled `<slot>`.
2048 if (!isRenderingCompiledSlot) {
2049 openBlock(true /* null block that disables tracking */);
2050 }
2051 const prevInstance = setCurrentRenderingInstance(ctx);
2052 const res = fn(...args);
2053 setCurrentRenderingInstance(prevInstance);
2054 if (!isRenderingCompiledSlot) {
2055 closeBlock();
2056 }
2057 return res;
2058 };
2059 // mark this as a compiled slot function.
2060 // this is used in vnode.ts -> normalizeChildren() to set the slot
2061 // rendering flag.
2062 renderFnWithContext._c = true;
2063 return renderFnWithContext;
2064}
2065
2066/**
2067 * dev only flag to track whether $attrs was used during render.
2068 * If $attrs was used during render then the warning for failed attrs
2069 * fallthrough can be suppressed.
2070 */
2071let accessedAttrs = false;
2072function markAttrsAccessed() {
2073 accessedAttrs = true;
2074}
2075function renderComponentRoot(instance) {
2076 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance;
2077 let result;
2078 const prev = setCurrentRenderingInstance(instance);
2079 {
2080 accessedAttrs = false;
2081 }
2082 try {
2083 let fallthroughAttrs;
2084 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
2085 // withProxy is a proxy with a different `has` trap only for
2086 // runtime-compiled render functions using `with` block.
2087 const proxyToUse = withProxy || proxy;
2088 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2089 fallthroughAttrs = attrs;
2090 }
2091 else {
2092 // functional
2093 const render = Component;
2094 // in dev, mark attrs accessed if optional props (attrs === props)
2095 if (true && attrs === props) {
2096 markAttrsAccessed();
2097 }
2098 result = normalizeVNode(render.length > 1
2099 ? render(props, true
2100 ? {
2101 get attrs() {
2102 markAttrsAccessed();
2103 return attrs;
2104 },
2105 slots,
2106 emit
2107 }
2108 : { attrs, slots, emit })
2109 : render(props, null /* we know it doesn't need it */));
2110 fallthroughAttrs = Component.props
2111 ? attrs
2112 : getFunctionalFallthrough(attrs);
2113 }
2114 // attr merging
2115 // in dev mode, comments are preserved, and it's possible for a template
2116 // to have comments along side the root element which makes it a fragment
2117 let root = result;
2118 let setRoot = undefined;
2119 if (true &&
2120 result.patchFlag > 0 &&
2121 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
2122 ;
2123 [root, setRoot] = getChildRoot(result);
2124 }
2125 if (Component.inheritAttrs !== false && fallthroughAttrs) {
2126 const keys = Object.keys(fallthroughAttrs);
2127 const { shapeFlag } = root;
2128 if (keys.length) {
2129 if (shapeFlag & 1 /* ELEMENT */ ||
2130 shapeFlag & 6 /* COMPONENT */) {
2131 if (propsOptions && keys.some(isModelListener)) {
2132 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2133 // prop, it indicates this component expects to handle v-model and
2134 // it should not fallthrough.
2135 // related: #1543, #1643, #1989
2136 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2137 }
2138 root = cloneVNode(root, fallthroughAttrs);
2139 }
2140 else if (true && !accessedAttrs && root.type !== Comment) {
2141 const allAttrs = Object.keys(attrs);
2142 const eventAttrs = [];
2143 const extraAttrs = [];
2144 for (let i = 0, l = allAttrs.length; i < l; i++) {
2145 const key = allAttrs[i];
2146 if (isOn(key)) {
2147 // ignore v-model handlers when they fail to fallthrough
2148 if (!isModelListener(key)) {
2149 // remove `on`, lowercase first letter to reflect event casing
2150 // accurately
2151 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2152 }
2153 }
2154 else {
2155 extraAttrs.push(key);
2156 }
2157 }
2158 if (extraAttrs.length) {
2159 warn(`Extraneous non-props attributes (` +
2160 `${extraAttrs.join(', ')}) ` +
2161 `were passed to component but could not be automatically inherited ` +
2162 `because component renders fragment or text root nodes.`);
2163 }
2164 if (eventAttrs.length) {
2165 warn(`Extraneous non-emits event listeners (` +
2166 `${eventAttrs.join(', ')}) ` +
2167 `were passed to component but could not be automatically inherited ` +
2168 `because component renders fragment or text root nodes. ` +
2169 `If the listener is intended to be a component custom event listener only, ` +
2170 `declare it using the "emits" option.`);
2171 }
2172 }
2173 }
2174 }
2175 // inherit directives
2176 if (vnode.dirs) {
2177 if (true && !isElementRoot(root)) {
2178 warn(`Runtime directive used on component with non-element root node. ` +
2179 `The directives will not function as intended.`);
2180 }
2181 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2182 }
2183 // inherit transition data
2184 if (vnode.transition) {
2185 if (true && !isElementRoot(root)) {
2186 warn(`Component inside <Transition> renders non-element root node ` +
2187 `that cannot be animated.`);
2188 }
2189 root.transition = vnode.transition;
2190 }
2191 if (true && setRoot) {
2192 setRoot(root);
2193 }
2194 else {
2195 result = root;
2196 }
2197 }
2198 catch (err) {
2199 blockStack.length = 0;
2200 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2201 result = createVNode(Comment);
2202 }
2203 setCurrentRenderingInstance(prev);
2204 return result;
2205}
2206/**
2207 * dev only
2208 * In dev mode, template root level comments are rendered, which turns the
2209 * template into a fragment root, but we need to locate the single element
2210 * root for attrs and scope id processing.
2211 */
2212const getChildRoot = (vnode) => {
2213 const rawChildren = vnode.children;
2214 const dynamicChildren = vnode.dynamicChildren;
2215 const childRoot = filterSingleRoot(rawChildren);
2216 if (!childRoot) {
2217 return [vnode, undefined];
2218 }
2219 const index = rawChildren.indexOf(childRoot);
2220 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2221 const setRoot = (updatedRoot) => {
2222 rawChildren[index] = updatedRoot;
2223 if (dynamicChildren) {
2224 if (dynamicIndex > -1) {
2225 dynamicChildren[dynamicIndex] = updatedRoot;
2226 }
2227 else if (updatedRoot.patchFlag > 0) {
2228 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2229 }
2230 }
2231 };
2232 return [normalizeVNode(childRoot), setRoot];
2233};
2234function filterSingleRoot(children) {
2235 let singleRoot;
2236 for (let i = 0; i < children.length; i++) {
2237 const child = children[i];
2238 if (isVNode(child)) {
2239 // ignore user comment
2240 if (child.type !== Comment || child.children === 'v-if') {
2241 if (singleRoot) {
2242 // has more than 1 non-comment child, return now
2243 return;
2244 }
2245 else {
2246 singleRoot = child;
2247 }
2248 }
2249 }
2250 else {
2251 return;
2252 }
2253 }
2254 return singleRoot;
2255}
2256const getFunctionalFallthrough = (attrs) => {
2257 let res;
2258 for (const key in attrs) {
2259 if (key === 'class' || key === 'style' || isOn(key)) {
2260 (res || (res = {}))[key] = attrs[key];
2261 }
2262 }
2263 return res;
2264};
2265const filterModelListeners = (attrs, props) => {
2266 const res = {};
2267 for (const key in attrs) {
2268 if (!isModelListener(key) || !(key.slice(9) in props)) {
2269 res[key] = attrs[key];
2270 }
2271 }
2272 return res;
2273};
2274const isElementRoot = (vnode) => {
2275 return (vnode.shapeFlag & 6 /* COMPONENT */ ||
2276 vnode.shapeFlag & 1 /* ELEMENT */ ||
2277 vnode.type === Comment // potential v-if branch switch
2278 );
2279};
2280function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2281 const { props: prevProps, children: prevChildren, component } = prevVNode;
2282 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2283 const emits = component.emitsOptions;
2284 // Parent component's render function was hot-updated. Since this may have
2285 // caused the child component's slots content to have changed, we need to
2286 // force the child to update as well.
2287 if ((prevChildren || nextChildren) && isHmrUpdating) {
2288 return true;
2289 }
2290 // force child update for runtime directive or transition on component vnode.
2291 if (nextVNode.dirs || nextVNode.transition) {
2292 return true;
2293 }
2294 if (optimized && patchFlag >= 0) {
2295 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2296 // slot content that references values that might have changed,
2297 // e.g. in a v-for
2298 return true;
2299 }
2300 if (patchFlag & 16 /* FULL_PROPS */) {
2301 if (!prevProps) {
2302 return !!nextProps;
2303 }
2304 // presence of this flag indicates props are always non-null
2305 return hasPropsChanged(prevProps, nextProps, emits);
2306 }
2307 else if (patchFlag & 8 /* PROPS */) {
2308 const dynamicProps = nextVNode.dynamicProps;
2309 for (let i = 0; i < dynamicProps.length; i++) {
2310 const key = dynamicProps[i];
2311 if (nextProps[key] !== prevProps[key] &&
2312 !isEmitListener(emits, key)) {
2313 return true;
2314 }
2315 }
2316 }
2317 }
2318 else {
2319 // this path is only taken by manually written render functions
2320 // so presence of any children leads to a forced update
2321 if (prevChildren || nextChildren) {
2322 if (!nextChildren || !nextChildren.$stable) {
2323 return true;
2324 }
2325 }
2326 if (prevProps === nextProps) {
2327 return false;
2328 }
2329 if (!prevProps) {
2330 return !!nextProps;
2331 }
2332 if (!nextProps) {
2333 return true;
2334 }
2335 return hasPropsChanged(prevProps, nextProps, emits);
2336 }
2337 return false;
2338}
2339function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2340 const nextKeys = Object.keys(nextProps);
2341 if (nextKeys.length !== Object.keys(prevProps).length) {
2342 return true;
2343 }
2344 for (let i = 0; i < nextKeys.length; i++) {
2345 const key = nextKeys[i];
2346 if (nextProps[key] !== prevProps[key] &&
2347 !isEmitListener(emitsOptions, key)) {
2348 return true;
2349 }
2350 }
2351 return false;
2352}
2353function updateHOCHostEl({ vnode, parent }, el // HostNode
2354) {
2355 while (parent && parent.subTree === vnode) {
2356 (vnode = parent.vnode).el = el;
2357 parent = parent.parent;
2358 }
2359}
2360
2361const isSuspense = (type) => type.__isSuspense;
2362// Suspense exposes a component-like API, and is treated like a component
2363// in the compiler, but internally it's a special built-in type that hooks
2364// directly into the renderer.
2365const SuspenseImpl = {
2366 name: 'Suspense',
2367 // In order to make Suspense tree-shakable, we need to avoid importing it
2368 // directly in the renderer. The renderer checks for the __isSuspense flag
2369 // on a vnode's type and calls the `process` method, passing in renderer
2370 // internals.
2371 __isSuspense: true,
2372 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2373 // platform-specific impl passed from renderer
2374 rendererInternals) {
2375 if (n1 == null) {
2376 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2377 }
2378 else {
2379 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2380 }
2381 },
2382 hydrate: hydrateSuspense,
2383 create: createSuspenseBoundary
2384};
2385// Force-casted public typing for h and TSX props inference
2386const Suspense = (SuspenseImpl
2387 );
2388function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2389 const { p: patch, o: { createElement } } = rendererInternals;
2390 const hiddenContainer = createElement('div');
2391 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2392 // start mounting the content subtree in an off-dom container
2393 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2394 // now check if we have encountered any async deps
2395 if (suspense.deps > 0) {
2396 // has async
2397 // mount the fallback tree
2398 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2399 isSVG, slotScopeIds);
2400 setActiveBranch(suspense, vnode.ssFallback);
2401 }
2402 else {
2403 // Suspense has no async deps. Just resolve.
2404 suspense.resolve();
2405 }
2406}
2407function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2408 const suspense = (n2.suspense = n1.suspense);
2409 suspense.vnode = n2;
2410 n2.el = n1.el;
2411 const newBranch = n2.ssContent;
2412 const newFallback = n2.ssFallback;
2413 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2414 if (pendingBranch) {
2415 suspense.pendingBranch = newBranch;
2416 if (isSameVNodeType(newBranch, pendingBranch)) {
2417 // same root type but content may have changed.
2418 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2419 if (suspense.deps <= 0) {
2420 suspense.resolve();
2421 }
2422 else if (isInFallback) {
2423 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2424 isSVG, slotScopeIds, optimized);
2425 setActiveBranch(suspense, newFallback);
2426 }
2427 }
2428 else {
2429 // toggled before pending tree is resolved
2430 suspense.pendingId++;
2431 if (isHydrating) {
2432 // if toggled before hydration is finished, the current DOM tree is
2433 // no longer valid. set it as the active branch so it will be unmounted
2434 // when resolved
2435 suspense.isHydrating = false;
2436 suspense.activeBranch = pendingBranch;
2437 }
2438 else {
2439 unmount(pendingBranch, parentComponent, suspense);
2440 }
2441 // increment pending ID. this is used to invalidate async callbacks
2442 // reset suspense state
2443 suspense.deps = 0;
2444 // discard effects from pending branch
2445 suspense.effects.length = 0;
2446 // discard previous container
2447 suspense.hiddenContainer = createElement('div');
2448 if (isInFallback) {
2449 // already in fallback state
2450 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2451 if (suspense.deps <= 0) {
2452 suspense.resolve();
2453 }
2454 else {
2455 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2456 isSVG, slotScopeIds, optimized);
2457 setActiveBranch(suspense, newFallback);
2458 }
2459 }
2460 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2461 // toggled "back" to current active branch
2462 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2463 // force resolve
2464 suspense.resolve(true);
2465 }
2466 else {
2467 // switched to a 3rd branch
2468 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2469 if (suspense.deps <= 0) {
2470 suspense.resolve();
2471 }
2472 }
2473 }
2474 }
2475 else {
2476 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2477 // root did not change, just normal patch
2478 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2479 setActiveBranch(suspense, newBranch);
2480 }
2481 else {
2482 // root node toggled
2483 // invoke @pending event
2484 const onPending = n2.props && n2.props.onPending;
2485 if (isFunction(onPending)) {
2486 onPending();
2487 }
2488 // mount pending branch in off-dom container
2489 suspense.pendingBranch = newBranch;
2490 suspense.pendingId++;
2491 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2492 if (suspense.deps <= 0) {
2493 // incoming branch has no async deps, resolve now.
2494 suspense.resolve();
2495 }
2496 else {
2497 const { timeout, pendingId } = suspense;
2498 if (timeout > 0) {
2499 setTimeout(() => {
2500 if (suspense.pendingId === pendingId) {
2501 suspense.fallback(newFallback);
2502 }
2503 }, timeout);
2504 }
2505 else if (timeout === 0) {
2506 suspense.fallback(newFallback);
2507 }
2508 }
2509 }
2510 }
2511}
2512let hasWarned = false;
2513function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2514 /* istanbul ignore if */
2515 if (!hasWarned) {
2516 hasWarned = true;
2517 // @ts-ignore `console.info` cannot be null error
2518 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2519 }
2520 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2521 const timeout = toNumber(vnode.props && vnode.props.timeout);
2522 const suspense = {
2523 vnode,
2524 parent,
2525 parentComponent,
2526 isSVG,
2527 container,
2528 hiddenContainer,
2529 anchor,
2530 deps: 0,
2531 pendingId: 0,
2532 timeout: typeof timeout === 'number' ? timeout : -1,
2533 activeBranch: null,
2534 pendingBranch: null,
2535 isInFallback: true,
2536 isHydrating,
2537 isUnmounted: false,
2538 effects: [],
2539 resolve(resume = false) {
2540 {
2541 if (!resume && !suspense.pendingBranch) {
2542 throw new Error(`suspense.resolve() is called without a pending branch.`);
2543 }
2544 if (suspense.isUnmounted) {
2545 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2546 }
2547 }
2548 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2549 if (suspense.isHydrating) {
2550 suspense.isHydrating = false;
2551 }
2552 else if (!resume) {
2553 const delayEnter = activeBranch &&
2554 pendingBranch.transition &&
2555 pendingBranch.transition.mode === 'out-in';
2556 if (delayEnter) {
2557 activeBranch.transition.afterLeave = () => {
2558 if (pendingId === suspense.pendingId) {
2559 move(pendingBranch, container, anchor, 0 /* ENTER */);
2560 }
2561 };
2562 }
2563 // this is initial anchor on mount
2564 let { anchor } = suspense;
2565 // unmount current active tree
2566 if (activeBranch) {
2567 // if the fallback tree was mounted, it may have been moved
2568 // as part of a parent suspense. get the latest anchor for insertion
2569 anchor = next(activeBranch);
2570 unmount(activeBranch, parentComponent, suspense, true);
2571 }
2572 if (!delayEnter) {
2573 // move content from off-dom container to actual container
2574 move(pendingBranch, container, anchor, 0 /* ENTER */);
2575 }
2576 }
2577 setActiveBranch(suspense, pendingBranch);
2578 suspense.pendingBranch = null;
2579 suspense.isInFallback = false;
2580 // flush buffered effects
2581 // check if there is a pending parent suspense
2582 let parent = suspense.parent;
2583 let hasUnresolvedAncestor = false;
2584 while (parent) {
2585 if (parent.pendingBranch) {
2586 // found a pending parent suspense, merge buffered post jobs
2587 // into that parent
2588 parent.effects.push(...effects);
2589 hasUnresolvedAncestor = true;
2590 break;
2591 }
2592 parent = parent.parent;
2593 }
2594 // no pending parent suspense, flush all jobs
2595 if (!hasUnresolvedAncestor) {
2596 queuePostFlushCb(effects);
2597 }
2598 suspense.effects = [];
2599 // invoke @resolve event
2600 const onResolve = vnode.props && vnode.props.onResolve;
2601 if (isFunction(onResolve)) {
2602 onResolve();
2603 }
2604 },
2605 fallback(fallbackVNode) {
2606 if (!suspense.pendingBranch) {
2607 return;
2608 }
2609 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2610 // invoke @fallback event
2611 const onFallback = vnode.props && vnode.props.onFallback;
2612 if (isFunction(onFallback)) {
2613 onFallback();
2614 }
2615 const anchor = next(activeBranch);
2616 const mountFallback = () => {
2617 if (!suspense.isInFallback) {
2618 return;
2619 }
2620 // mount the fallback tree
2621 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2622 isSVG, slotScopeIds, optimized);
2623 setActiveBranch(suspense, fallbackVNode);
2624 };
2625 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
2626 if (delayEnter) {
2627 activeBranch.transition.afterLeave = mountFallback;
2628 }
2629 // unmount current active branch
2630 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
2631 true // shouldRemove
2632 );
2633 suspense.isInFallback = true;
2634 if (!delayEnter) {
2635 mountFallback();
2636 }
2637 },
2638 move(container, anchor, type) {
2639 suspense.activeBranch &&
2640 move(suspense.activeBranch, container, anchor, type);
2641 suspense.container = container;
2642 },
2643 next() {
2644 return suspense.activeBranch && next(suspense.activeBranch);
2645 },
2646 registerDep(instance, setupRenderEffect) {
2647 const isInPendingSuspense = !!suspense.pendingBranch;
2648 if (isInPendingSuspense) {
2649 suspense.deps++;
2650 }
2651 const hydratedEl = instance.vnode.el;
2652 instance
2653 .asyncDep.catch(err => {
2654 handleError(err, instance, 0 /* SETUP_FUNCTION */);
2655 })
2656 .then(asyncSetupResult => {
2657 // retry when the setup() promise resolves.
2658 // component may have been unmounted before resolve.
2659 if (instance.isUnmounted ||
2660 suspense.isUnmounted ||
2661 suspense.pendingId !== instance.suspenseId) {
2662 return;
2663 }
2664 // retry from this component
2665 instance.asyncResolved = true;
2666 const { vnode } = instance;
2667 {
2668 pushWarningContext(vnode);
2669 }
2670 handleSetupResult(instance, asyncSetupResult, false);
2671 if (hydratedEl) {
2672 // vnode may have been replaced if an update happened before the
2673 // async dep is resolved.
2674 vnode.el = hydratedEl;
2675 }
2676 const placeholder = !hydratedEl && instance.subTree.el;
2677 setupRenderEffect(instance, vnode,
2678 // component may have been moved before resolve.
2679 // if this is not a hydration, instance.subTree will be the comment
2680 // placeholder.
2681 parentNode(hydratedEl || instance.subTree.el),
2682 // anchor will not be used if this is hydration, so only need to
2683 // consider the comment placeholder case.
2684 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
2685 if (placeholder) {
2686 remove(placeholder);
2687 }
2688 updateHOCHostEl(instance, vnode.el);
2689 {
2690 popWarningContext();
2691 }
2692 // only decrease deps count if suspense is not already resolved
2693 if (isInPendingSuspense && --suspense.deps === 0) {
2694 suspense.resolve();
2695 }
2696 });
2697 },
2698 unmount(parentSuspense, doRemove) {
2699 suspense.isUnmounted = true;
2700 if (suspense.activeBranch) {
2701 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
2702 }
2703 if (suspense.pendingBranch) {
2704 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
2705 }
2706 }
2707 };
2708 return suspense;
2709}
2710function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
2711 /* eslint-disable no-restricted-globals */
2712 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
2713 // there are two possible scenarios for server-rendered suspense:
2714 // - success: ssr content should be fully resolved
2715 // - failure: ssr content should be the fallback branch.
2716 // however, on the client we don't really know if it has failed or not
2717 // attempt to hydrate the DOM assuming it has succeeded, but we still
2718 // need to construct a suspense boundary first
2719 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
2720 if (suspense.deps === 0) {
2721 suspense.resolve();
2722 }
2723 return result;
2724 /* eslint-enable no-restricted-globals */
2725}
2726function normalizeSuspenseChildren(vnode) {
2727 const { shapeFlag, children } = vnode;
2728 let content;
2729 let fallback;
2730 if (shapeFlag & 32 /* SLOTS_CHILDREN */) {
2731 content = normalizeSuspenseSlot(children.default);
2732 fallback = normalizeSuspenseSlot(children.fallback);
2733 }
2734 else {
2735 content = normalizeSuspenseSlot(children);
2736 fallback = normalizeVNode(null);
2737 }
2738 return {
2739 content,
2740 fallback
2741 };
2742}
2743function normalizeSuspenseSlot(s) {
2744 if (isFunction(s)) {
2745 s = s();
2746 }
2747 if (isArray(s)) {
2748 const singleChild = filterSingleRoot(s);
2749 if (!singleChild) {
2750 warn(`<Suspense> slots expect a single root node.`);
2751 }
2752 s = singleChild;
2753 }
2754 return normalizeVNode(s);
2755}
2756function queueEffectWithSuspense(fn, suspense) {
2757 if (suspense && suspense.pendingBranch) {
2758 if (isArray(fn)) {
2759 suspense.effects.push(...fn);
2760 }
2761 else {
2762 suspense.effects.push(fn);
2763 }
2764 }
2765 else {
2766 queuePostFlushCb(fn);
2767 }
2768}
2769function setActiveBranch(suspense, branch) {
2770 suspense.activeBranch = branch;
2771 const { vnode, parentComponent } = suspense;
2772 const el = (vnode.el = branch.el);
2773 // in case suspense is the root node of a component,
2774 // recursively update the HOC el
2775 if (parentComponent && parentComponent.subTree === vnode) {
2776 parentComponent.vnode.el = el;
2777 updateHOCHostEl(parentComponent, el);
2778 }
2779}
2780
2781function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
2782isSSR = false) {
2783 const props = {};
2784 const attrs = {};
2785 def(attrs, InternalObjectKey, 1);
2786 instance.propsDefaults = Object.create(null);
2787 setFullProps(instance, rawProps, props, attrs);
2788 // validation
2789 {
2790 validateProps(rawProps || {}, props, instance);
2791 }
2792 if (isStateful) {
2793 // stateful
2794 instance.props = isSSR ? props : shallowReactive(props);
2795 }
2796 else {
2797 if (!instance.type.props) {
2798 // functional w/ optional props, props === attrs
2799 instance.props = attrs;
2800 }
2801 else {
2802 // functional w/ declared props
2803 instance.props = props;
2804 }
2805 }
2806 instance.attrs = attrs;
2807}
2808function updateProps(instance, rawProps, rawPrevProps, optimized) {
2809 const { props, attrs, vnode: { patchFlag } } = instance;
2810 const rawCurrentProps = toRaw(props);
2811 const [options] = instance.propsOptions;
2812 if (
2813 // always force full diff in dev
2814 // - #1942 if hmr is enabled with sfc component
2815 // - vite#872 non-sfc component used by sfc component
2816 !((instance.type.__hmrId ||
2817 (instance.parent && instance.parent.type.__hmrId))) &&
2818 (optimized || patchFlag > 0) &&
2819 !(patchFlag & 16 /* FULL_PROPS */)) {
2820 if (patchFlag & 8 /* PROPS */) {
2821 // Compiler-generated props & no keys change, just set the updated
2822 // the props.
2823 const propsToUpdate = instance.vnode.dynamicProps;
2824 for (let i = 0; i < propsToUpdate.length; i++) {
2825 const key = propsToUpdate[i];
2826 // PROPS flag guarantees rawProps to be non-null
2827 const value = rawProps[key];
2828 if (options) {
2829 // attr / props separation was done on init and will be consistent
2830 // in this code path, so just check if attrs have it.
2831 if (hasOwn(attrs, key)) {
2832 attrs[key] = value;
2833 }
2834 else {
2835 const camelizedKey = camelize(key);
2836 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
2837 }
2838 }
2839 else {
2840 attrs[key] = value;
2841 }
2842 }
2843 }
2844 }
2845 else {
2846 // full props update.
2847 setFullProps(instance, rawProps, props, attrs);
2848 // in case of dynamic props, check if we need to delete keys from
2849 // the props object
2850 let kebabKey;
2851 for (const key in rawCurrentProps) {
2852 if (!rawProps ||
2853 // for camelCase
2854 (!hasOwn(rawProps, key) &&
2855 // it's possible the original props was passed in as kebab-case
2856 // and converted to camelCase (#955)
2857 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
2858 if (options) {
2859 if (rawPrevProps &&
2860 // for camelCase
2861 (rawPrevProps[key] !== undefined ||
2862 // for kebab-case
2863 rawPrevProps[kebabKey] !== undefined)) {
2864 props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
2865 }
2866 }
2867 else {
2868 delete props[key];
2869 }
2870 }
2871 }
2872 // in the case of functional component w/o props declaration, props and
2873 // attrs point to the same object so it should already have been updated.
2874 if (attrs !== rawCurrentProps) {
2875 for (const key in attrs) {
2876 if (!rawProps || !hasOwn(rawProps, key)) {
2877 delete attrs[key];
2878 }
2879 }
2880 }
2881 }
2882 // trigger updates for $attrs in case it's used in component slots
2883 trigger(instance, "set" /* SET */, '$attrs');
2884 {
2885 validateProps(rawProps || {}, props, instance);
2886 }
2887}
2888function setFullProps(instance, rawProps, props, attrs) {
2889 const [options, needCastKeys] = instance.propsOptions;
2890 if (rawProps) {
2891 for (const key in rawProps) {
2892 const value = rawProps[key];
2893 // key, ref are reserved and never passed down
2894 if (isReservedProp(key)) {
2895 continue;
2896 }
2897 // prop option names are camelized during normalization, so to support
2898 // kebab -> camel conversion here we need to camelize the key.
2899 let camelKey;
2900 if (options && hasOwn(options, (camelKey = camelize(key)))) {
2901 props[camelKey] = value;
2902 }
2903 else if (!isEmitListener(instance.emitsOptions, key)) {
2904 // Any non-declared (either as a prop or an emitted event) props are put
2905 // into a separate `attrs` object for spreading. Make sure to preserve
2906 // original key casing
2907 attrs[key] = value;
2908 }
2909 }
2910 }
2911 if (needCastKeys) {
2912 const rawCurrentProps = toRaw(props);
2913 for (let i = 0; i < needCastKeys.length; i++) {
2914 const key = needCastKeys[i];
2915 props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
2916 }
2917 }
2918}
2919function resolvePropValue(options, props, key, value, instance) {
2920 const opt = options[key];
2921 if (opt != null) {
2922 const hasDefault = hasOwn(opt, 'default');
2923 // default values
2924 if (hasDefault && value === undefined) {
2925 const defaultValue = opt.default;
2926 if (opt.type !== Function && isFunction(defaultValue)) {
2927 const { propsDefaults } = instance;
2928 if (key in propsDefaults) {
2929 value = propsDefaults[key];
2930 }
2931 else {
2932 setCurrentInstance(instance);
2933 value = propsDefaults[key] = defaultValue(props);
2934 setCurrentInstance(null);
2935 }
2936 }
2937 else {
2938 value = defaultValue;
2939 }
2940 }
2941 // boolean casting
2942 if (opt[0 /* shouldCast */]) {
2943 if (!hasOwn(props, key) && !hasDefault) {
2944 value = false;
2945 }
2946 else if (opt[1 /* shouldCastTrue */] &&
2947 (value === '' || value === hyphenate(key))) {
2948 value = true;
2949 }
2950 }
2951 }
2952 return value;
2953}
2954function normalizePropsOptions(comp, appContext, asMixin = false) {
2955 if (!appContext.deopt && comp.__props) {
2956 return comp.__props;
2957 }
2958 const raw = comp.props;
2959 const normalized = {};
2960 const needCastKeys = [];
2961 // apply mixin/extends props
2962 let hasExtends = false;
2963 if (!isFunction(comp)) {
2964 const extendProps = (raw) => {
2965 hasExtends = true;
2966 const [props, keys] = normalizePropsOptions(raw, appContext, true);
2967 extend(normalized, props);
2968 if (keys)
2969 needCastKeys.push(...keys);
2970 };
2971 if (!asMixin && appContext.mixins.length) {
2972 appContext.mixins.forEach(extendProps);
2973 }
2974 if (comp.extends) {
2975 extendProps(comp.extends);
2976 }
2977 if (comp.mixins) {
2978 comp.mixins.forEach(extendProps);
2979 }
2980 }
2981 if (!raw && !hasExtends) {
2982 return (comp.__props = EMPTY_ARR);
2983 }
2984 if (isArray(raw)) {
2985 for (let i = 0; i < raw.length; i++) {
2986 if (!isString(raw[i])) {
2987 warn(`props must be strings when using array syntax.`, raw[i]);
2988 }
2989 const normalizedKey = camelize(raw[i]);
2990 if (validatePropName(normalizedKey)) {
2991 normalized[normalizedKey] = EMPTY_OBJ;
2992 }
2993 }
2994 }
2995 else if (raw) {
2996 if (!isObject(raw)) {
2997 warn(`invalid props options`, raw);
2998 }
2999 for (const key in raw) {
3000 const normalizedKey = camelize(key);
3001 if (validatePropName(normalizedKey)) {
3002 const opt = raw[key];
3003 const prop = (normalized[normalizedKey] =
3004 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
3005 if (prop) {
3006 const booleanIndex = getTypeIndex(Boolean, prop.type);
3007 const stringIndex = getTypeIndex(String, prop.type);
3008 prop[0 /* shouldCast */] = booleanIndex > -1;
3009 prop[1 /* shouldCastTrue */] =
3010 stringIndex < 0 || booleanIndex < stringIndex;
3011 // if the prop needs boolean casting or default value
3012 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
3013 needCastKeys.push(normalizedKey);
3014 }
3015 }
3016 }
3017 }
3018 }
3019 return (comp.__props = [normalized, needCastKeys]);
3020}
3021function validatePropName(key) {
3022 if (key[0] !== '$') {
3023 return true;
3024 }
3025 else {
3026 warn(`Invalid prop name: "${key}" is a reserved property.`);
3027 }
3028 return false;
3029}
3030// use function string name to check type constructors
3031// so that it works across vms / iframes.
3032function getType(ctor) {
3033 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
3034 return match ? match[1] : '';
3035}
3036function isSameType(a, b) {
3037 return getType(a) === getType(b);
3038}
3039function getTypeIndex(type, expectedTypes) {
3040 if (isArray(expectedTypes)) {
3041 return expectedTypes.findIndex(t => isSameType(t, type));
3042 }
3043 else if (isFunction(expectedTypes)) {
3044 return isSameType(expectedTypes, type) ? 0 : -1;
3045 }
3046 return -1;
3047}
3048/**
3049 * dev only
3050 */
3051function validateProps(rawProps, props, instance) {
3052 const resolvedValues = toRaw(props);
3053 const options = instance.propsOptions[0];
3054 for (const key in options) {
3055 let opt = options[key];
3056 if (opt == null)
3057 continue;
3058 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
3059 }
3060}
3061/**
3062 * dev only
3063 */
3064function validateProp(name, value, prop, isAbsent) {
3065 const { type, required, validator } = prop;
3066 // required!
3067 if (required && isAbsent) {
3068 warn('Missing required prop: "' + name + '"');
3069 return;
3070 }
3071 // missing but optional
3072 if (value == null && !prop.required) {
3073 return;
3074 }
3075 // type check
3076 if (type != null && type !== true) {
3077 let isValid = false;
3078 const types = isArray(type) ? type : [type];
3079 const expectedTypes = [];
3080 // value is valid as long as one of the specified types match
3081 for (let i = 0; i < types.length && !isValid; i++) {
3082 const { valid, expectedType } = assertType(value, types[i]);
3083 expectedTypes.push(expectedType || '');
3084 isValid = valid;
3085 }
3086 if (!isValid) {
3087 warn(getInvalidTypeMessage(name, value, expectedTypes));
3088 return;
3089 }
3090 }
3091 // custom validator
3092 if (validator && !validator(value)) {
3093 warn('Invalid prop: custom validator check failed for prop "' + name + '".');
3094 }
3095}
3096const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
3097/**
3098 * dev only
3099 */
3100function assertType(value, type) {
3101 let valid;
3102 const expectedType = getType(type);
3103 if (isSimpleType(expectedType)) {
3104 const t = typeof value;
3105 valid = t === expectedType.toLowerCase();
3106 // for primitive wrapper objects
3107 if (!valid && t === 'object') {
3108 valid = value instanceof type;
3109 }
3110 }
3111 else if (expectedType === 'Object') {
3112 valid = isObject(value);
3113 }
3114 else if (expectedType === 'Array') {
3115 valid = isArray(value);
3116 }
3117 else {
3118 valid = value instanceof type;
3119 }
3120 return {
3121 valid,
3122 expectedType
3123 };
3124}
3125/**
3126 * dev only
3127 */
3128function getInvalidTypeMessage(name, value, expectedTypes) {
3129 let message = `Invalid prop: type check failed for prop "${name}".` +
3130 ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
3131 const expectedType = expectedTypes[0];
3132 const receivedType = toRawType(value);
3133 const expectedValue = styleValue(value, expectedType);
3134 const receivedValue = styleValue(value, receivedType);
3135 // check if we need to specify expected value
3136 if (expectedTypes.length === 1 &&
3137 isExplicable(expectedType) &&
3138 !isBoolean(expectedType, receivedType)) {
3139 message += ` with value ${expectedValue}`;
3140 }
3141 message += `, got ${receivedType} `;
3142 // check if we need to specify received value
3143 if (isExplicable(receivedType)) {
3144 message += `with value ${receivedValue}.`;
3145 }
3146 return message;
3147}
3148/**
3149 * dev only
3150 */
3151function styleValue(value, type) {
3152 if (type === 'String') {
3153 return `"${value}"`;
3154 }
3155 else if (type === 'Number') {
3156 return `${Number(value)}`;
3157 }
3158 else {
3159 return `${value}`;
3160 }
3161}
3162/**
3163 * dev only
3164 */
3165function isExplicable(type) {
3166 const explicitTypes = ['string', 'number', 'boolean'];
3167 return explicitTypes.some(elem => type.toLowerCase() === elem);
3168}
3169/**
3170 * dev only
3171 */
3172function isBoolean(...args) {
3173 return args.some(elem => elem.toLowerCase() === 'boolean');
3174}
3175
3176function injectHook(type, hook, target = currentInstance, prepend = false) {
3177 if (target) {
3178 const hooks = target[type] || (target[type] = []);
3179 // cache the error handling wrapper for injected hooks so the same hook
3180 // can be properly deduped by the scheduler. "__weh" stands for "with error
3181 // handling".
3182 const wrappedHook = hook.__weh ||
3183 (hook.__weh = (...args) => {
3184 if (target.isUnmounted) {
3185 return;
3186 }
3187 // disable tracking inside all lifecycle hooks
3188 // since they can potentially be called inside effects.
3189 pauseTracking();
3190 // Set currentInstance during hook invocation.
3191 // This assumes the hook does not synchronously trigger other hooks, which
3192 // can only be false when the user does something really funky.
3193 setCurrentInstance(target);
3194 const res = callWithAsyncErrorHandling(hook, target, type, args);
3195 setCurrentInstance(null);
3196 resetTracking();
3197 return res;
3198 });
3199 if (prepend) {
3200 hooks.unshift(wrappedHook);
3201 }
3202 else {
3203 hooks.push(wrappedHook);
3204 }
3205 return wrappedHook;
3206 }
3207 else {
3208 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
3209 warn(`${apiName} is called when there is no active component instance to be ` +
3210 `associated with. ` +
3211 `Lifecycle injection APIs can only be used during execution of setup().` +
3212 (` If you are using async setup(), make sure to register lifecycle ` +
3213 `hooks before the first await statement.`
3214 ));
3215 }
3216}
3217const createHook = (lifecycle) => (hook, target = currentInstance) =>
3218// post-create lifecycle registrations are noops during SSR
3219!isInSSRComponentSetup && injectHook(lifecycle, hook, target);
3220const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
3221const onMounted = createHook("m" /* MOUNTED */);
3222const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
3223const onUpdated = createHook("u" /* UPDATED */);
3224const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
3225const onUnmounted = createHook("um" /* UNMOUNTED */);
3226const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
3227const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
3228const onErrorCaptured = (hook, target = currentInstance) => {
3229 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
3230};
3231
3232// Simple effect.
3233function watchEffect(effect, options) {
3234 return doWatch(effect, null, options);
3235}
3236// initial value for watchers to trigger on undefined initial values
3237const INITIAL_WATCHER_VALUE = {};
3238// implementation
3239function watch(source, cb, options) {
3240 if (!isFunction(cb)) {
3241 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3242 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3243 `supports \`watch(source, cb, options?) signature.`);
3244 }
3245 return doWatch(source, cb, options);
3246}
3247function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
3248 if (!cb) {
3249 if (immediate !== undefined) {
3250 warn(`watch() "immediate" option is only respected when using the ` +
3251 `watch(source, callback, options?) signature.`);
3252 }
3253 if (deep !== undefined) {
3254 warn(`watch() "deep" option is only respected when using the ` +
3255 `watch(source, callback, options?) signature.`);
3256 }
3257 }
3258 const warnInvalidSource = (s) => {
3259 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3260 `a reactive object, or an array of these types.`);
3261 };
3262 let getter;
3263 let forceTrigger = false;
3264 if (isRef(source)) {
3265 getter = () => source.value;
3266 forceTrigger = !!source._shallow;
3267 }
3268 else if (isReactive(source)) {
3269 getter = () => source;
3270 deep = true;
3271 }
3272 else if (isArray(source)) {
3273 getter = () => source.map(s => {
3274 if (isRef(s)) {
3275 return s.value;
3276 }
3277 else if (isReactive(s)) {
3278 return traverse(s);
3279 }
3280 else if (isFunction(s)) {
3281 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */, [
3282 instance && instance.proxy
3283 ]);
3284 }
3285 else {
3286 warnInvalidSource(s);
3287 }
3288 });
3289 }
3290 else if (isFunction(source)) {
3291 if (cb) {
3292 // getter with cb
3293 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */, [
3294 instance && instance.proxy
3295 ]);
3296 }
3297 else {
3298 // no cb -> simple effect
3299 getter = () => {
3300 if (instance && instance.isUnmounted) {
3301 return;
3302 }
3303 if (cleanup) {
3304 cleanup();
3305 }
3306 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
3307 };
3308 }
3309 }
3310 else {
3311 getter = NOOP;
3312 warnInvalidSource(source);
3313 }
3314 if (cb && deep) {
3315 const baseGetter = getter;
3316 getter = () => traverse(baseGetter());
3317 }
3318 let cleanup;
3319 let onInvalidate = (fn) => {
3320 cleanup = runner.options.onStop = () => {
3321 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3322 };
3323 };
3324 let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
3325 const job = () => {
3326 if (!runner.active) {
3327 return;
3328 }
3329 if (cb) {
3330 // watch(source, cb)
3331 const newValue = runner();
3332 if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
3333 // cleanup before running cb again
3334 if (cleanup) {
3335 cleanup();
3336 }
3337 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3338 newValue,
3339 // pass undefined as the old value when it's changed for the first time
3340 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3341 onInvalidate
3342 ]);
3343 oldValue = newValue;
3344 }
3345 }
3346 else {
3347 // watchEffect
3348 runner();
3349 }
3350 };
3351 // important: mark the job as a watcher callback so that scheduler knows
3352 // it is allowed to self-trigger (#1727)
3353 job.allowRecurse = !!cb;
3354 let scheduler;
3355 if (flush === 'sync') {
3356 scheduler = job;
3357 }
3358 else if (flush === 'post') {
3359 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3360 }
3361 else {
3362 // default: 'pre'
3363 scheduler = () => {
3364 if (!instance || instance.isMounted) {
3365 queuePreFlushCb(job);
3366 }
3367 else {
3368 // with 'pre' option, the first call must happen before
3369 // the component is mounted so it is called synchronously.
3370 job();
3371 }
3372 };
3373 }
3374 const runner = effect(getter, {
3375 lazy: true,
3376 onTrack,
3377 onTrigger,
3378 scheduler
3379 });
3380 recordInstanceBoundEffect(runner, instance);
3381 // initial run
3382 if (cb) {
3383 if (immediate) {
3384 job();
3385 }
3386 else {
3387 oldValue = runner();
3388 }
3389 }
3390 else if (flush === 'post') {
3391 queuePostRenderEffect(runner, instance && instance.suspense);
3392 }
3393 else {
3394 runner();
3395 }
3396 return () => {
3397 stop(runner);
3398 if (instance) {
3399 remove(instance.effects, runner);
3400 }
3401 };
3402}
3403// this.$watch
3404function instanceWatch(source, cb, options) {
3405 const publicThis = this.proxy;
3406 const getter = isString(source)
3407 ? () => publicThis[source]
3408 : source.bind(publicThis);
3409 return doWatch(getter, cb.bind(publicThis), options, this);
3410}
3411function traverse(value, seen = new Set()) {
3412 if (!isObject(value) || seen.has(value)) {
3413 return value;
3414 }
3415 seen.add(value);
3416 if (isRef(value)) {
3417 traverse(value.value, seen);
3418 }
3419 else if (isArray(value)) {
3420 for (let i = 0; i < value.length; i++) {
3421 traverse(value[i], seen);
3422 }
3423 }
3424 else if (isSet(value) || isMap(value)) {
3425 value.forEach((v) => {
3426 traverse(v, seen);
3427 });
3428 }
3429 else {
3430 for (const key in value) {
3431 traverse(value[key], seen);
3432 }
3433 }
3434 return value;
3435}
3436
3437function useTransitionState() {
3438 const state = {
3439 isMounted: false,
3440 isLeaving: false,
3441 isUnmounting: false,
3442 leavingVNodes: new Map()
3443 };
3444 onMounted(() => {
3445 state.isMounted = true;
3446 });
3447 onBeforeUnmount(() => {
3448 state.isUnmounting = true;
3449 });
3450 return state;
3451}
3452const TransitionHookValidator = [Function, Array];
3453const BaseTransitionImpl = {
3454 name: `BaseTransition`,
3455 props: {
3456 mode: String,
3457 appear: Boolean,
3458 persisted: Boolean,
3459 // enter
3460 onBeforeEnter: TransitionHookValidator,
3461 onEnter: TransitionHookValidator,
3462 onAfterEnter: TransitionHookValidator,
3463 onEnterCancelled: TransitionHookValidator,
3464 // leave
3465 onBeforeLeave: TransitionHookValidator,
3466 onLeave: TransitionHookValidator,
3467 onAfterLeave: TransitionHookValidator,
3468 onLeaveCancelled: TransitionHookValidator,
3469 // appear
3470 onBeforeAppear: TransitionHookValidator,
3471 onAppear: TransitionHookValidator,
3472 onAfterAppear: TransitionHookValidator,
3473 onAppearCancelled: TransitionHookValidator
3474 },
3475 setup(props, { slots }) {
3476 const instance = getCurrentInstance();
3477 const state = useTransitionState();
3478 let prevTransitionKey;
3479 return () => {
3480 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3481 if (!children || !children.length) {
3482 return;
3483 }
3484 // warn multiple elements
3485 if (children.length > 1) {
3486 warn('<transition> can only be used on a single element or component. Use ' +
3487 '<transition-group> for lists.');
3488 }
3489 // there's no need to track reactivity for these props so use the raw
3490 // props for a bit better perf
3491 const rawProps = toRaw(props);
3492 const { mode } = rawProps;
3493 // check mode
3494 if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
3495 warn(`invalid <transition> mode: ${mode}`);
3496 }
3497 // at this point children has a guaranteed length of 1.
3498 const child = children[0];
3499 if (state.isLeaving) {
3500 return emptyPlaceholder(child);
3501 }
3502 // in the case of <transition><keep-alive/></transition>, we need to
3503 // compare the type of the kept-alive children.
3504 const innerChild = getKeepAliveChild(child);
3505 if (!innerChild) {
3506 return emptyPlaceholder(child);
3507 }
3508 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3509 setTransitionHooks(innerChild, enterHooks);
3510 const oldChild = instance.subTree;
3511 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3512 let transitionKeyChanged = false;
3513 const { getTransitionKey } = innerChild.type;
3514 if (getTransitionKey) {
3515 const key = getTransitionKey();
3516 if (prevTransitionKey === undefined) {
3517 prevTransitionKey = key;
3518 }
3519 else if (key !== prevTransitionKey) {
3520 prevTransitionKey = key;
3521 transitionKeyChanged = true;
3522 }
3523 }
3524 // handle mode
3525 if (oldInnerChild &&
3526 oldInnerChild.type !== Comment &&
3527 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3528 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3529 // update old tree's hooks in case of dynamic transition
3530 setTransitionHooks(oldInnerChild, leavingHooks);
3531 // switching between different views
3532 if (mode === 'out-in') {
3533 state.isLeaving = true;
3534 // return placeholder node and queue update when leave finishes
3535 leavingHooks.afterLeave = () => {
3536 state.isLeaving = false;
3537 instance.update();
3538 };
3539 return emptyPlaceholder(child);
3540 }
3541 else if (mode === 'in-out' && innerChild.type !== Comment) {
3542 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3543 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3544 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3545 // early removal callback
3546 el._leaveCb = () => {
3547 earlyRemove();
3548 el._leaveCb = undefined;
3549 delete enterHooks.delayedLeave;
3550 };
3551 enterHooks.delayedLeave = delayedLeave;
3552 };
3553 }
3554 }
3555 return child;
3556 };
3557 }
3558};
3559// export the public type for h/tsx inference
3560// also to avoid inline import() in generated d.ts files
3561const BaseTransition = BaseTransitionImpl;
3562function getLeavingNodesForType(state, vnode) {
3563 const { leavingVNodes } = state;
3564 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3565 if (!leavingVNodesCache) {
3566 leavingVNodesCache = Object.create(null);
3567 leavingVNodes.set(vnode.type, leavingVNodesCache);
3568 }
3569 return leavingVNodesCache;
3570}
3571// The transition hooks are attached to the vnode as vnode.transition
3572// and will be called at appropriate timing in the renderer.
3573function resolveTransitionHooks(vnode, props, state, instance) {
3574 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3575 const key = String(vnode.key);
3576 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3577 const callHook = (hook, args) => {
3578 hook &&
3579 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3580 };
3581 const hooks = {
3582 mode,
3583 persisted,
3584 beforeEnter(el) {
3585 let hook = onBeforeEnter;
3586 if (!state.isMounted) {
3587 if (appear) {
3588 hook = onBeforeAppear || onBeforeEnter;
3589 }
3590 else {
3591 return;
3592 }
3593 }
3594 // for same element (v-show)
3595 if (el._leaveCb) {
3596 el._leaveCb(true /* cancelled */);
3597 }
3598 // for toggled element with same key (v-if)
3599 const leavingVNode = leavingVNodesCache[key];
3600 if (leavingVNode &&
3601 isSameVNodeType(vnode, leavingVNode) &&
3602 leavingVNode.el._leaveCb) {
3603 // force early removal (not cancelled)
3604 leavingVNode.el._leaveCb();
3605 }
3606 callHook(hook, [el]);
3607 },
3608 enter(el) {
3609 let hook = onEnter;
3610 let afterHook = onAfterEnter;
3611 let cancelHook = onEnterCancelled;
3612 if (!state.isMounted) {
3613 if (appear) {
3614 hook = onAppear || onEnter;
3615 afterHook = onAfterAppear || onAfterEnter;
3616 cancelHook = onAppearCancelled || onEnterCancelled;
3617 }
3618 else {
3619 return;
3620 }
3621 }
3622 let called = false;
3623 const done = (el._enterCb = (cancelled) => {
3624 if (called)
3625 return;
3626 called = true;
3627 if (cancelled) {
3628 callHook(cancelHook, [el]);
3629 }
3630 else {
3631 callHook(afterHook, [el]);
3632 }
3633 if (hooks.delayedLeave) {
3634 hooks.delayedLeave();
3635 }
3636 el._enterCb = undefined;
3637 });
3638 if (hook) {
3639 hook(el, done);
3640 if (hook.length <= 1) {
3641 done();
3642 }
3643 }
3644 else {
3645 done();
3646 }
3647 },
3648 leave(el, remove) {
3649 const key = String(vnode.key);
3650 if (el._enterCb) {
3651 el._enterCb(true /* cancelled */);
3652 }
3653 if (state.isUnmounting) {
3654 return remove();
3655 }
3656 callHook(onBeforeLeave, [el]);
3657 let called = false;
3658 const done = (el._leaveCb = (cancelled) => {
3659 if (called)
3660 return;
3661 called = true;
3662 remove();
3663 if (cancelled) {
3664 callHook(onLeaveCancelled, [el]);
3665 }
3666 else {
3667 callHook(onAfterLeave, [el]);
3668 }
3669 el._leaveCb = undefined;
3670 if (leavingVNodesCache[key] === vnode) {
3671 delete leavingVNodesCache[key];
3672 }
3673 });
3674 leavingVNodesCache[key] = vnode;
3675 if (onLeave) {
3676 onLeave(el, done);
3677 if (onLeave.length <= 1) {
3678 done();
3679 }
3680 }
3681 else {
3682 done();
3683 }
3684 },
3685 clone(vnode) {
3686 return resolveTransitionHooks(vnode, props, state, instance);
3687 }
3688 };
3689 return hooks;
3690}
3691// the placeholder really only handles one special case: KeepAlive
3692// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3693// placeholder with empty content to avoid the KeepAlive instance from being
3694// unmounted.
3695function emptyPlaceholder(vnode) {
3696 if (isKeepAlive(vnode)) {
3697 vnode = cloneVNode(vnode);
3698 vnode.children = null;
3699 return vnode;
3700 }
3701}
3702function getKeepAliveChild(vnode) {
3703 return isKeepAlive(vnode)
3704 ? vnode.children
3705 ? vnode.children[0]
3706 : undefined
3707 : vnode;
3708}
3709function setTransitionHooks(vnode, hooks) {
3710 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3711 setTransitionHooks(vnode.component.subTree, hooks);
3712 }
3713 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3714 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3715 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3716 }
3717 else {
3718 vnode.transition = hooks;
3719 }
3720}
3721function getTransitionRawChildren(children, keepComment = false) {
3722 let ret = [];
3723 let keyedFragmentCount = 0;
3724 for (let i = 0; i < children.length; i++) {
3725 const child = children[i];
3726 // handle fragment children case, e.g. v-for
3727 if (child.type === Fragment) {
3728 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3729 keyedFragmentCount++;
3730 ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
3731 }
3732 // comment placeholders should be skipped, e.g. v-if
3733 else if (keepComment || child.type !== Comment) {
3734 ret.push(child);
3735 }
3736 }
3737 // #1126 if a transition children list contains multiple sub fragments, these
3738 // fragments will be merged into a flat children array. Since each v-for
3739 // fragment may contain different static bindings inside, we need to de-op
3740 // these children to force full diffs to ensure correct behavior.
3741 if (keyedFragmentCount > 1) {
3742 for (let i = 0; i < ret.length; i++) {
3743 ret[i].patchFlag = -2 /* BAIL */;
3744 }
3745 }
3746 return ret;
3747}
3748
3749const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3750const KeepAliveImpl = {
3751 name: `KeepAlive`,
3752 // Marker for special handling inside the renderer. We are not using a ===
3753 // check directly on KeepAlive in the renderer, because importing it directly
3754 // would prevent it from being tree-shaken.
3755 __isKeepAlive: true,
3756 props: {
3757 include: [String, RegExp, Array],
3758 exclude: [String, RegExp, Array],
3759 max: [String, Number]
3760 },
3761 setup(props, { slots }) {
3762 const instance = getCurrentInstance();
3763 // KeepAlive communicates with the instantiated renderer via the
3764 // ctx where the renderer passes in its internals,
3765 // and the KeepAlive instance exposes activate/deactivate implementations.
3766 // The whole point of this is to avoid importing KeepAlive directly in the
3767 // renderer to facilitate tree-shaking.
3768 const sharedContext = instance.ctx;
3769 // if the internal renderer is not registered, it indicates that this is server-side rendering,
3770 // for KeepAlive, we just need to render its children
3771 if (!sharedContext.renderer) {
3772 return slots.default;
3773 }
3774 const cache = new Map();
3775 const keys = new Set();
3776 let current = null;
3777 const parentSuspense = instance.suspense;
3778 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3779 const storageContainer = createElement('div');
3780 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3781 const instance = vnode.component;
3782 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3783 // in case props have changed
3784 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3785 queuePostRenderEffect(() => {
3786 instance.isDeactivated = false;
3787 if (instance.a) {
3788 invokeArrayFns(instance.a);
3789 }
3790 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3791 if (vnodeHook) {
3792 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3793 }
3794 }, parentSuspense);
3795 };
3796 sharedContext.deactivate = (vnode) => {
3797 const instance = vnode.component;
3798 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3799 queuePostRenderEffect(() => {
3800 if (instance.da) {
3801 invokeArrayFns(instance.da);
3802 }
3803 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3804 if (vnodeHook) {
3805 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3806 }
3807 instance.isDeactivated = true;
3808 }, parentSuspense);
3809 };
3810 function unmount(vnode) {
3811 // reset the shapeFlag so it can be properly unmounted
3812 resetShapeFlag(vnode);
3813 _unmount(vnode, instance, parentSuspense);
3814 }
3815 function pruneCache(filter) {
3816 cache.forEach((vnode, key) => {
3817 const name = getComponentName(vnode.type);
3818 if (name && (!filter || !filter(name))) {
3819 pruneCacheEntry(key);
3820 }
3821 });
3822 }
3823 function pruneCacheEntry(key) {
3824 const cached = cache.get(key);
3825 if (!current || cached.type !== current.type) {
3826 unmount(cached);
3827 }
3828 else if (current) {
3829 // current active instance should no longer be kept-alive.
3830 // we can't unmount it now but it might be later, so reset its flag now.
3831 resetShapeFlag(current);
3832 }
3833 cache.delete(key);
3834 keys.delete(key);
3835 }
3836 // prune cache on include/exclude prop change
3837 watch(() => [props.include, props.exclude], ([include, exclude]) => {
3838 include && pruneCache(name => matches(include, name));
3839 exclude && pruneCache(name => !matches(exclude, name));
3840 },
3841 // prune post-render after `current` has been updated
3842 { flush: 'post', deep: true });
3843 // cache sub tree after render
3844 let pendingCacheKey = null;
3845 const cacheSubtree = () => {
3846 // fix #1621, the pendingCacheKey could be 0
3847 if (pendingCacheKey != null) {
3848 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
3849 }
3850 };
3851 onMounted(cacheSubtree);
3852 onUpdated(cacheSubtree);
3853 onBeforeUnmount(() => {
3854 cache.forEach(cached => {
3855 const { subTree, suspense } = instance;
3856 const vnode = getInnerChild(subTree);
3857 if (cached.type === vnode.type) {
3858 // current instance will be unmounted as part of keep-alive's unmount
3859 resetShapeFlag(vnode);
3860 // but invoke its deactivated hook here
3861 const da = vnode.component.da;
3862 da && queuePostRenderEffect(da, suspense);
3863 return;
3864 }
3865 unmount(cached);
3866 });
3867 });
3868 return () => {
3869 pendingCacheKey = null;
3870 if (!slots.default) {
3871 return null;
3872 }
3873 const children = slots.default();
3874 const rawVNode = children[0];
3875 if (children.length > 1) {
3876 {
3877 warn(`KeepAlive should contain exactly one component child.`);
3878 }
3879 current = null;
3880 return children;
3881 }
3882 else if (!isVNode(rawVNode) ||
3883 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
3884 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
3885 current = null;
3886 return rawVNode;
3887 }
3888 let vnode = getInnerChild(rawVNode);
3889 const comp = vnode.type;
3890 const name = getComponentName(comp);
3891 const { include, exclude, max } = props;
3892 if ((include && (!name || !matches(include, name))) ||
3893 (exclude && name && matches(exclude, name))) {
3894 current = vnode;
3895 return rawVNode;
3896 }
3897 const key = vnode.key == null ? comp : vnode.key;
3898 const cachedVNode = cache.get(key);
3899 // clone vnode if it's reused because we are going to mutate it
3900 if (vnode.el) {
3901 vnode = cloneVNode(vnode);
3902 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
3903 rawVNode.ssContent = vnode;
3904 }
3905 }
3906 // #1513 it's possible for the returned vnode to be cloned due to attr
3907 // fallthrough or scopeId, so the vnode here may not be the final vnode
3908 // that is mounted. Instead of caching it directly, we store the pending
3909 // key and cache `instance.subTree` (the normalized vnode) in
3910 // beforeMount/beforeUpdate hooks.
3911 pendingCacheKey = key;
3912 if (cachedVNode) {
3913 // copy over mounted state
3914 vnode.el = cachedVNode.el;
3915 vnode.component = cachedVNode.component;
3916 if (vnode.transition) {
3917 // recursively update transition hooks on subTree
3918 setTransitionHooks(vnode, vnode.transition);
3919 }
3920 // avoid vnode being mounted as fresh
3921 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
3922 // make this key the freshest
3923 keys.delete(key);
3924 keys.add(key);
3925 }
3926 else {
3927 keys.add(key);
3928 // prune oldest entry
3929 if (max && keys.size > parseInt(max, 10)) {
3930 pruneCacheEntry(keys.values().next().value);
3931 }
3932 }
3933 // avoid vnode being unmounted
3934 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
3935 current = vnode;
3936 return rawVNode;
3937 };
3938 }
3939};
3940// export the public type for h/tsx inference
3941// also to avoid inline import() in generated d.ts files
3942const KeepAlive = KeepAliveImpl;
3943function matches(pattern, name) {
3944 if (isArray(pattern)) {
3945 return pattern.some((p) => matches(p, name));
3946 }
3947 else if (isString(pattern)) {
3948 return pattern.split(',').indexOf(name) > -1;
3949 }
3950 else if (pattern.test) {
3951 return pattern.test(name);
3952 }
3953 /* istanbul ignore next */
3954 return false;
3955}
3956function onActivated(hook, target) {
3957 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
3958}
3959function onDeactivated(hook, target) {
3960 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
3961}
3962function registerKeepAliveHook(hook, type, target = currentInstance) {
3963 // cache the deactivate branch check wrapper for injected hooks so the same
3964 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
3965 // deactivation check".
3966 const wrappedHook = hook.__wdc ||
3967 (hook.__wdc = () => {
3968 // only fire the hook if the target instance is NOT in a deactivated branch.
3969 let current = target;
3970 while (current) {
3971 if (current.isDeactivated) {
3972 return;
3973 }
3974 current = current.parent;
3975 }
3976 hook();
3977 });
3978 injectHook(type, wrappedHook, target);
3979 // In addition to registering it on the target instance, we walk up the parent
3980 // chain and register it on all ancestor instances that are keep-alive roots.
3981 // This avoids the need to walk the entire component tree when invoking these
3982 // hooks, and more importantly, avoids the need to track child components in
3983 // arrays.
3984 if (target) {
3985 let current = target.parent;
3986 while (current && current.parent) {
3987 if (isKeepAlive(current.parent.vnode)) {
3988 injectToKeepAliveRoot(wrappedHook, type, target, current);
3989 }
3990 current = current.parent;
3991 }
3992 }
3993}
3994function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
3995 // injectHook wraps the original for error handling, so make sure to remove
3996 // the wrapped version.
3997 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
3998 onUnmounted(() => {
3999 remove(keepAliveRoot[type], injected);
4000 }, target);
4001}
4002function resetShapeFlag(vnode) {
4003 let shapeFlag = vnode.shapeFlag;
4004 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
4005 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
4006 }
4007 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
4008 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
4009 }
4010 vnode.shapeFlag = shapeFlag;
4011}
4012function getInnerChild(vnode) {
4013 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
4014}
4015
4016const isInternalKey = (key) => key[0] === '_' || key === '$stable';
4017const normalizeSlotValue = (value) => isArray(value)
4018 ? value.map(normalizeVNode)
4019 : [normalizeVNode(value)];
4020const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => {
4021 if (currentInstance) {
4022 warn(`Slot "${key}" invoked outside of the render function: ` +
4023 `this will not track dependencies used in the slot. ` +
4024 `Invoke the slot function inside the render function instead.`);
4025 }
4026 return normalizeSlotValue(rawSlot(props));
4027}, ctx);
4028const normalizeObjectSlots = (rawSlots, slots) => {
4029 const ctx = rawSlots._ctx;
4030 for (const key in rawSlots) {
4031 if (isInternalKey(key))
4032 continue;
4033 const value = rawSlots[key];
4034 if (isFunction(value)) {
4035 slots[key] = normalizeSlot(key, value, ctx);
4036 }
4037 else if (value != null) {
4038 {
4039 warn(`Non-function value encountered for slot "${key}". ` +
4040 `Prefer function slots for better performance.`);
4041 }
4042 const normalized = normalizeSlotValue(value);
4043 slots[key] = () => normalized;
4044 }
4045 }
4046};
4047const normalizeVNodeSlots = (instance, children) => {
4048 if (!isKeepAlive(instance.vnode)) {
4049 warn(`Non-function value encountered for default slot. ` +
4050 `Prefer function slots for better performance.`);
4051 }
4052 const normalized = normalizeSlotValue(children);
4053 instance.slots.default = () => normalized;
4054};
4055const initSlots = (instance, children) => {
4056 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4057 const type = children._;
4058 if (type) {
4059 instance.slots = children;
4060 // make compiler marker non-enumerable
4061 def(children, '_', type);
4062 }
4063 else {
4064 normalizeObjectSlots(children, (instance.slots = {}));
4065 }
4066 }
4067 else {
4068 instance.slots = {};
4069 if (children) {
4070 normalizeVNodeSlots(instance, children);
4071 }
4072 }
4073 def(instance.slots, InternalObjectKey, 1);
4074};
4075const updateSlots = (instance, children, optimized) => {
4076 const { vnode, slots } = instance;
4077 let needDeletionCheck = true;
4078 let deletionComparisonTarget = EMPTY_OBJ;
4079 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4080 const type = children._;
4081 if (type) {
4082 // compiled slots.
4083 if (isHmrUpdating) {
4084 // Parent was HMR updated so slot content may have changed.
4085 // force update slots and mark instance for hmr as well
4086 extend(slots, children);
4087 }
4088 else if (optimized && type === 1 /* STABLE */) {
4089 // compiled AND stable.
4090 // no need to update, and skip stale slots removal.
4091 needDeletionCheck = false;
4092 }
4093 else {
4094 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
4095 // normalization.
4096 extend(slots, children);
4097 // #2893
4098 // when rendering the optimized slots by manually written render function,
4099 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
4100 // i.e. let the `renderSlot` create the bailed Fragment
4101 if (!optimized && type === 1 /* STABLE */) {
4102 delete slots._;
4103 }
4104 }
4105 }
4106 else {
4107 needDeletionCheck = !children.$stable;
4108 normalizeObjectSlots(children, slots);
4109 }
4110 deletionComparisonTarget = children;
4111 }
4112 else if (children) {
4113 // non slot object children (direct value) passed to a component
4114 normalizeVNodeSlots(instance, children);
4115 deletionComparisonTarget = { default: 1 };
4116 }
4117 // delete stale slots
4118 if (needDeletionCheck) {
4119 for (const key in slots) {
4120 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
4121 delete slots[key];
4122 }
4123 }
4124 }
4125};
4126
4127/**
4128Runtime helper for applying directives to a vnode. Example usage:
4129
4130const comp = resolveComponent('comp')
4131const foo = resolveDirective('foo')
4132const bar = resolveDirective('bar')
4133
4134return withDirectives(h(comp), [
4135 [foo, this.x],
4136 [bar, this.y]
4137])
4138*/
4139const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
4140function validateDirectiveName(name) {
4141 if (isBuiltInDirective(name)) {
4142 warn('Do not use built-in directive ids as custom directive id: ' + name);
4143 }
4144}
4145/**
4146 * Adds directives to a VNode.
4147 */
4148function withDirectives(vnode, directives) {
4149 const internalInstance = currentRenderingInstance;
4150 if (internalInstance === null) {
4151 warn(`withDirectives can only be used inside render functions.`);
4152 return vnode;
4153 }
4154 const instance = internalInstance.proxy;
4155 const bindings = vnode.dirs || (vnode.dirs = []);
4156 for (let i = 0; i < directives.length; i++) {
4157 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4158 if (isFunction(dir)) {
4159 dir = {
4160 mounted: dir,
4161 updated: dir
4162 };
4163 }
4164 bindings.push({
4165 dir,
4166 instance,
4167 value,
4168 oldValue: void 0,
4169 arg,
4170 modifiers
4171 });
4172 }
4173 return vnode;
4174}
4175function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4176 const bindings = vnode.dirs;
4177 const oldBindings = prevVNode && prevVNode.dirs;
4178 for (let i = 0; i < bindings.length; i++) {
4179 const binding = bindings[i];
4180 if (oldBindings) {
4181 binding.oldValue = oldBindings[i].value;
4182 }
4183 const hook = binding.dir[name];
4184 if (hook) {
4185 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4186 vnode.el,
4187 binding,
4188 vnode,
4189 prevVNode
4190 ]);
4191 }
4192 }
4193}
4194
4195function createAppContext() {
4196 return {
4197 app: null,
4198 config: {
4199 isNativeTag: NO,
4200 performance: false,
4201 globalProperties: {},
4202 optionMergeStrategies: {},
4203 isCustomElement: NO,
4204 errorHandler: undefined,
4205 warnHandler: undefined
4206 },
4207 mixins: [],
4208 components: {},
4209 directives: {},
4210 provides: Object.create(null)
4211 };
4212}
4213let uid$1 = 0;
4214function createAppAPI(render, hydrate) {
4215 return function createApp(rootComponent, rootProps = null) {
4216 if (rootProps != null && !isObject(rootProps)) {
4217 warn(`root props passed to app.mount() must be an object.`);
4218 rootProps = null;
4219 }
4220 const context = createAppContext();
4221 const installedPlugins = new Set();
4222 let isMounted = false;
4223 const app = (context.app = {
4224 _uid: uid$1++,
4225 _component: rootComponent,
4226 _props: rootProps,
4227 _container: null,
4228 _context: context,
4229 version,
4230 get config() {
4231 return context.config;
4232 },
4233 set config(v) {
4234 {
4235 warn(`app.config cannot be replaced. Modify individual options instead.`);
4236 }
4237 },
4238 use(plugin, ...options) {
4239 if (installedPlugins.has(plugin)) {
4240 warn(`Plugin has already been applied to target app.`);
4241 }
4242 else if (plugin && isFunction(plugin.install)) {
4243 installedPlugins.add(plugin);
4244 plugin.install(app, ...options);
4245 }
4246 else if (isFunction(plugin)) {
4247 installedPlugins.add(plugin);
4248 plugin(app, ...options);
4249 }
4250 else {
4251 warn(`A plugin must either be a function or an object with an "install" ` +
4252 `function.`);
4253 }
4254 return app;
4255 },
4256 mixin(mixin) {
4257 {
4258 if (!context.mixins.includes(mixin)) {
4259 context.mixins.push(mixin);
4260 // global mixin with props/emits de-optimizes props/emits
4261 // normalization caching.
4262 if (mixin.props || mixin.emits) {
4263 context.deopt = true;
4264 }
4265 }
4266 else {
4267 warn('Mixin has already been applied to target app' +
4268 (mixin.name ? `: ${mixin.name}` : ''));
4269 }
4270 }
4271 return app;
4272 },
4273 component(name, component) {
4274 {
4275 validateComponentName(name, context.config);
4276 }
4277 if (!component) {
4278 return context.components[name];
4279 }
4280 if (context.components[name]) {
4281 warn(`Component "${name}" has already been registered in target app.`);
4282 }
4283 context.components[name] = component;
4284 return app;
4285 },
4286 directive(name, directive) {
4287 {
4288 validateDirectiveName(name);
4289 }
4290 if (!directive) {
4291 return context.directives[name];
4292 }
4293 if (context.directives[name]) {
4294 warn(`Directive "${name}" has already been registered in target app.`);
4295 }
4296 context.directives[name] = directive;
4297 return app;
4298 },
4299 mount(rootContainer, isHydrate, isSVG) {
4300 if (!isMounted) {
4301 const vnode = createVNode(rootComponent, rootProps);
4302 // store app context on the root VNode.
4303 // this will be set on the root instance on initial mount.
4304 vnode.appContext = context;
4305 // HMR root reload
4306 {
4307 context.reload = () => {
4308 render(cloneVNode(vnode), rootContainer, isSVG);
4309 };
4310 }
4311 if (isHydrate && hydrate) {
4312 hydrate(vnode, rootContainer);
4313 }
4314 else {
4315 render(vnode, rootContainer, isSVG);
4316 }
4317 isMounted = true;
4318 app._container = rootContainer;
4319 rootContainer.__vue_app__ = app;
4320 {
4321 devtoolsInitApp(app, version);
4322 }
4323 return vnode.component.proxy;
4324 }
4325 else {
4326 warn(`App has already been mounted.\n` +
4327 `If you want to remount the same app, move your app creation logic ` +
4328 `into a factory function and create fresh app instances for each ` +
4329 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
4330 }
4331 },
4332 unmount() {
4333 if (isMounted) {
4334 render(null, app._container);
4335 {
4336 devtoolsUnmountApp(app);
4337 }
4338 delete app._container.__vue_app__;
4339 }
4340 else {
4341 warn(`Cannot unmount an app that is not mounted.`);
4342 }
4343 },
4344 provide(key, value) {
4345 if (key in context.provides) {
4346 warn(`App already provides property with key "${String(key)}". ` +
4347 `It will be overwritten with the new value.`);
4348 }
4349 // TypeScript doesn't allow symbols as index type
4350 // https://github.com/Microsoft/TypeScript/issues/24587
4351 context.provides[key] = value;
4352 return app;
4353 }
4354 });
4355 return app;
4356 };
4357}
4358
4359let hasMismatch = false;
4360const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4361const isComment = (node) => node.nodeType === 8 /* COMMENT */;
4362// Note: hydration is DOM-specific
4363// But we have to place it in core due to tight coupling with core - splitting
4364// it out creates a ton of unnecessary complexity.
4365// Hydration also depends on some renderer internal logic which needs to be
4366// passed in via arguments.
4367function createHydrationFunctions(rendererInternals) {
4368 const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
4369 const hydrate = (vnode, container) => {
4370 if (!container.hasChildNodes()) {
4371 warn(`Attempting to hydrate existing markup but container is empty. ` +
4372 `Performing full mount instead.`);
4373 patch(null, vnode, container);
4374 return;
4375 }
4376 hasMismatch = false;
4377 hydrateNode(container.firstChild, vnode, null, null, null);
4378 flushPostFlushCbs();
4379 if (hasMismatch && !false) {
4380 // this error should show up in production
4381 console.error(`Hydration completed but contains mismatches.`);
4382 }
4383 };
4384 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
4385 const isFragmentStart = isComment(node) && node.data === '[';
4386 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
4387 const { type, ref, shapeFlag } = vnode;
4388 const domType = node.nodeType;
4389 vnode.el = node;
4390 let nextNode = null;
4391 switch (type) {
4392 case Text:
4393 if (domType !== 3 /* TEXT */) {
4394 nextNode = onMismatch();
4395 }
4396 else {
4397 if (node.data !== vnode.children) {
4398 hasMismatch = true;
4399 warn(`Hydration text mismatch:` +
4400 `\n- Client: ${JSON.stringify(node.data)}` +
4401 `\n- Server: ${JSON.stringify(vnode.children)}`);
4402 node.data = vnode.children;
4403 }
4404 nextNode = nextSibling(node);
4405 }
4406 break;
4407 case Comment:
4408 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
4409 nextNode = onMismatch();
4410 }
4411 else {
4412 nextNode = nextSibling(node);
4413 }
4414 break;
4415 case Static:
4416 if (domType !== 1 /* ELEMENT */) {
4417 nextNode = onMismatch();
4418 }
4419 else {
4420 // determine anchor, adopt content
4421 nextNode = node;
4422 // if the static vnode has its content stripped during build,
4423 // adopt it from the server-rendered HTML.
4424 const needToAdoptContent = !vnode.children.length;
4425 for (let i = 0; i < vnode.staticCount; i++) {
4426 if (needToAdoptContent)
4427 vnode.children += nextNode.outerHTML;
4428 if (i === vnode.staticCount - 1) {
4429 vnode.anchor = nextNode;
4430 }
4431 nextNode = nextSibling(nextNode);
4432 }
4433 return nextNode;
4434 }
4435 break;
4436 case Fragment:
4437 if (!isFragmentStart) {
4438 nextNode = onMismatch();
4439 }
4440 else {
4441 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4442 }
4443 break;
4444 default:
4445 if (shapeFlag & 1 /* ELEMENT */) {
4446 if (domType !== 1 /* ELEMENT */ ||
4447 vnode.type.toLowerCase() !==
4448 node.tagName.toLowerCase()) {
4449 nextNode = onMismatch();
4450 }
4451 else {
4452 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4453 }
4454 }
4455 else if (shapeFlag & 6 /* COMPONENT */) {
4456 // when setting up the render effect, if the initial vnode already
4457 // has .el set, the component will perform hydration instead of mount
4458 // on its sub-tree.
4459 vnode.slotScopeIds = slotScopeIds;
4460 const container = parentNode(node);
4461 const hydrateComponent = () => {
4462 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
4463 };
4464 // async component
4465 const loadAsync = vnode.type.__asyncLoader;
4466 if (loadAsync) {
4467 loadAsync().then(hydrateComponent);
4468 }
4469 else {
4470 hydrateComponent();
4471 }
4472 // component may be async, so in the case of fragments we cannot rely
4473 // on component's rendered output to determine the end of the fragment
4474 // instead, we do a lookahead to find the end anchor node.
4475 nextNode = isFragmentStart
4476 ? locateClosingAsyncAnchor(node)
4477 : nextSibling(node);
4478 }
4479 else if (shapeFlag & 64 /* TELEPORT */) {
4480 if (domType !== 8 /* COMMENT */) {
4481 nextNode = onMismatch();
4482 }
4483 else {
4484 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
4485 }
4486 }
4487 else if (shapeFlag & 128 /* SUSPENSE */) {
4488 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
4489 }
4490 else {
4491 warn('Invalid HostVNode type:', type, `(${typeof type})`);
4492 }
4493 }
4494 if (ref != null) {
4495 setRef(ref, null, parentSuspense, vnode);
4496 }
4497 return nextNode;
4498 };
4499 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4500 optimized = optimized || !!vnode.dynamicChildren;
4501 const { props, patchFlag, shapeFlag, dirs } = vnode;
4502 // skip props & children if this is hoisted static nodes
4503 if (patchFlag !== -1 /* HOISTED */) {
4504 if (dirs) {
4505 invokeDirectiveHook(vnode, null, parentComponent, 'created');
4506 }
4507 // props
4508 if (props) {
4509 if (!optimized ||
4510 (patchFlag & 16 /* FULL_PROPS */ ||
4511 patchFlag & 32 /* HYDRATE_EVENTS */)) {
4512 for (const key in props) {
4513 if (!isReservedProp(key) && isOn(key)) {
4514 patchProp(el, key, null, props[key]);
4515 }
4516 }
4517 }
4518 else if (props.onClick) {
4519 // Fast path for click listeners (which is most often) to avoid
4520 // iterating through props.
4521 patchProp(el, 'onClick', null, props.onClick);
4522 }
4523 }
4524 // vnode / directive hooks
4525 let vnodeHooks;
4526 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
4527 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4528 }
4529 if (dirs) {
4530 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
4531 }
4532 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
4533 queueEffectWithSuspense(() => {
4534 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4535 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
4536 }, parentSuspense);
4537 }
4538 // children
4539 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
4540 // skip if element has innerHTML / textContent
4541 !(props && (props.innerHTML || props.textContent))) {
4542 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
4543 let hasWarned = false;
4544 while (next) {
4545 hasMismatch = true;
4546 if (!hasWarned) {
4547 warn(`Hydration children mismatch in <${vnode.type}>: ` +
4548 `server rendered element contains more child nodes than client vdom.`);
4549 hasWarned = true;
4550 }
4551 // The SSRed DOM contains more nodes than it should. Remove them.
4552 const cur = next;
4553 next = next.nextSibling;
4554 remove(cur);
4555 }
4556 }
4557 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
4558 if (el.textContent !== vnode.children) {
4559 hasMismatch = true;
4560 warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
4561 `- Client: ${el.textContent}\n` +
4562 `- Server: ${vnode.children}`);
4563 el.textContent = vnode.children;
4564 }
4565 }
4566 }
4567 return el.nextSibling;
4568 };
4569 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4570 optimized = optimized || !!parentVNode.dynamicChildren;
4571 const children = parentVNode.children;
4572 const l = children.length;
4573 let hasWarned = false;
4574 for (let i = 0; i < l; i++) {
4575 const vnode = optimized
4576 ? children[i]
4577 : (children[i] = normalizeVNode(children[i]));
4578 if (node) {
4579 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4580 }
4581 else if (vnode.type === Text && !vnode.children) {
4582 continue;
4583 }
4584 else {
4585 hasMismatch = true;
4586 if (!hasWarned) {
4587 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
4588 `server rendered element contains fewer child nodes than client vdom.`);
4589 hasWarned = true;
4590 }
4591 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
4592 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
4593 }
4594 }
4595 return node;
4596 };
4597 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4598 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
4599 if (fragmentSlotScopeIds) {
4600 slotScopeIds = slotScopeIds
4601 ? slotScopeIds.concat(fragmentSlotScopeIds)
4602 : fragmentSlotScopeIds;
4603 }
4604 const container = parentNode(node);
4605 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
4606 if (next && isComment(next) && next.data === ']') {
4607 return nextSibling((vnode.anchor = next));
4608 }
4609 else {
4610 // fragment didn't hydrate successfully, since we didn't get a end anchor
4611 // back. This should have led to node/children mismatch warnings.
4612 hasMismatch = true;
4613 // since the anchor is missing, we need to create one and insert it
4614 insert((vnode.anchor = createComment(`]`)), container, next);
4615 return next;
4616 }
4617 };
4618 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
4619 hasMismatch = true;
4620 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
4621 ? `(text)`
4622 : isComment(node) && node.data === '['
4623 ? `(start of fragment)`
4624 : ``);
4625 vnode.el = null;
4626 if (isFragment) {
4627 // remove excessive fragment nodes
4628 const end = locateClosingAsyncAnchor(node);
4629 while (true) {
4630 const next = nextSibling(node);
4631 if (next && next !== end) {
4632 remove(next);
4633 }
4634 else {
4635 break;
4636 }
4637 }
4638 }
4639 const next = nextSibling(node);
4640 const container = parentNode(node);
4641 remove(node);
4642 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
4643 return next;
4644 };
4645 const locateClosingAsyncAnchor = (node) => {
4646 let match = 0;
4647 while (node) {
4648 node = nextSibling(node);
4649 if (node && isComment(node)) {
4650 if (node.data === '[')
4651 match++;
4652 if (node.data === ']') {
4653 if (match === 0) {
4654 return nextSibling(node);
4655 }
4656 else {
4657 match--;
4658 }
4659 }
4660 }
4661 }
4662 return node;
4663 };
4664 return [hydrate, hydrateNode];
4665}
4666
4667let supported;
4668let perf;
4669function startMeasure(instance, type) {
4670 if (instance.appContext.config.performance && isSupported()) {
4671 perf.mark(`vue-${type}-${instance.uid}`);
4672 }
4673}
4674function endMeasure(instance, type) {
4675 if (instance.appContext.config.performance && isSupported()) {
4676 const startTag = `vue-${type}-${instance.uid}`;
4677 const endTag = startTag + `:end`;
4678 perf.mark(endTag);
4679 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
4680 perf.clearMarks(startTag);
4681 perf.clearMarks(endTag);
4682 }
4683}
4684function isSupported() {
4685 if (supported !== undefined) {
4686 return supported;
4687 }
4688 /* eslint-disable no-restricted-globals */
4689 if (typeof window !== 'undefined' && window.performance) {
4690 supported = true;
4691 perf = window.performance;
4692 }
4693 else {
4694 supported = false;
4695 }
4696 /* eslint-enable no-restricted-globals */
4697 return supported;
4698}
4699
4700// implementation, close to no-op
4701function defineComponent(options) {
4702 return isFunction(options) ? { setup: options, name: options.name } : options;
4703}
4704
4705const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
4706function defineAsyncComponent(source) {
4707 if (isFunction(source)) {
4708 source = { loader: source };
4709 }
4710 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
4711 suspensible = true, onError: userOnError } = source;
4712 let pendingRequest = null;
4713 let resolvedComp;
4714 let retries = 0;
4715 const retry = () => {
4716 retries++;
4717 pendingRequest = null;
4718 return load();
4719 };
4720 const load = () => {
4721 let thisRequest;
4722 return (pendingRequest ||
4723 (thisRequest = pendingRequest = loader()
4724 .catch(err => {
4725 err = err instanceof Error ? err : new Error(String(err));
4726 if (userOnError) {
4727 return new Promise((resolve, reject) => {
4728 const userRetry = () => resolve(retry());
4729 const userFail = () => reject(err);
4730 userOnError(err, userRetry, userFail, retries + 1);
4731 });
4732 }
4733 else {
4734 throw err;
4735 }
4736 })
4737 .then((comp) => {
4738 if (thisRequest !== pendingRequest && pendingRequest) {
4739 return pendingRequest;
4740 }
4741 if (!comp) {
4742 warn(`Async component loader resolved to undefined. ` +
4743 `If you are using retry(), make sure to return its return value.`);
4744 }
4745 // interop module default
4746 if (comp &&
4747 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
4748 comp = comp.default;
4749 }
4750 if (comp && !isObject(comp) && !isFunction(comp)) {
4751 throw new Error(`Invalid async component load result: ${comp}`);
4752 }
4753 resolvedComp = comp;
4754 return comp;
4755 })));
4756 };
4757 return defineComponent({
4758 __asyncLoader: load,
4759 name: 'AsyncComponentWrapper',
4760 setup() {
4761 const instance = currentInstance;
4762 // already resolved
4763 if (resolvedComp) {
4764 return () => createInnerComp(resolvedComp, instance);
4765 }
4766 const onError = (err) => {
4767 pendingRequest = null;
4768 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
4769 };
4770 // suspense-controlled or SSR.
4771 if ((suspensible && instance.suspense) ||
4772 (false )) {
4773 return load()
4774 .then(comp => {
4775 return () => createInnerComp(comp, instance);
4776 })
4777 .catch(err => {
4778 onError(err);
4779 return () => errorComponent
4780 ? createVNode(errorComponent, {
4781 error: err
4782 })
4783 : null;
4784 });
4785 }
4786 const loaded = ref(false);
4787 const error = ref();
4788 const delayed = ref(!!delay);
4789 if (delay) {
4790 setTimeout(() => {
4791 delayed.value = false;
4792 }, delay);
4793 }
4794 if (timeout != null) {
4795 setTimeout(() => {
4796 if (!loaded.value && !error.value) {
4797 const err = new Error(`Async component timed out after ${timeout}ms.`);
4798 onError(err);
4799 error.value = err;
4800 }
4801 }, timeout);
4802 }
4803 load()
4804 .then(() => {
4805 loaded.value = true;
4806 })
4807 .catch(err => {
4808 onError(err);
4809 error.value = err;
4810 });
4811 return () => {
4812 if (loaded.value && resolvedComp) {
4813 return createInnerComp(resolvedComp, instance);
4814 }
4815 else if (error.value && errorComponent) {
4816 return createVNode(errorComponent, {
4817 error: error.value
4818 });
4819 }
4820 else if (loadingComponent && !delayed.value) {
4821 return createVNode(loadingComponent);
4822 }
4823 };
4824 }
4825 });
4826}
4827function createInnerComp(comp, { vnode: { ref, props, children } }) {
4828 const vnode = createVNode(comp, props, children);
4829 // ensure inner component inherits the async wrapper's ref owner
4830 vnode.ref = ref;
4831 return vnode;
4832}
4833
4834function createDevEffectOptions(instance) {
4835 return {
4836 scheduler: queueJob,
4837 allowRecurse: true,
4838 onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0,
4839 onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 0
4840 };
4841}
4842const queuePostRenderEffect = queueEffectWithSuspense
4843 ;
4844const setRef = (rawRef, oldRawRef, parentSuspense, vnode) => {
4845 if (isArray(rawRef)) {
4846 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode));
4847 return;
4848 }
4849 let value;
4850 if (!vnode) {
4851 // means unmount
4852 value = null;
4853 }
4854 else if (isAsyncWrapper(vnode)) {
4855 // when mounting async components, nothing needs to be done,
4856 // because the template ref is forwarded to inner component
4857 return;
4858 }
4859 else if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
4860 value = vnode.component.exposed || vnode.component.proxy;
4861 }
4862 else {
4863 value = vnode.el;
4864 }
4865 const { i: owner, r: ref } = rawRef;
4866 if (!owner) {
4867 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
4868 `A vnode with ref must be created inside the render function.`);
4869 return;
4870 }
4871 const oldRef = oldRawRef && oldRawRef.r;
4872 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
4873 const setupState = owner.setupState;
4874 // unset old ref
4875 if (oldRef != null && oldRef !== ref) {
4876 if (isString(oldRef)) {
4877 refs[oldRef] = null;
4878 if (hasOwn(setupState, oldRef)) {
4879 setupState[oldRef] = null;
4880 }
4881 }
4882 else if (isRef(oldRef)) {
4883 oldRef.value = null;
4884 }
4885 }
4886 if (isString(ref)) {
4887 const doSet = () => {
4888 refs[ref] = value;
4889 if (hasOwn(setupState, ref)) {
4890 setupState[ref] = value;
4891 }
4892 };
4893 // #1789: for non-null values, set them after render
4894 // null values means this is unmount and it should not overwrite another
4895 // ref with the same key
4896 if (value) {
4897 doSet.id = -1;
4898 queuePostRenderEffect(doSet, parentSuspense);
4899 }
4900 else {
4901 doSet();
4902 }
4903 }
4904 else if (isRef(ref)) {
4905 const doSet = () => {
4906 ref.value = value;
4907 };
4908 if (value) {
4909 doSet.id = -1;
4910 queuePostRenderEffect(doSet, parentSuspense);
4911 }
4912 else {
4913 doSet();
4914 }
4915 }
4916 else if (isFunction(ref)) {
4917 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
4918 }
4919 else {
4920 warn('Invalid template ref type:', value, `(${typeof value})`);
4921 }
4922};
4923/**
4924 * The createRenderer function accepts two generic arguments:
4925 * HostNode and HostElement, corresponding to Node and Element types in the
4926 * host environment. For example, for runtime-dom, HostNode would be the DOM
4927 * `Node` interface and HostElement would be the DOM `Element` interface.
4928 *
4929 * Custom renderers can pass in the platform specific types like this:
4930 *
4931 * ``` js
4932 * const { render, createApp } = createRenderer<Node, Element>({
4933 * patchProp,
4934 * ...nodeOps
4935 * })
4936 * ```
4937 */
4938function createRenderer(options) {
4939 return baseCreateRenderer(options);
4940}
4941// Separate API for creating hydration-enabled renderer.
4942// Hydration logic is only used when calling this function, making it
4943// tree-shakable.
4944function createHydrationRenderer(options) {
4945 return baseCreateRenderer(options, createHydrationFunctions);
4946}
4947// implementation
4948function baseCreateRenderer(options, createHydrationFns) {
4949 {
4950 const target = getGlobalThis();
4951 target.__VUE__ = true;
4952 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__);
4953 }
4954 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;
4955 // Note: functions inside this closure should use `const xxx = () => {}`
4956 // style in order to prevent being inlined by minifiers.
4957 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = false) => {
4958 // patching & not same type, unmount old tree
4959 if (n1 && !isSameVNodeType(n1, n2)) {
4960 anchor = getNextHostNode(n1);
4961 unmount(n1, parentComponent, parentSuspense, true);
4962 n1 = null;
4963 }
4964 if (n2.patchFlag === -2 /* BAIL */) {
4965 optimized = false;
4966 n2.dynamicChildren = null;
4967 }
4968 const { type, ref, shapeFlag } = n2;
4969 switch (type) {
4970 case Text:
4971 processText(n1, n2, container, anchor);
4972 break;
4973 case Comment:
4974 processCommentNode(n1, n2, container, anchor);
4975 break;
4976 case Static:
4977 if (n1 == null) {
4978 mountStaticNode(n2, container, anchor, isSVG);
4979 }
4980 else {
4981 patchStaticNode(n1, n2, container, isSVG);
4982 }
4983 break;
4984 case Fragment:
4985 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
4986 break;
4987 default:
4988 if (shapeFlag & 1 /* ELEMENT */) {
4989 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
4990 }
4991 else if (shapeFlag & 6 /* COMPONENT */) {
4992 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
4993 }
4994 else if (shapeFlag & 64 /* TELEPORT */) {
4995 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
4996 }
4997 else if (shapeFlag & 128 /* SUSPENSE */) {
4998 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
4999 }
5000 else {
5001 warn('Invalid VNode type:', type, `(${typeof type})`);
5002 }
5003 }
5004 // set ref
5005 if (ref != null && parentComponent) {
5006 setRef(ref, n1 && n1.ref, parentSuspense, n2);
5007 }
5008 };
5009 const processText = (n1, n2, container, anchor) => {
5010 if (n1 == null) {
5011 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
5012 }
5013 else {
5014 const el = (n2.el = n1.el);
5015 if (n2.children !== n1.children) {
5016 hostSetText(el, n2.children);
5017 }
5018 }
5019 };
5020 const processCommentNode = (n1, n2, container, anchor) => {
5021 if (n1 == null) {
5022 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
5023 }
5024 else {
5025 // there's no support for dynamic comments
5026 n2.el = n1.el;
5027 }
5028 };
5029 const mountStaticNode = (n2, container, anchor, isSVG) => {
5030 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5031 };
5032 /**
5033 * Dev / HMR only
5034 */
5035 const patchStaticNode = (n1, n2, container, isSVG) => {
5036 // static nodes are only patched during dev for HMR
5037 if (n2.children !== n1.children) {
5038 const anchor = hostNextSibling(n1.anchor);
5039 // remove existing
5040 removeStaticNode(n1);
5041 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5042 }
5043 else {
5044 n2.el = n1.el;
5045 n2.anchor = n1.anchor;
5046 }
5047 };
5048 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
5049 let next;
5050 while (el && el !== anchor) {
5051 next = hostNextSibling(el);
5052 hostInsert(el, container, nextSibling);
5053 el = next;
5054 }
5055 hostInsert(anchor, container, nextSibling);
5056 };
5057 const removeStaticNode = ({ el, anchor }) => {
5058 let next;
5059 while (el && el !== anchor) {
5060 next = hostNextSibling(el);
5061 hostRemove(el);
5062 el = next;
5063 }
5064 hostRemove(anchor);
5065 };
5066 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5067 isSVG = isSVG || n2.type === 'svg';
5068 if (n1 == null) {
5069 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5070 }
5071 else {
5072 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5073 }
5074 };
5075 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5076 let el;
5077 let vnodeHook;
5078 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
5079 {
5080 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
5081 // mount children first, since some props may rely on child content
5082 // being already rendered, e.g. `<select value>`
5083 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5084 hostSetElementText(el, vnode.children);
5085 }
5086 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5087 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized || !!vnode.dynamicChildren);
5088 }
5089 if (dirs) {
5090 invokeDirectiveHook(vnode, null, parentComponent, 'created');
5091 }
5092 // props
5093 if (props) {
5094 for (const key in props) {
5095 if (!isReservedProp(key)) {
5096 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5097 }
5098 }
5099 if ((vnodeHook = props.onVnodeBeforeMount)) {
5100 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5101 }
5102 }
5103 // scopeId
5104 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
5105 }
5106 {
5107 Object.defineProperty(el, '__vnode', {
5108 value: vnode,
5109 enumerable: false
5110 });
5111 Object.defineProperty(el, '__vueParentComponent', {
5112 value: parentComponent,
5113 enumerable: false
5114 });
5115 }
5116 if (dirs) {
5117 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
5118 }
5119 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
5120 // #1689 For inside suspense + suspense resolved case, just call it
5121 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
5122 transition &&
5123 !transition.persisted;
5124 if (needCallTransitionHooks) {
5125 transition.beforeEnter(el);
5126 }
5127 hostInsert(el, container, anchor);
5128 if ((vnodeHook = props && props.onVnodeMounted) ||
5129 needCallTransitionHooks ||
5130 dirs) {
5131 queuePostRenderEffect(() => {
5132 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5133 needCallTransitionHooks && transition.enter(el);
5134 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
5135 }, parentSuspense);
5136 }
5137 };
5138 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
5139 if (scopeId) {
5140 hostSetScopeId(el, scopeId);
5141 }
5142 if (slotScopeIds) {
5143 for (let i = 0; i < slotScopeIds.length; i++) {
5144 hostSetScopeId(el, slotScopeIds[i]);
5145 }
5146 }
5147 if (parentComponent) {
5148 let subTree = parentComponent.subTree;
5149 if (subTree.patchFlag > 0 &&
5150 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
5151 subTree =
5152 filterSingleRoot(subTree.children) || subTree;
5153 }
5154 if (vnode === subTree) {
5155 const parentVNode = parentComponent.vnode;
5156 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
5157 }
5158 }
5159 };
5160 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, slotScopeIds, start = 0) => {
5161 for (let i = start; i < children.length; i++) {
5162 const child = (children[i] = optimized
5163 ? cloneIfMounted(children[i])
5164 : normalizeVNode(children[i]));
5165 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized, slotScopeIds);
5166 }
5167 };
5168 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5169 const el = (n2.el = n1.el);
5170 let { patchFlag, dynamicChildren, dirs } = n2;
5171 // #1426 take the old vnode's patch flag into account since user may clone a
5172 // compiler-generated vnode, which de-opts to FULL_PROPS
5173 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
5174 const oldProps = n1.props || EMPTY_OBJ;
5175 const newProps = n2.props || EMPTY_OBJ;
5176 let vnodeHook;
5177 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5178 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5179 }
5180 if (dirs) {
5181 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5182 }
5183 if (isHmrUpdating) {
5184 // HMR updated, force full diff
5185 patchFlag = 0;
5186 optimized = false;
5187 dynamicChildren = null;
5188 }
5189 if (patchFlag > 0) {
5190 // the presence of a patchFlag means this element's render code was
5191 // generated by the compiler and can take the fast path.
5192 // in this path old node and new node are guaranteed to have the same shape
5193 // (i.e. at the exact same position in the source template)
5194 if (patchFlag & 16 /* FULL_PROPS */) {
5195 // element props contain dynamic keys, full diff needed
5196 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5197 }
5198 else {
5199 // class
5200 // this flag is matched when the element has dynamic class bindings.
5201 if (patchFlag & 2 /* CLASS */) {
5202 if (oldProps.class !== newProps.class) {
5203 hostPatchProp(el, 'class', null, newProps.class, isSVG);
5204 }
5205 }
5206 // style
5207 // this flag is matched when the element has dynamic style bindings
5208 if (patchFlag & 4 /* STYLE */) {
5209 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
5210 }
5211 // props
5212 // This flag is matched when the element has dynamic prop/attr bindings
5213 // other than class and style. The keys of dynamic prop/attrs are saved for
5214 // faster iteration.
5215 // Note dynamic keys like :[foo]="bar" will cause this optimization to
5216 // bail out and go through a full diff because we need to unset the old key
5217 if (patchFlag & 8 /* PROPS */) {
5218 // if the flag is present then dynamicProps must be non-null
5219 const propsToUpdate = n2.dynamicProps;
5220 for (let i = 0; i < propsToUpdate.length; i++) {
5221 const key = propsToUpdate[i];
5222 const prev = oldProps[key];
5223 const next = newProps[key];
5224 if (next !== prev ||
5225 (hostForcePatchProp && hostForcePatchProp(el, key))) {
5226 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
5227 }
5228 }
5229 }
5230 }
5231 // text
5232 // This flag is matched when the element has only dynamic text children.
5233 if (patchFlag & 1 /* TEXT */) {
5234 if (n1.children !== n2.children) {
5235 hostSetElementText(el, n2.children);
5236 }
5237 }
5238 }
5239 else if (!optimized && dynamicChildren == null) {
5240 // unoptimized, full diff
5241 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5242 }
5243 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
5244 if (dynamicChildren) {
5245 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
5246 if (parentComponent && parentComponent.type.__hmrId) {
5247 traverseStaticChildren(n1, n2);
5248 }
5249 }
5250 else if (!optimized) {
5251 // full diff
5252 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
5253 }
5254 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
5255 queuePostRenderEffect(() => {
5256 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5257 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
5258 }, parentSuspense);
5259 }
5260 };
5261 // The fast path for blocks.
5262 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
5263 for (let i = 0; i < newChildren.length; i++) {
5264 const oldVNode = oldChildren[i];
5265 const newVNode = newChildren[i];
5266 // Determine the container (parent element) for the patch.
5267 const container =
5268 // - In the case of a Fragment, we need to provide the actual parent
5269 // of the Fragment itself so it can move its children.
5270 oldVNode.type === Fragment ||
5271 // - In the case of different nodes, there is going to be a replacement
5272 // which also requires the correct parent container
5273 !isSameVNodeType(oldVNode, newVNode) ||
5274 // - In the case of a component, it could contain anything.
5275 oldVNode.shapeFlag & 6 /* COMPONENT */ ||
5276 oldVNode.shapeFlag & 64 /* TELEPORT */
5277 ? hostParentNode(oldVNode.el)
5278 : // In other cases, the parent container is not actually used so we
5279 // just pass the block element here to avoid a DOM parentNode call.
5280 fallbackContainer;
5281 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
5282 }
5283 };
5284 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
5285 if (oldProps !== newProps) {
5286 for (const key in newProps) {
5287 // empty string is not valid prop
5288 if (isReservedProp(key))
5289 continue;
5290 const next = newProps[key];
5291 const prev = oldProps[key];
5292 if (next !== prev ||
5293 (hostForcePatchProp && hostForcePatchProp(el, key))) {
5294 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5295 }
5296 }
5297 if (oldProps !== EMPTY_OBJ) {
5298 for (const key in oldProps) {
5299 if (!isReservedProp(key) && !(key in newProps)) {
5300 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5301 }
5302 }
5303 }
5304 }
5305 };
5306 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5307 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
5308 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
5309 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
5310 if (patchFlag > 0) {
5311 optimized = true;
5312 }
5313 // check if this is a slot fragment with :slotted scope ids
5314 if (fragmentSlotScopeIds) {
5315 slotScopeIds = slotScopeIds
5316 ? slotScopeIds.concat(fragmentSlotScopeIds)
5317 : fragmentSlotScopeIds;
5318 }
5319 if (isHmrUpdating) {
5320 // HMR updated, force full diff
5321 patchFlag = 0;
5322 optimized = false;
5323 dynamicChildren = null;
5324 }
5325 if (n1 == null) {
5326 hostInsert(fragmentStartAnchor, container, anchor);
5327 hostInsert(fragmentEndAnchor, container, anchor);
5328 // a fragment can only have array children
5329 // since they are either generated by the compiler, or implicitly created
5330 // from arrays.
5331 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5332 }
5333 else {
5334 if (patchFlag > 0 &&
5335 patchFlag & 64 /* STABLE_FRAGMENT */ &&
5336 dynamicChildren &&
5337 // #2715 the previous fragment could've been a BAILed one as a result
5338 // of renderSlot() with no valid children
5339 n1.dynamicChildren) {
5340 // a stable fragment (template root or <template v-for>) doesn't need to
5341 // patch children order, but it may contain dynamicChildren.
5342 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
5343 if (parentComponent && parentComponent.type.__hmrId) {
5344 traverseStaticChildren(n1, n2);
5345 }
5346 else if (
5347 // #2080 if the stable fragment has a key, it's a <template v-for> that may
5348 // get moved around. Make sure all root level vnodes inherit el.
5349 // #2134 or if it's a component root, it may also get moved around
5350 // as the component is being moved.
5351 n2.key != null ||
5352 (parentComponent && n2 === parentComponent.subTree)) {
5353 traverseStaticChildren(n1, n2, true /* shallow */);
5354 }
5355 }
5356 else {
5357 // keyed / unkeyed, or manual fragments.
5358 // for keyed & unkeyed, since they are compiler generated from v-for,
5359 // each child is guaranteed to be a block so the fragment will never
5360 // have dynamicChildren.
5361 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5362 }
5363 }
5364 };
5365 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5366 n2.slotScopeIds = slotScopeIds;
5367 if (n1 == null) {
5368 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
5369 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
5370 }
5371 else {
5372 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5373 }
5374 }
5375 else {
5376 updateComponent(n1, n2, optimized);
5377 }
5378 };
5379 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5380 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
5381 if (instance.type.__hmrId) {
5382 registerHMR(instance);
5383 }
5384 {
5385 pushWarningContext(initialVNode);
5386 startMeasure(instance, `mount`);
5387 }
5388 // inject renderer internals for keepAlive
5389 if (isKeepAlive(initialVNode)) {
5390 instance.ctx.renderer = internals;
5391 }
5392 // resolve props and slots for setup context
5393 {
5394 startMeasure(instance, `init`);
5395 }
5396 setupComponent(instance);
5397 {
5398 endMeasure(instance, `init`);
5399 }
5400 // setup() is async. This component relies on async logic to be resolved
5401 // before proceeding
5402 if (instance.asyncDep) {
5403 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
5404 // Give it a placeholder if this is not hydration
5405 // TODO handle self-defined fallback
5406 if (!initialVNode.el) {
5407 const placeholder = (instance.subTree = createVNode(Comment));
5408 processCommentNode(null, placeholder, container, anchor);
5409 }
5410 return;
5411 }
5412 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
5413 {
5414 popWarningContext();
5415 endMeasure(instance, `mount`);
5416 }
5417 };
5418 const updateComponent = (n1, n2, optimized) => {
5419 const instance = (n2.component = n1.component);
5420 if (shouldUpdateComponent(n1, n2, optimized)) {
5421 if (instance.asyncDep &&
5422 !instance.asyncResolved) {
5423 // async & still pending - just update props and slots
5424 // since the component's reactive effect for render isn't set-up yet
5425 {
5426 pushWarningContext(n2);
5427 }
5428 updateComponentPreRender(instance, n2, optimized);
5429 {
5430 popWarningContext();
5431 }
5432 return;
5433 }
5434 else {
5435 // normal update
5436 instance.next = n2;
5437 // in case the child component is also queued, remove it to avoid
5438 // double updating the same child component in the same flush.
5439 invalidateJob(instance.update);
5440 // instance.update is the reactive effect runner.
5441 instance.update();
5442 }
5443 }
5444 else {
5445 // no update needed. just copy over properties
5446 n2.component = n1.component;
5447 n2.el = n1.el;
5448 instance.vnode = n2;
5449 }
5450 };
5451 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
5452 // create reactive effect for rendering
5453 instance.update = effect(function componentEffect() {
5454 if (!instance.isMounted) {
5455 let vnodeHook;
5456 const { el, props } = initialVNode;
5457 const { bm, m, parent } = instance;
5458 // beforeMount hook
5459 if (bm) {
5460 invokeArrayFns(bm);
5461 }
5462 // onVnodeBeforeMount
5463 if ((vnodeHook = props && props.onVnodeBeforeMount)) {
5464 invokeVNodeHook(vnodeHook, parent, initialVNode);
5465 }
5466 // render
5467 {
5468 startMeasure(instance, `render`);
5469 }
5470 const subTree = (instance.subTree = renderComponentRoot(instance));
5471 {
5472 endMeasure(instance, `render`);
5473 }
5474 if (el && hydrateNode) {
5475 {
5476 startMeasure(instance, `hydrate`);
5477 }
5478 // vnode has adopted host node - perform hydration instead of mount.
5479 hydrateNode(initialVNode.el, subTree, instance, parentSuspense, null);
5480 {
5481 endMeasure(instance, `hydrate`);
5482 }
5483 }
5484 else {
5485 {
5486 startMeasure(instance, `patch`);
5487 }
5488 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
5489 {
5490 endMeasure(instance, `patch`);
5491 }
5492 initialVNode.el = subTree.el;
5493 }
5494 // mounted hook
5495 if (m) {
5496 queuePostRenderEffect(m, parentSuspense);
5497 }
5498 // onVnodeMounted
5499 if ((vnodeHook = props && props.onVnodeMounted)) {
5500 const scopedInitialVNode = initialVNode;
5501 queuePostRenderEffect(() => {
5502 invokeVNodeHook(vnodeHook, parent, scopedInitialVNode);
5503 }, parentSuspense);
5504 }
5505 // activated hook for keep-alive roots.
5506 // #1742 activated hook must be accessed after first render
5507 // since the hook may be injected by a child keep-alive
5508 const { a } = instance;
5509 if (a &&
5510 initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5511 queuePostRenderEffect(a, parentSuspense);
5512 }
5513 instance.isMounted = true;
5514 {
5515 devtoolsComponentAdded(instance);
5516 }
5517 // #2458: deference mount-only object parameters to prevent memleaks
5518 initialVNode = container = anchor = null;
5519 }
5520 else {
5521 // updateComponent
5522 // This is triggered by mutation of component's own state (next: null)
5523 // OR parent calling processComponent (next: VNode)
5524 let { next, bu, u, parent, vnode } = instance;
5525 let originNext = next;
5526 let vnodeHook;
5527 {
5528 pushWarningContext(next || instance.vnode);
5529 }
5530 if (next) {
5531 next.el = vnode.el;
5532 updateComponentPreRender(instance, next, optimized);
5533 }
5534 else {
5535 next = vnode;
5536 }
5537 // beforeUpdate hook
5538 if (bu) {
5539 invokeArrayFns(bu);
5540 }
5541 // onVnodeBeforeUpdate
5542 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
5543 invokeVNodeHook(vnodeHook, parent, next, vnode);
5544 }
5545 // render
5546 {
5547 startMeasure(instance, `render`);
5548 }
5549 const nextTree = renderComponentRoot(instance);
5550 {
5551 endMeasure(instance, `render`);
5552 }
5553 const prevTree = instance.subTree;
5554 instance.subTree = nextTree;
5555 {
5556 startMeasure(instance, `patch`);
5557 }
5558 patch(prevTree, nextTree,
5559 // parent may have changed if it's in a teleport
5560 hostParentNode(prevTree.el),
5561 // anchor may have changed if it's in a fragment
5562 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
5563 {
5564 endMeasure(instance, `patch`);
5565 }
5566 next.el = nextTree.el;
5567 if (originNext === null) {
5568 // self-triggered update. In case of HOC, update parent component
5569 // vnode el. HOC is indicated by parent instance's subTree pointing
5570 // to child component's vnode
5571 updateHOCHostEl(instance, nextTree.el);
5572 }
5573 // updated hook
5574 if (u) {
5575 queuePostRenderEffect(u, parentSuspense);
5576 }
5577 // onVnodeUpdated
5578 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
5579 queuePostRenderEffect(() => {
5580 invokeVNodeHook(vnodeHook, parent, next, vnode);
5581 }, parentSuspense);
5582 }
5583 {
5584 devtoolsComponentUpdated(instance);
5585 }
5586 {
5587 popWarningContext();
5588 }
5589 }
5590 }, createDevEffectOptions(instance) );
5591 };
5592 const updateComponentPreRender = (instance, nextVNode, optimized) => {
5593 nextVNode.component = instance;
5594 const prevProps = instance.vnode.props;
5595 instance.vnode = nextVNode;
5596 instance.next = null;
5597 updateProps(instance, nextVNode.props, prevProps, optimized);
5598 updateSlots(instance, nextVNode.children, optimized);
5599 pauseTracking();
5600 // props update may have triggered pre-flush watchers.
5601 // flush them before the render update.
5602 flushPreFlushCbs(undefined, instance.update);
5603 resetTracking();
5604 };
5605 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
5606 const c1 = n1 && n1.children;
5607 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
5608 const c2 = n2.children;
5609 const { patchFlag, shapeFlag } = n2;
5610 // fast path
5611 if (patchFlag > 0) {
5612 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
5613 // this could be either fully-keyed or mixed (some keyed some not)
5614 // presence of patchFlag means children are guaranteed to be arrays
5615 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5616 return;
5617 }
5618 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
5619 // unkeyed
5620 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5621 return;
5622 }
5623 }
5624 // children has 3 possibilities: text, array or no children.
5625 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5626 // text children fast path
5627 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5628 unmountChildren(c1, parentComponent, parentSuspense);
5629 }
5630 if (c2 !== c1) {
5631 hostSetElementText(container, c2);
5632 }
5633 }
5634 else {
5635 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5636 // prev children was array
5637 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5638 // two arrays, cannot assume anything, do full diff
5639 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5640 }
5641 else {
5642 // no new children, just unmount old
5643 unmountChildren(c1, parentComponent, parentSuspense, true);
5644 }
5645 }
5646 else {
5647 // prev children was text OR null
5648 // new children is array OR null
5649 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
5650 hostSetElementText(container, '');
5651 }
5652 // mount new if array
5653 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5654 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5655 }
5656 }
5657 }
5658 };
5659 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5660 c1 = c1 || EMPTY_ARR;
5661 c2 = c2 || EMPTY_ARR;
5662 const oldLength = c1.length;
5663 const newLength = c2.length;
5664 const commonLength = Math.min(oldLength, newLength);
5665 let i;
5666 for (i = 0; i < commonLength; i++) {
5667 const nextChild = (c2[i] = optimized
5668 ? cloneIfMounted(c2[i])
5669 : normalizeVNode(c2[i]));
5670 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5671 }
5672 if (oldLength > newLength) {
5673 // remove old
5674 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
5675 }
5676 else {
5677 // mount new
5678 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
5679 }
5680 };
5681 // can be all-keyed or mixed
5682 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5683 let i = 0;
5684 const l2 = c2.length;
5685 let e1 = c1.length - 1; // prev ending index
5686 let e2 = l2 - 1; // next ending index
5687 // 1. sync from start
5688 // (a b) c
5689 // (a b) d e
5690 while (i <= e1 && i <= e2) {
5691 const n1 = c1[i];
5692 const n2 = (c2[i] = optimized
5693 ? cloneIfMounted(c2[i])
5694 : normalizeVNode(c2[i]));
5695 if (isSameVNodeType(n1, n2)) {
5696 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5697 }
5698 else {
5699 break;
5700 }
5701 i++;
5702 }
5703 // 2. sync from end
5704 // a (b c)
5705 // d e (b c)
5706 while (i <= e1 && i <= e2) {
5707 const n1 = c1[e1];
5708 const n2 = (c2[e2] = optimized
5709 ? cloneIfMounted(c2[e2])
5710 : normalizeVNode(c2[e2]));
5711 if (isSameVNodeType(n1, n2)) {
5712 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5713 }
5714 else {
5715 break;
5716 }
5717 e1--;
5718 e2--;
5719 }
5720 // 3. common sequence + mount
5721 // (a b)
5722 // (a b) c
5723 // i = 2, e1 = 1, e2 = 2
5724 // (a b)
5725 // c (a b)
5726 // i = 0, e1 = -1, e2 = 0
5727 if (i > e1) {
5728 if (i <= e2) {
5729 const nextPos = e2 + 1;
5730 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
5731 while (i <= e2) {
5732 patch(null, (c2[i] = optimized
5733 ? cloneIfMounted(c2[i])
5734 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5735 i++;
5736 }
5737 }
5738 }
5739 // 4. common sequence + unmount
5740 // (a b) c
5741 // (a b)
5742 // i = 2, e1 = 2, e2 = 1
5743 // a (b c)
5744 // (b c)
5745 // i = 0, e1 = 0, e2 = -1
5746 else if (i > e2) {
5747 while (i <= e1) {
5748 unmount(c1[i], parentComponent, parentSuspense, true);
5749 i++;
5750 }
5751 }
5752 // 5. unknown sequence
5753 // [i ... e1 + 1]: a b [c d e] f g
5754 // [i ... e2 + 1]: a b [e d c h] f g
5755 // i = 2, e1 = 4, e2 = 5
5756 else {
5757 const s1 = i; // prev starting index
5758 const s2 = i; // next starting index
5759 // 5.1 build key:index map for newChildren
5760 const keyToNewIndexMap = new Map();
5761 for (i = s2; i <= e2; i++) {
5762 const nextChild = (c2[i] = optimized
5763 ? cloneIfMounted(c2[i])
5764 : normalizeVNode(c2[i]));
5765 if (nextChild.key != null) {
5766 if (keyToNewIndexMap.has(nextChild.key)) {
5767 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
5768 }
5769 keyToNewIndexMap.set(nextChild.key, i);
5770 }
5771 }
5772 // 5.2 loop through old children left to be patched and try to patch
5773 // matching nodes & remove nodes that are no longer present
5774 let j;
5775 let patched = 0;
5776 const toBePatched = e2 - s2 + 1;
5777 let moved = false;
5778 // used to track whether any node has moved
5779 let maxNewIndexSoFar = 0;
5780 // works as Map<newIndex, oldIndex>
5781 // Note that oldIndex is offset by +1
5782 // and oldIndex = 0 is a special value indicating the new node has
5783 // no corresponding old node.
5784 // used for determining longest stable subsequence
5785 const newIndexToOldIndexMap = new Array(toBePatched);
5786 for (i = 0; i < toBePatched; i++)
5787 newIndexToOldIndexMap[i] = 0;
5788 for (i = s1; i <= e1; i++) {
5789 const prevChild = c1[i];
5790 if (patched >= toBePatched) {
5791 // all new children have been patched so this can only be a removal
5792 unmount(prevChild, parentComponent, parentSuspense, true);
5793 continue;
5794 }
5795 let newIndex;
5796 if (prevChild.key != null) {
5797 newIndex = keyToNewIndexMap.get(prevChild.key);
5798 }
5799 else {
5800 // key-less node, try to locate a key-less node of the same type
5801 for (j = s2; j <= e2; j++) {
5802 if (newIndexToOldIndexMap[j - s2] === 0 &&
5803 isSameVNodeType(prevChild, c2[j])) {
5804 newIndex = j;
5805 break;
5806 }
5807 }
5808 }
5809 if (newIndex === undefined) {
5810 unmount(prevChild, parentComponent, parentSuspense, true);
5811 }
5812 else {
5813 newIndexToOldIndexMap[newIndex - s2] = i + 1;
5814 if (newIndex >= maxNewIndexSoFar) {
5815 maxNewIndexSoFar = newIndex;
5816 }
5817 else {
5818 moved = true;
5819 }
5820 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5821 patched++;
5822 }
5823 }
5824 // 5.3 move and mount
5825 // generate longest stable subsequence only when nodes have moved
5826 const increasingNewIndexSequence = moved
5827 ? getSequence(newIndexToOldIndexMap)
5828 : EMPTY_ARR;
5829 j = increasingNewIndexSequence.length - 1;
5830 // looping backwards so that we can use last patched node as anchor
5831 for (i = toBePatched - 1; i >= 0; i--) {
5832 const nextIndex = s2 + i;
5833 const nextChild = c2[nextIndex];
5834 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
5835 if (newIndexToOldIndexMap[i] === 0) {
5836 // mount new
5837 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5838 }
5839 else if (moved) {
5840 // move if:
5841 // There is no stable subsequence (e.g. a reverse)
5842 // OR current node is not among the stable sequence
5843 if (j < 0 || i !== increasingNewIndexSequence[j]) {
5844 move(nextChild, container, anchor, 2 /* REORDER */);
5845 }
5846 else {
5847 j--;
5848 }
5849 }
5850 }
5851 }
5852 };
5853 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
5854 const { el, type, transition, children, shapeFlag } = vnode;
5855 if (shapeFlag & 6 /* COMPONENT */) {
5856 move(vnode.component.subTree, container, anchor, moveType);
5857 return;
5858 }
5859 if (shapeFlag & 128 /* SUSPENSE */) {
5860 vnode.suspense.move(container, anchor, moveType);
5861 return;
5862 }
5863 if (shapeFlag & 64 /* TELEPORT */) {
5864 type.move(vnode, container, anchor, internals);
5865 return;
5866 }
5867 if (type === Fragment) {
5868 hostInsert(el, container, anchor);
5869 for (let i = 0; i < children.length; i++) {
5870 move(children[i], container, anchor, moveType);
5871 }
5872 hostInsert(vnode.anchor, container, anchor);
5873 return;
5874 }
5875 if (type === Static) {
5876 moveStaticNode(vnode, container, anchor);
5877 return;
5878 }
5879 // single nodes
5880 const needTransition = moveType !== 2 /* REORDER */ &&
5881 shapeFlag & 1 /* ELEMENT */ &&
5882 transition;
5883 if (needTransition) {
5884 if (moveType === 0 /* ENTER */) {
5885 transition.beforeEnter(el);
5886 hostInsert(el, container, anchor);
5887 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
5888 }
5889 else {
5890 const { leave, delayLeave, afterLeave } = transition;
5891 const remove = () => hostInsert(el, container, anchor);
5892 const performLeave = () => {
5893 leave(el, () => {
5894 remove();
5895 afterLeave && afterLeave();
5896 });
5897 };
5898 if (delayLeave) {
5899 delayLeave(el, remove, performLeave);
5900 }
5901 else {
5902 performLeave();
5903 }
5904 }
5905 }
5906 else {
5907 hostInsert(el, container, anchor);
5908 }
5909 };
5910 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
5911 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
5912 // unset ref
5913 if (ref != null) {
5914 setRef(ref, null, parentSuspense, null);
5915 }
5916 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5917 parentComponent.ctx.deactivate(vnode);
5918 return;
5919 }
5920 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
5921 let vnodeHook;
5922 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {
5923 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5924 }
5925 if (shapeFlag & 6 /* COMPONENT */) {
5926 unmountComponent(vnode.component, parentSuspense, doRemove);
5927 }
5928 else {
5929 if (shapeFlag & 128 /* SUSPENSE */) {
5930 vnode.suspense.unmount(parentSuspense, doRemove);
5931 return;
5932 }
5933 if (shouldInvokeDirs) {
5934 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
5935 }
5936 if (shapeFlag & 64 /* TELEPORT */) {
5937 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
5938 }
5939 else if (dynamicChildren &&
5940 // #1153: fast path should not be taken for non-stable (v-for) fragments
5941 (type !== Fragment ||
5942 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
5943 // fast path for block nodes: only need to unmount dynamic children.
5944 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
5945 }
5946 else if ((type === Fragment &&
5947 (patchFlag & 128 /* KEYED_FRAGMENT */ ||
5948 patchFlag & 256 /* UNKEYED_FRAGMENT */)) ||
5949 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
5950 unmountChildren(children, parentComponent, parentSuspense);
5951 }
5952 if (doRemove) {
5953 remove(vnode);
5954 }
5955 }
5956 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {
5957 queuePostRenderEffect(() => {
5958 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5959 shouldInvokeDirs &&
5960 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
5961 }, parentSuspense);
5962 }
5963 };
5964 const remove = vnode => {
5965 const { type, el, anchor, transition } = vnode;
5966 if (type === Fragment) {
5967 removeFragment(el, anchor);
5968 return;
5969 }
5970 if (type === Static) {
5971 removeStaticNode(vnode);
5972 return;
5973 }
5974 const performRemove = () => {
5975 hostRemove(el);
5976 if (transition && !transition.persisted && transition.afterLeave) {
5977 transition.afterLeave();
5978 }
5979 };
5980 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
5981 transition &&
5982 !transition.persisted) {
5983 const { leave, delayLeave } = transition;
5984 const performLeave = () => leave(el, performRemove);
5985 if (delayLeave) {
5986 delayLeave(vnode.el, performRemove, performLeave);
5987 }
5988 else {
5989 performLeave();
5990 }
5991 }
5992 else {
5993 performRemove();
5994 }
5995 };
5996 const removeFragment = (cur, end) => {
5997 // For fragments, directly remove all contained DOM nodes.
5998 // (fragment child nodes cannot have transition)
5999 let next;
6000 while (cur !== end) {
6001 next = hostNextSibling(cur);
6002 hostRemove(cur);
6003 cur = next;
6004 }
6005 hostRemove(end);
6006 };
6007 const unmountComponent = (instance, parentSuspense, doRemove) => {
6008 if (instance.type.__hmrId) {
6009 unregisterHMR(instance);
6010 }
6011 const { bum, effects, update, subTree, um } = instance;
6012 // beforeUnmount hook
6013 if (bum) {
6014 invokeArrayFns(bum);
6015 }
6016 if (effects) {
6017 for (let i = 0; i < effects.length; i++) {
6018 stop(effects[i]);
6019 }
6020 }
6021 // update may be null if a component is unmounted before its async
6022 // setup has resolved.
6023 if (update) {
6024 stop(update);
6025 unmount(subTree, instance, parentSuspense, doRemove);
6026 }
6027 // unmounted hook
6028 if (um) {
6029 queuePostRenderEffect(um, parentSuspense);
6030 }
6031 queuePostRenderEffect(() => {
6032 instance.isUnmounted = true;
6033 }, parentSuspense);
6034 // A component with async dep inside a pending suspense is unmounted before
6035 // its async dep resolves. This should remove the dep from the suspense, and
6036 // cause the suspense to resolve immediately if that was the last dep.
6037 if (parentSuspense &&
6038 parentSuspense.pendingBranch &&
6039 !parentSuspense.isUnmounted &&
6040 instance.asyncDep &&
6041 !instance.asyncResolved &&
6042 instance.suspenseId === parentSuspense.pendingId) {
6043 parentSuspense.deps--;
6044 if (parentSuspense.deps === 0) {
6045 parentSuspense.resolve();
6046 }
6047 }
6048 {
6049 devtoolsComponentRemoved(instance);
6050 }
6051 };
6052 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
6053 for (let i = start; i < children.length; i++) {
6054 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
6055 }
6056 };
6057 const getNextHostNode = vnode => {
6058 if (vnode.shapeFlag & 6 /* COMPONENT */) {
6059 return getNextHostNode(vnode.component.subTree);
6060 }
6061 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
6062 return vnode.suspense.next();
6063 }
6064 return hostNextSibling((vnode.anchor || vnode.el));
6065 };
6066 const render = (vnode, container, isSVG) => {
6067 if (vnode == null) {
6068 if (container._vnode) {
6069 unmount(container._vnode, null, null, true);
6070 }
6071 }
6072 else {
6073 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
6074 }
6075 flushPostFlushCbs();
6076 container._vnode = vnode;
6077 };
6078 const internals = {
6079 p: patch,
6080 um: unmount,
6081 m: move,
6082 r: remove,
6083 mt: mountComponent,
6084 mc: mountChildren,
6085 pc: patchChildren,
6086 pbc: patchBlockChildren,
6087 n: getNextHostNode,
6088 o: options
6089 };
6090 let hydrate;
6091 let hydrateNode;
6092 if (createHydrationFns) {
6093 [hydrate, hydrateNode] = createHydrationFns(internals);
6094 }
6095 return {
6096 render,
6097 hydrate,
6098 createApp: createAppAPI(render, hydrate)
6099 };
6100}
6101function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6102 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6103 vnode,
6104 prevVNode
6105 ]);
6106}
6107/**
6108 * #1156
6109 * When a component is HMR-enabled, we need to make sure that all static nodes
6110 * inside a block also inherit the DOM element from the previous tree so that
6111 * HMR updates (which are full updates) can retrieve the element for patching.
6112 *
6113 * #2080
6114 * Inside keyed `template` fragment static children, if a fragment is moved,
6115 * the children will always moved so that need inherit el form previous nodes
6116 * to ensure correct moved position.
6117 */
6118function traverseStaticChildren(n1, n2, shallow = false) {
6119 const ch1 = n1.children;
6120 const ch2 = n2.children;
6121 if (isArray(ch1) && isArray(ch2)) {
6122 for (let i = 0; i < ch1.length; i++) {
6123 // this is only called in the optimized path so array children are
6124 // guaranteed to be vnodes
6125 const c1 = ch1[i];
6126 let c2 = ch2[i];
6127 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
6128 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
6129 c2 = ch2[i] = cloneIfMounted(ch2[i]);
6130 c2.el = c1.el;
6131 }
6132 if (!shallow)
6133 traverseStaticChildren(c1, c2);
6134 }
6135 // also inherit for comment nodes, but not placeholders (e.g. v-if which
6136 // would have received .el during block patch)
6137 if (c2.type === Comment && !c2.el) {
6138 c2.el = c1.el;
6139 }
6140 }
6141 }
6142}
6143// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
6144function getSequence(arr) {
6145 const p = arr.slice();
6146 const result = [0];
6147 let i, j, u, v, c;
6148 const len = arr.length;
6149 for (i = 0; i < len; i++) {
6150 const arrI = arr[i];
6151 if (arrI !== 0) {
6152 j = result[result.length - 1];
6153 if (arr[j] < arrI) {
6154 p[i] = j;
6155 result.push(i);
6156 continue;
6157 }
6158 u = 0;
6159 v = result.length - 1;
6160 while (u < v) {
6161 c = ((u + v) / 2) | 0;
6162 if (arr[result[c]] < arrI) {
6163 u = c + 1;
6164 }
6165 else {
6166 v = c;
6167 }
6168 }
6169 if (arrI < arr[result[u]]) {
6170 if (u > 0) {
6171 p[i] = result[u - 1];
6172 }
6173 result[u] = i;
6174 }
6175 }
6176 }
6177 u = result.length;
6178 v = result[u - 1];
6179 while (u-- > 0) {
6180 result[u] = v;
6181 v = p[v];
6182 }
6183 return result;
6184}
6185
6186const isTeleport = (type) => type.__isTeleport;
6187const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
6188const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
6189const resolveTarget = (props, select) => {
6190 const targetSelector = props && props.to;
6191 if (isString(targetSelector)) {
6192 if (!select) {
6193 warn(`Current renderer does not support string target for Teleports. ` +
6194 `(missing querySelector renderer option)`);
6195 return null;
6196 }
6197 else {
6198 const target = select(targetSelector);
6199 if (!target) {
6200 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
6201 `Note the target element must exist before the component is mounted - ` +
6202 `i.e. the target cannot be rendered by the component itself, and ` +
6203 `ideally should be outside of the entire Vue component tree.`);
6204 }
6205 return target;
6206 }
6207 }
6208 else {
6209 if (!targetSelector && !isTeleportDisabled(props)) {
6210 warn(`Invalid Teleport target: ${targetSelector}`);
6211 }
6212 return targetSelector;
6213 }
6214};
6215const TeleportImpl = {
6216 __isTeleport: true,
6217 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
6218 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
6219 const disabled = isTeleportDisabled(n2.props);
6220 const { shapeFlag, children } = n2;
6221 // #3302
6222 // HMR updated, force full diff
6223 if (isHmrUpdating) {
6224 optimized = false;
6225 n2.dynamicChildren = null;
6226 }
6227 if (n1 == null) {
6228 // insert anchors in the main view
6229 const placeholder = (n2.el = createComment('teleport start')
6230 );
6231 const mainAnchor = (n2.anchor = createComment('teleport end')
6232 );
6233 insert(placeholder, container, anchor);
6234 insert(mainAnchor, container, anchor);
6235 const target = (n2.target = resolveTarget(n2.props, querySelector));
6236 const targetAnchor = (n2.targetAnchor = createText(''));
6237 if (target) {
6238 insert(targetAnchor, target);
6239 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
6240 isSVG = isSVG || isTargetSVG(target);
6241 }
6242 else if (!disabled) {
6243 warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
6244 }
6245 const mount = (container, anchor) => {
6246 // Teleport *always* has Array children. This is enforced in both the
6247 // compiler and vnode children normalization.
6248 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6249 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6250 }
6251 };
6252 if (disabled) {
6253 mount(container, mainAnchor);
6254 }
6255 else if (target) {
6256 mount(target, targetAnchor);
6257 }
6258 }
6259 else {
6260 // update content
6261 n2.el = n1.el;
6262 const mainAnchor = (n2.anchor = n1.anchor);
6263 const target = (n2.target = n1.target);
6264 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
6265 const wasDisabled = isTeleportDisabled(n1.props);
6266 const currentContainer = wasDisabled ? container : target;
6267 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
6268 isSVG = isSVG || isTargetSVG(target);
6269 if (n2.dynamicChildren) {
6270 // fast path when the teleport happens to be a block root
6271 patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
6272 // even in block tree mode we need to make sure all root-level nodes
6273 // in the teleport inherit previous DOM references so that they can
6274 // be moved in future patches.
6275 traverseStaticChildren(n1, n2, true);
6276 }
6277 else if (!optimized) {
6278 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
6279 }
6280 if (disabled) {
6281 if (!wasDisabled) {
6282 // enabled -> disabled
6283 // move into main container
6284 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
6285 }
6286 }
6287 else {
6288 // target changed
6289 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
6290 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
6291 if (nextTarget) {
6292 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
6293 }
6294 else {
6295 warn('Invalid Teleport target on update:', target, `(${typeof target})`);
6296 }
6297 }
6298 else if (wasDisabled) {
6299 // disabled -> enabled
6300 // move into teleport target
6301 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
6302 }
6303 }
6304 }
6305 },
6306 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
6307 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
6308 if (target) {
6309 hostRemove(targetAnchor);
6310 }
6311 // an unmounted teleport should always remove its children if not disabled
6312 if (doRemove || !isTeleportDisabled(props)) {
6313 hostRemove(anchor);
6314 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6315 for (let i = 0; i < children.length; i++) {
6316 unmount(children[i], parentComponent, parentSuspense, true, optimized);
6317 }
6318 }
6319 }
6320 },
6321 move: moveTeleport,
6322 hydrate: hydrateTeleport
6323};
6324function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
6325 // move target anchor if this is a target change.
6326 if (moveType === 0 /* TARGET_CHANGE */) {
6327 insert(vnode.targetAnchor, container, parentAnchor);
6328 }
6329 const { el, anchor, shapeFlag, children, props } = vnode;
6330 const isReorder = moveType === 2 /* REORDER */;
6331 // move main view anchor if this is a re-order.
6332 if (isReorder) {
6333 insert(el, container, parentAnchor);
6334 }
6335 // if this is a re-order and teleport is enabled (content is in target)
6336 // do not move children. So the opposite is: only move children if this
6337 // is not a reorder, or the teleport is disabled
6338 if (!isReorder || isTeleportDisabled(props)) {
6339 // Teleport has either Array children or no children.
6340 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6341 for (let i = 0; i < children.length; i++) {
6342 move(children[i], container, parentAnchor, 2 /* REORDER */);
6343 }
6344 }
6345 }
6346 // move main view anchor if this is a re-order.
6347 if (isReorder) {
6348 insert(anchor, container, parentAnchor);
6349 }
6350}
6351function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
6352 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
6353 if (target) {
6354 // if multiple teleports rendered to the same target element, we need to
6355 // pick up from where the last teleport finished instead of the first node
6356 const targetNode = target._lpa || target.firstChild;
6357 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
6358 if (isTeleportDisabled(vnode.props)) {
6359 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
6360 vnode.targetAnchor = targetNode;
6361 }
6362 else {
6363 vnode.anchor = nextSibling(node);
6364 vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
6365 }
6366 target._lpa =
6367 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
6368 }
6369 }
6370 return vnode.anchor && nextSibling(vnode.anchor);
6371}
6372// Force-casted public typing for h and TSX props inference
6373const Teleport = TeleportImpl;
6374
6375const COMPONENTS = 'components';
6376const DIRECTIVES = 'directives';
6377/**
6378 * @private
6379 */
6380function resolveComponent(name, maybeSelfReference) {
6381 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
6382}
6383const NULL_DYNAMIC_COMPONENT = Symbol();
6384/**
6385 * @private
6386 */
6387function resolveDynamicComponent(component) {
6388 if (isString(component)) {
6389 return resolveAsset(COMPONENTS, component, false) || component;
6390 }
6391 else {
6392 // invalid types will fallthrough to createVNode and raise warning
6393 return (component || NULL_DYNAMIC_COMPONENT);
6394 }
6395}
6396/**
6397 * @private
6398 */
6399function resolveDirective(name) {
6400 return resolveAsset(DIRECTIVES, name);
6401}
6402// implementation
6403function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
6404 const instance = currentRenderingInstance || currentInstance;
6405 if (instance) {
6406 const Component = instance.type;
6407 // explicit self name has highest priority
6408 if (type === COMPONENTS) {
6409 const selfName = getComponentName(Component);
6410 if (selfName &&
6411 (selfName === name ||
6412 selfName === camelize(name) ||
6413 selfName === capitalize(camelize(name)))) {
6414 return Component;
6415 }
6416 }
6417 const res =
6418 // local registration
6419 // check instance[type] first for components with mixin or extends.
6420 resolve(instance[type] || Component[type], name) ||
6421 // global registration
6422 resolve(instance.appContext[type], name);
6423 if (!res && maybeSelfReference) {
6424 // fallback to implicit self-reference
6425 return Component;
6426 }
6427 if (warnMissing && !res) {
6428 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
6429 }
6430 return res;
6431 }
6432 else {
6433 warn(`resolve${capitalize(type.slice(0, -1))} ` +
6434 `can only be used in render() or setup().`);
6435 }
6436}
6437function resolve(registry, name) {
6438 return (registry &&
6439 (registry[name] ||
6440 registry[camelize(name)] ||
6441 registry[capitalize(camelize(name))]));
6442}
6443
6444const Fragment = Symbol('Fragment' );
6445const Text = Symbol('Text' );
6446const Comment = Symbol('Comment' );
6447const Static = Symbol('Static' );
6448// Since v-if and v-for are the two possible ways node structure can dynamically
6449// change, once we consider v-if branches and each v-for fragment a block, we
6450// can divide a template into nested blocks, and within each block the node
6451// structure would be stable. This allows us to skip most children diffing
6452// and only worry about the dynamic nodes (indicated by patch flags).
6453const blockStack = [];
6454let currentBlock = null;
6455/**
6456 * Open a block.
6457 * This must be called before `createBlock`. It cannot be part of `createBlock`
6458 * because the children of the block are evaluated before `createBlock` itself
6459 * is called. The generated code typically looks like this:
6460 *
6461 * ```js
6462 * function render() {
6463 * return (openBlock(),createBlock('div', null, [...]))
6464 * }
6465 * ```
6466 * disableTracking is true when creating a v-for fragment block, since a v-for
6467 * fragment always diffs its children.
6468 *
6469 * @private
6470 */
6471function openBlock(disableTracking = false) {
6472 blockStack.push((currentBlock = disableTracking ? null : []));
6473}
6474function closeBlock() {
6475 blockStack.pop();
6476 currentBlock = blockStack[blockStack.length - 1] || null;
6477}
6478// Whether we should be tracking dynamic child nodes inside a block.
6479// Only tracks when this value is > 0
6480// We are not using a simple boolean because this value may need to be
6481// incremented/decremented by nested usage of v-once (see below)
6482let shouldTrack$1 = 1;
6483/**
6484 * Block tracking sometimes needs to be disabled, for example during the
6485 * creation of a tree that needs to be cached by v-once. The compiler generates
6486 * code like this:
6487 *
6488 * ``` js
6489 * _cache[1] || (
6490 * setBlockTracking(-1),
6491 * _cache[1] = createVNode(...),
6492 * setBlockTracking(1),
6493 * _cache[1]
6494 * )
6495 * ```
6496 *
6497 * @private
6498 */
6499function setBlockTracking(value) {
6500 shouldTrack$1 += value;
6501}
6502/**
6503 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
6504 * A block root keeps track of dynamic nodes within the block in the
6505 * `dynamicChildren` array.
6506 *
6507 * @private
6508 */
6509function createBlock(type, props, children, patchFlag, dynamicProps) {
6510 const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
6511 // save current block children on the block vnode
6512 vnode.dynamicChildren = currentBlock || EMPTY_ARR;
6513 // close block
6514 closeBlock();
6515 // a block is always going to be patched, so track it as a child of its
6516 // parent block
6517 if (shouldTrack$1 > 0 && currentBlock) {
6518 currentBlock.push(vnode);
6519 }
6520 return vnode;
6521}
6522function isVNode(value) {
6523 return value ? value.__v_isVNode === true : false;
6524}
6525function isSameVNodeType(n1, n2) {
6526 if (n2.shapeFlag & 6 /* COMPONENT */ &&
6527 hmrDirtyComponents.has(n2.type)) {
6528 // HMR only: if the component has been hot-updated, force a reload.
6529 return false;
6530 }
6531 return n1.type === n2.type && n1.key === n2.key;
6532}
6533let vnodeArgsTransformer;
6534/**
6535 * Internal API for registering an arguments transform for createVNode
6536 * used for creating stubs in the test-utils
6537 * It is *internal* but needs to be exposed for test-utils to pick up proper
6538 * typings
6539 */
6540function transformVNodeArgs(transformer) {
6541 vnodeArgsTransformer = transformer;
6542}
6543const createVNodeWithArgsTransform = (...args) => {
6544 return _createVNode(...(vnodeArgsTransformer
6545 ? vnodeArgsTransformer(args, currentRenderingInstance)
6546 : args));
6547};
6548const InternalObjectKey = `__vInternal`;
6549const normalizeKey = ({ key }) => key != null ? key : null;
6550const normalizeRef = ({ ref }) => {
6551 return (ref != null
6552 ? isString(ref) || isRef(ref) || isFunction(ref)
6553 ? { i: currentRenderingInstance, r: ref }
6554 : ref
6555 : null);
6556};
6557const createVNode = (createVNodeWithArgsTransform
6558 );
6559function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
6560 if (!type || type === NULL_DYNAMIC_COMPONENT) {
6561 if (!type) {
6562 warn(`Invalid vnode type when creating vnode: ${type}.`);
6563 }
6564 type = Comment;
6565 }
6566 if (isVNode(type)) {
6567 // createVNode receiving an existing vnode. This happens in cases like
6568 // <component :is="vnode"/>
6569 // #2078 make sure to merge refs during the clone instead of overwriting it
6570 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
6571 if (children) {
6572 normalizeChildren(cloned, children);
6573 }
6574 return cloned;
6575 }
6576 // class component normalization.
6577 if (isClassComponent(type)) {
6578 type = type.__vccOpts;
6579 }
6580 // class & style normalization.
6581 if (props) {
6582 // for reactive or proxy objects, we need to clone it to enable mutation.
6583 if (isProxy(props) || InternalObjectKey in props) {
6584 props = extend({}, props);
6585 }
6586 let { class: klass, style } = props;
6587 if (klass && !isString(klass)) {
6588 props.class = normalizeClass(klass);
6589 }
6590 if (isObject(style)) {
6591 // reactive state objects need to be cloned since they are likely to be
6592 // mutated
6593 if (isProxy(style) && !isArray(style)) {
6594 style = extend({}, style);
6595 }
6596 props.style = normalizeStyle(style);
6597 }
6598 }
6599 // encode the vnode type information into a bitmap
6600 const shapeFlag = isString(type)
6601 ? 1 /* ELEMENT */
6602 : isSuspense(type)
6603 ? 128 /* SUSPENSE */
6604 : isTeleport(type)
6605 ? 64 /* TELEPORT */
6606 : isObject(type)
6607 ? 4 /* STATEFUL_COMPONENT */
6608 : isFunction(type)
6609 ? 2 /* FUNCTIONAL_COMPONENT */
6610 : 0;
6611 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
6612 type = toRaw(type);
6613 warn(`Vue received a Component which was made a reactive object. This can ` +
6614 `lead to unnecessary performance overhead, and should be avoided by ` +
6615 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
6616 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
6617 }
6618 const vnode = {
6619 __v_isVNode: true,
6620 ["__v_skip" /* SKIP */]: true,
6621 type,
6622 props,
6623 key: props && normalizeKey(props),
6624 ref: props && normalizeRef(props),
6625 scopeId: currentScopeId,
6626 slotScopeIds: null,
6627 children: null,
6628 component: null,
6629 suspense: null,
6630 ssContent: null,
6631 ssFallback: null,
6632 dirs: null,
6633 transition: null,
6634 el: null,
6635 anchor: null,
6636 target: null,
6637 targetAnchor: null,
6638 staticCount: 0,
6639 shapeFlag,
6640 patchFlag,
6641 dynamicProps,
6642 dynamicChildren: null,
6643 appContext: null
6644 };
6645 // validate key
6646 if (vnode.key !== vnode.key) {
6647 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
6648 }
6649 normalizeChildren(vnode, children);
6650 // normalize suspense children
6651 if (shapeFlag & 128 /* SUSPENSE */) {
6652 const { content, fallback } = normalizeSuspenseChildren(vnode);
6653 vnode.ssContent = content;
6654 vnode.ssFallback = fallback;
6655 }
6656 if (shouldTrack$1 > 0 &&
6657 // avoid a block node from tracking itself
6658 !isBlockNode &&
6659 // has current parent block
6660 currentBlock &&
6661 // presence of a patch flag indicates this node needs patching on updates.
6662 // component nodes also should always be patched, because even if the
6663 // component doesn't need to update, it needs to persist the instance on to
6664 // the next vnode so that it can be properly unmounted later.
6665 (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
6666 // the EVENTS flag is only for hydration and if it is the only flag, the
6667 // vnode should not be considered dynamic due to handler caching.
6668 patchFlag !== 32 /* HYDRATE_EVENTS */) {
6669 currentBlock.push(vnode);
6670 }
6671 return vnode;
6672}
6673function cloneVNode(vnode, extraProps, mergeRef = false) {
6674 // This is intentionally NOT using spread or extend to avoid the runtime
6675 // key enumeration cost.
6676 const { props, ref, patchFlag, children } = vnode;
6677 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
6678 return {
6679 __v_isVNode: true,
6680 ["__v_skip" /* SKIP */]: true,
6681 type: vnode.type,
6682 props: mergedProps,
6683 key: mergedProps && normalizeKey(mergedProps),
6684 ref: extraProps && extraProps.ref
6685 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
6686 // if the vnode itself already has a ref, cloneVNode will need to merge
6687 // the refs so the single vnode can be set on multiple refs
6688 mergeRef && ref
6689 ? isArray(ref)
6690 ? ref.concat(normalizeRef(extraProps))
6691 : [ref, normalizeRef(extraProps)]
6692 : normalizeRef(extraProps)
6693 : ref,
6694 scopeId: vnode.scopeId,
6695 slotScopeIds: vnode.slotScopeIds,
6696 children: patchFlag === -1 /* HOISTED */ && isArray(children)
6697 ? children.map(deepCloneVNode)
6698 : children,
6699 target: vnode.target,
6700 targetAnchor: vnode.targetAnchor,
6701 staticCount: vnode.staticCount,
6702 shapeFlag: vnode.shapeFlag,
6703 // if the vnode is cloned with extra props, we can no longer assume its
6704 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
6705 // note: perserve flag for fragments since they use the flag for children
6706 // fast paths only.
6707 patchFlag: extraProps && vnode.type !== Fragment
6708 ? patchFlag === -1 // hoisted node
6709 ? 16 /* FULL_PROPS */
6710 : patchFlag | 16 /* FULL_PROPS */
6711 : patchFlag,
6712 dynamicProps: vnode.dynamicProps,
6713 dynamicChildren: vnode.dynamicChildren,
6714 appContext: vnode.appContext,
6715 dirs: vnode.dirs,
6716 transition: vnode.transition,
6717 // These should technically only be non-null on mounted VNodes. However,
6718 // they *should* be copied for kept-alive vnodes. So we just always copy
6719 // them since them being non-null during a mount doesn't affect the logic as
6720 // they will simply be overwritten.
6721 component: vnode.component,
6722 suspense: vnode.suspense,
6723 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
6724 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
6725 el: vnode.el,
6726 anchor: vnode.anchor
6727 };
6728}
6729/**
6730 * Dev only, for HMR of hoisted vnodes reused in v-for
6731 * https://github.com/vitejs/vite/issues/2022
6732 */
6733function deepCloneVNode(vnode) {
6734 const cloned = cloneVNode(vnode);
6735 if (isArray(vnode.children)) {
6736 cloned.children = vnode.children.map(deepCloneVNode);
6737 }
6738 return cloned;
6739}
6740/**
6741 * @private
6742 */
6743function createTextVNode(text = ' ', flag = 0) {
6744 return createVNode(Text, null, text, flag);
6745}
6746/**
6747 * @private
6748 */
6749function createStaticVNode(content, numberOfNodes) {
6750 // A static vnode can contain multiple stringified elements, and the number
6751 // of elements is necessary for hydration.
6752 const vnode = createVNode(Static, null, content);
6753 vnode.staticCount = numberOfNodes;
6754 return vnode;
6755}
6756/**
6757 * @private
6758 */
6759function createCommentVNode(text = '',
6760// when used as the v-else branch, the comment node must be created as a
6761// block to ensure correct updates.
6762asBlock = false) {
6763 return asBlock
6764 ? (openBlock(), createBlock(Comment, null, text))
6765 : createVNode(Comment, null, text);
6766}
6767function normalizeVNode(child) {
6768 if (child == null || typeof child === 'boolean') {
6769 // empty placeholder
6770 return createVNode(Comment);
6771 }
6772 else if (isArray(child)) {
6773 // fragment
6774 return createVNode(Fragment, null, child);
6775 }
6776 else if (typeof child === 'object') {
6777 // already vnode, this should be the most common since compiled templates
6778 // always produce all-vnode children arrays
6779 return child.el === null ? child : cloneVNode(child);
6780 }
6781 else {
6782 // strings and numbers
6783 return createVNode(Text, null, String(child));
6784 }
6785}
6786// optimized normalization for template-compiled render fns
6787function cloneIfMounted(child) {
6788 return child.el === null ? child : cloneVNode(child);
6789}
6790function normalizeChildren(vnode, children) {
6791 let type = 0;
6792 const { shapeFlag } = vnode;
6793 if (children == null) {
6794 children = null;
6795 }
6796 else if (isArray(children)) {
6797 type = 16 /* ARRAY_CHILDREN */;
6798 }
6799 else if (typeof children === 'object') {
6800 if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
6801 // Normalize slot to plain children for plain element and Teleport
6802 const slot = children.default;
6803 if (slot) {
6804 // _c marker is added by withCtx() indicating this is a compiled slot
6805 slot._c && setCompiledSlotRendering(1);
6806 normalizeChildren(vnode, slot());
6807 slot._c && setCompiledSlotRendering(-1);
6808 }
6809 return;
6810 }
6811 else {
6812 type = 32 /* SLOTS_CHILDREN */;
6813 const slotFlag = children._;
6814 if (!slotFlag && !(InternalObjectKey in children)) {
6815 children._ctx = currentRenderingInstance;
6816 }
6817 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
6818 // a child component receives forwarded slots from the parent.
6819 // its slot type is determined by its parent's slot type.
6820 if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
6821 children._ = 2 /* DYNAMIC */;
6822 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
6823 }
6824 else {
6825 children._ = 1 /* STABLE */;
6826 }
6827 }
6828 }
6829 }
6830 else if (isFunction(children)) {
6831 children = { default: children, _ctx: currentRenderingInstance };
6832 type = 32 /* SLOTS_CHILDREN */;
6833 }
6834 else {
6835 children = String(children);
6836 // force teleport children to array so it can be moved around
6837 if (shapeFlag & 64 /* TELEPORT */) {
6838 type = 16 /* ARRAY_CHILDREN */;
6839 children = [createTextVNode(children)];
6840 }
6841 else {
6842 type = 8 /* TEXT_CHILDREN */;
6843 }
6844 }
6845 vnode.children = children;
6846 vnode.shapeFlag |= type;
6847}
6848function mergeProps(...args) {
6849 const ret = extend({}, args[0]);
6850 for (let i = 1; i < args.length; i++) {
6851 const toMerge = args[i];
6852 for (const key in toMerge) {
6853 if (key === 'class') {
6854 if (ret.class !== toMerge.class) {
6855 ret.class = normalizeClass([ret.class, toMerge.class]);
6856 }
6857 }
6858 else if (key === 'style') {
6859 ret.style = normalizeStyle([ret.style, toMerge.style]);
6860 }
6861 else if (isOn(key)) {
6862 const existing = ret[key];
6863 const incoming = toMerge[key];
6864 if (existing !== incoming) {
6865 ret[key] = existing
6866 ? [].concat(existing, toMerge[key])
6867 : incoming;
6868 }
6869 }
6870 else if (key !== '') {
6871 ret[key] = toMerge[key];
6872 }
6873 }
6874 }
6875 return ret;
6876}
6877
6878function provide(key, value) {
6879 if (!currentInstance) {
6880 {
6881 warn(`provide() can only be used inside setup().`);
6882 }
6883 }
6884 else {
6885 let provides = currentInstance.provides;
6886 // by default an instance inherits its parent's provides object
6887 // but when it needs to provide values of its own, it creates its
6888 // own provides object using parent provides object as prototype.
6889 // this way in `inject` we can simply look up injections from direct
6890 // parent and let the prototype chain do the work.
6891 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
6892 if (parentProvides === provides) {
6893 provides = currentInstance.provides = Object.create(parentProvides);
6894 }
6895 // TS doesn't allow symbol as index type
6896 provides[key] = value;
6897 }
6898}
6899function inject(key, defaultValue, treatDefaultAsFactory = false) {
6900 // fallback to `currentRenderingInstance` so that this can be called in
6901 // a functional component
6902 const instance = currentInstance || currentRenderingInstance;
6903 if (instance) {
6904 // #2400
6905 // to support `app.use` plugins,
6906 // fallback to appContext's `provides` if the intance is at root
6907 const provides = instance.parent == null
6908 ? instance.vnode.appContext && instance.vnode.appContext.provides
6909 : instance.parent.provides;
6910 if (provides && key in provides) {
6911 // TS doesn't allow symbol as index type
6912 return provides[key];
6913 }
6914 else if (arguments.length > 1) {
6915 return treatDefaultAsFactory && isFunction(defaultValue)
6916 ? defaultValue()
6917 : defaultValue;
6918 }
6919 else {
6920 warn(`injection "${String(key)}" not found.`);
6921 }
6922 }
6923 else {
6924 warn(`inject() can only be used inside setup() or functional components.`);
6925 }
6926}
6927
6928function createDuplicateChecker() {
6929 const cache = Object.create(null);
6930 return (type, key) => {
6931 if (cache[key]) {
6932 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
6933 }
6934 else {
6935 cache[key] = type;
6936 }
6937 };
6938}
6939let shouldCacheAccess = true;
6940function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
6941 const {
6942 // composition
6943 mixins, extends: extendsOptions,
6944 // state
6945 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
6946 // assets
6947 components, directives,
6948 // lifecycle
6949 beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured,
6950 // public API
6951 expose } = options;
6952 const publicThis = instance.proxy;
6953 const ctx = instance.ctx;
6954 const globalMixins = instance.appContext.mixins;
6955 if (asMixin && render && instance.render === NOOP) {
6956 instance.render = render;
6957 }
6958 // applyOptions is called non-as-mixin once per instance
6959 if (!asMixin) {
6960 shouldCacheAccess = false;
6961 callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
6962 shouldCacheAccess = true;
6963 // global mixins are applied first
6964 applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
6965 }
6966 // extending a base component...
6967 if (extendsOptions) {
6968 applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
6969 }
6970 // local mixins
6971 if (mixins) {
6972 applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
6973 }
6974 const checkDuplicateProperties = createDuplicateChecker() ;
6975 {
6976 const [propsOptions] = instance.propsOptions;
6977 if (propsOptions) {
6978 for (const key in propsOptions) {
6979 checkDuplicateProperties("Props" /* PROPS */, key);
6980 }
6981 }
6982 }
6983 // options initialization order (to be consistent with Vue 2):
6984 // - props (already done outside of this function)
6985 // - inject
6986 // - methods
6987 // - data (deferred since it relies on `this` access)
6988 // - computed
6989 // - watch (deferred since it relies on `this` access)
6990 if (injectOptions) {
6991 if (isArray(injectOptions)) {
6992 for (let i = 0; i < injectOptions.length; i++) {
6993 const key = injectOptions[i];
6994 ctx[key] = inject(key);
6995 {
6996 checkDuplicateProperties("Inject" /* INJECT */, key);
6997 }
6998 }
6999 }
7000 else {
7001 for (const key in injectOptions) {
7002 const opt = injectOptions[key];
7003 if (isObject(opt)) {
7004 ctx[key] = inject(opt.from || key, opt.default, true /* treat default function as factory */);
7005 }
7006 else {
7007 ctx[key] = inject(opt);
7008 }
7009 {
7010 checkDuplicateProperties("Inject" /* INJECT */, key);
7011 }
7012 }
7013 }
7014 }
7015 if (methods) {
7016 for (const key in methods) {
7017 const methodHandler = methods[key];
7018 if (isFunction(methodHandler)) {
7019 // In dev mode, we use the `createRenderContext` function to define methods to the proxy target,
7020 // and those are read-only but reconfigurable, so it needs to be redefined here
7021 {
7022 Object.defineProperty(ctx, key, {
7023 value: methodHandler.bind(publicThis),
7024 configurable: true,
7025 enumerable: true,
7026 writable: true
7027 });
7028 }
7029 {
7030 checkDuplicateProperties("Methods" /* METHODS */, key);
7031 }
7032 }
7033 else {
7034 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
7035 `Did you reference the function correctly?`);
7036 }
7037 }
7038 }
7039 if (!asMixin) {
7040 if (deferredData.length) {
7041 deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis));
7042 }
7043 if (dataOptions) {
7044 // @ts-ignore dataOptions is not fully type safe
7045 resolveData(instance, dataOptions, publicThis);
7046 }
7047 {
7048 const rawData = toRaw(instance.data);
7049 for (const key in rawData) {
7050 checkDuplicateProperties("Data" /* DATA */, key);
7051 // expose data on ctx during dev
7052 if (key[0] !== '$' && key[0] !== '_') {
7053 Object.defineProperty(ctx, key, {
7054 configurable: true,
7055 enumerable: true,
7056 get: () => rawData[key],
7057 set: NOOP
7058 });
7059 }
7060 }
7061 }
7062 }
7063 else if (dataOptions) {
7064 deferredData.push(dataOptions);
7065 }
7066 if (computedOptions) {
7067 for (const key in computedOptions) {
7068 const opt = computedOptions[key];
7069 const get = isFunction(opt)
7070 ? opt.bind(publicThis, publicThis)
7071 : isFunction(opt.get)
7072 ? opt.get.bind(publicThis, publicThis)
7073 : NOOP;
7074 if (get === NOOP) {
7075 warn(`Computed property "${key}" has no getter.`);
7076 }
7077 const set = !isFunction(opt) && isFunction(opt.set)
7078 ? opt.set.bind(publicThis)
7079 : () => {
7080 warn(`Write operation failed: computed property "${key}" is readonly.`);
7081 }
7082 ;
7083 const c = computed$1({
7084 get,
7085 set
7086 });
7087 Object.defineProperty(ctx, key, {
7088 enumerable: true,
7089 configurable: true,
7090 get: () => c.value,
7091 set: v => (c.value = v)
7092 });
7093 {
7094 checkDuplicateProperties("Computed" /* COMPUTED */, key);
7095 }
7096 }
7097 }
7098 if (watchOptions) {
7099 deferredWatch.push(watchOptions);
7100 }
7101 if (!asMixin && deferredWatch.length) {
7102 deferredWatch.forEach(watchOptions => {
7103 for (const key in watchOptions) {
7104 createWatcher(watchOptions[key], ctx, publicThis, key);
7105 }
7106 });
7107 }
7108 if (provideOptions) {
7109 deferredProvide.push(provideOptions);
7110 }
7111 if (!asMixin && deferredProvide.length) {
7112 deferredProvide.forEach(provideOptions => {
7113 const provides = isFunction(provideOptions)
7114 ? provideOptions.call(publicThis)
7115 : provideOptions;
7116 Reflect.ownKeys(provides).forEach(key => {
7117 provide(key, provides[key]);
7118 });
7119 });
7120 }
7121 // asset options.
7122 // To reduce memory usage, only components with mixins or extends will have
7123 // resolved asset registry attached to instance.
7124 if (asMixin) {
7125 if (components) {
7126 extend(instance.components ||
7127 (instance.components = extend({}, instance.type.components)), components);
7128 }
7129 if (directives) {
7130 extend(instance.directives ||
7131 (instance.directives = extend({}, instance.type.directives)), directives);
7132 }
7133 }
7134 // lifecycle options
7135 if (!asMixin) {
7136 callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
7137 }
7138 if (beforeMount) {
7139 onBeforeMount(beforeMount.bind(publicThis));
7140 }
7141 if (mounted) {
7142 onMounted(mounted.bind(publicThis));
7143 }
7144 if (beforeUpdate) {
7145 onBeforeUpdate(beforeUpdate.bind(publicThis));
7146 }
7147 if (updated) {
7148 onUpdated(updated.bind(publicThis));
7149 }
7150 if (activated) {
7151 onActivated(activated.bind(publicThis));
7152 }
7153 if (deactivated) {
7154 onDeactivated(deactivated.bind(publicThis));
7155 }
7156 if (errorCaptured) {
7157 onErrorCaptured(errorCaptured.bind(publicThis));
7158 }
7159 if (renderTracked) {
7160 onRenderTracked(renderTracked.bind(publicThis));
7161 }
7162 if (renderTriggered) {
7163 onRenderTriggered(renderTriggered.bind(publicThis));
7164 }
7165 if (beforeDestroy) {
7166 warn(`\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`);
7167 }
7168 if (beforeUnmount) {
7169 onBeforeUnmount(beforeUnmount.bind(publicThis));
7170 }
7171 if (destroyed) {
7172 warn(`\`destroyed\` has been renamed to \`unmounted\`.`);
7173 }
7174 if (unmounted) {
7175 onUnmounted(unmounted.bind(publicThis));
7176 }
7177 if (isArray(expose)) {
7178 if (!asMixin) {
7179 if (expose.length) {
7180 const exposed = instance.exposed || (instance.exposed = proxyRefs({}));
7181 expose.forEach(key => {
7182 exposed[key] = toRef(publicThis, key);
7183 });
7184 }
7185 else if (!instance.exposed) {
7186 instance.exposed = EMPTY_OBJ;
7187 }
7188 }
7189 else {
7190 warn(`The \`expose\` option is ignored when used in mixins.`);
7191 }
7192 }
7193}
7194function callSyncHook(name, type, options, instance, globalMixins) {
7195 for (let i = 0; i < globalMixins.length; i++) {
7196 callHookWithMixinAndExtends(name, type, globalMixins[i], instance);
7197 }
7198 callHookWithMixinAndExtends(name, type, options, instance);
7199}
7200function callHookWithMixinAndExtends(name, type, options, instance) {
7201 const { extends: base, mixins } = options;
7202 const selfHook = options[name];
7203 if (base) {
7204 callHookWithMixinAndExtends(name, type, base, instance);
7205 }
7206 if (mixins) {
7207 for (let i = 0; i < mixins.length; i++) {
7208 callHookWithMixinAndExtends(name, type, mixins[i], instance);
7209 }
7210 }
7211 if (selfHook) {
7212 callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
7213 }
7214}
7215function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
7216 for (let i = 0; i < mixins.length; i++) {
7217 applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
7218 }
7219}
7220function resolveData(instance, dataFn, publicThis) {
7221 if (!isFunction(dataFn)) {
7222 warn(`The data option must be a function. ` +
7223 `Plain object usage is no longer supported.`);
7224 }
7225 shouldCacheAccess = false;
7226 const data = dataFn.call(publicThis, publicThis);
7227 shouldCacheAccess = true;
7228 if (isPromise(data)) {
7229 warn(`data() returned a Promise - note data() cannot be async; If you ` +
7230 `intend to perform data fetching before component renders, use ` +
7231 `async setup() + <Suspense>.`);
7232 }
7233 if (!isObject(data)) {
7234 warn(`data() should return an object.`);
7235 }
7236 else if (instance.data === EMPTY_OBJ) {
7237 instance.data = reactive(data);
7238 }
7239 else {
7240 // existing data: this is a mixin or extends.
7241 extend(instance.data, data);
7242 }
7243}
7244function createWatcher(raw, ctx, publicThis, key) {
7245 const getter = key.includes('.')
7246 ? createPathGetter(publicThis, key)
7247 : () => publicThis[key];
7248 if (isString(raw)) {
7249 const handler = ctx[raw];
7250 if (isFunction(handler)) {
7251 watch(getter, handler);
7252 }
7253 else {
7254 warn(`Invalid watch handler specified by key "${raw}"`, handler);
7255 }
7256 }
7257 else if (isFunction(raw)) {
7258 watch(getter, raw.bind(publicThis));
7259 }
7260 else if (isObject(raw)) {
7261 if (isArray(raw)) {
7262 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
7263 }
7264 else {
7265 const handler = isFunction(raw.handler)
7266 ? raw.handler.bind(publicThis)
7267 : ctx[raw.handler];
7268 if (isFunction(handler)) {
7269 watch(getter, handler, raw);
7270 }
7271 else {
7272 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
7273 }
7274 }
7275 }
7276 else {
7277 warn(`Invalid watch option: "${key}"`, raw);
7278 }
7279}
7280function createPathGetter(ctx, path) {
7281 const segments = path.split('.');
7282 return () => {
7283 let cur = ctx;
7284 for (let i = 0; i < segments.length && cur; i++) {
7285 cur = cur[segments[i]];
7286 }
7287 return cur;
7288 };
7289}
7290function resolveMergedOptions(instance) {
7291 const raw = instance.type;
7292 const { __merged, mixins, extends: extendsOptions } = raw;
7293 if (__merged)
7294 return __merged;
7295 const globalMixins = instance.appContext.mixins;
7296 if (!globalMixins.length && !mixins && !extendsOptions)
7297 return raw;
7298 const options = {};
7299 globalMixins.forEach(m => mergeOptions(options, m, instance));
7300 mergeOptions(options, raw, instance);
7301 return (raw.__merged = options);
7302}
7303function mergeOptions(to, from, instance) {
7304 const strats = instance.appContext.config.optionMergeStrategies;
7305 const { mixins, extends: extendsOptions } = from;
7306 extendsOptions && mergeOptions(to, extendsOptions, instance);
7307 mixins &&
7308 mixins.forEach((m) => mergeOptions(to, m, instance));
7309 for (const key in from) {
7310 if (strats && hasOwn(strats, key)) {
7311 to[key] = strats[key](to[key], from[key], instance.proxy, key);
7312 }
7313 else {
7314 to[key] = from[key];
7315 }
7316 }
7317}
7318
7319/**
7320 * #2437 In Vue 3, functional components do not have a public instance proxy but
7321 * they exist in the internal parent chain. For code that relies on traversing
7322 * public $parent chains, skip functional ones and go to the parent instead.
7323 */
7324const getPublicInstance = (i) => {
7325 if (!i)
7326 return null;
7327 if (isStatefulComponent(i))
7328 return i.exposed ? i.exposed : i.proxy;
7329 return getPublicInstance(i.parent);
7330};
7331const publicPropertiesMap = extend(Object.create(null), {
7332 $: i => i,
7333 $el: i => i.vnode.el,
7334 $data: i => i.data,
7335 $props: i => (shallowReadonly(i.props) ),
7336 $attrs: i => (shallowReadonly(i.attrs) ),
7337 $slots: i => (shallowReadonly(i.slots) ),
7338 $refs: i => (shallowReadonly(i.refs) ),
7339 $parent: i => getPublicInstance(i.parent),
7340 $root: i => getPublicInstance(i.root),
7341 $emit: i => i.emit,
7342 $options: i => (resolveMergedOptions(i) ),
7343 $forceUpdate: i => () => queueJob(i.update),
7344 $nextTick: i => nextTick.bind(i.proxy),
7345 $watch: i => (instanceWatch.bind(i) )
7346});
7347const PublicInstanceProxyHandlers = {
7348 get({ _: instance }, key) {
7349 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
7350 // let @vue/reactivity know it should never observe Vue public instances.
7351 if (key === "__v_skip" /* SKIP */) {
7352 return true;
7353 }
7354 // for internal formatters to know that this is a Vue instance
7355 if (key === '__isVue') {
7356 return true;
7357 }
7358 // data / props / ctx
7359 // This getter gets called for every property access on the render context
7360 // during render and is a major hotspot. The most expensive part of this
7361 // is the multiple hasOwn() calls. It's much faster to do a simple property
7362 // access on a plain object, so we use an accessCache object (with null
7363 // prototype) to memoize what access type a key corresponds to.
7364 let normalizedProps;
7365 if (key[0] !== '$') {
7366 const n = accessCache[key];
7367 if (n !== undefined) {
7368 switch (n) {
7369 case 0 /* SETUP */:
7370 return setupState[key];
7371 case 1 /* DATA */:
7372 return data[key];
7373 case 3 /* CONTEXT */:
7374 return ctx[key];
7375 case 2 /* PROPS */:
7376 return props[key];
7377 // default: just fallthrough
7378 }
7379 }
7380 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7381 accessCache[key] = 0 /* SETUP */;
7382 return setupState[key];
7383 }
7384 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7385 accessCache[key] = 1 /* DATA */;
7386 return data[key];
7387 }
7388 else if (
7389 // only cache other properties when instance has declared (thus stable)
7390 // props
7391 (normalizedProps = instance.propsOptions[0]) &&
7392 hasOwn(normalizedProps, key)) {
7393 accessCache[key] = 2 /* PROPS */;
7394 return props[key];
7395 }
7396 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7397 accessCache[key] = 3 /* CONTEXT */;
7398 return ctx[key];
7399 }
7400 else if (shouldCacheAccess) {
7401 accessCache[key] = 4 /* OTHER */;
7402 }
7403 }
7404 const publicGetter = publicPropertiesMap[key];
7405 let cssModule, globalProperties;
7406 // public $xxx properties
7407 if (publicGetter) {
7408 if (key === '$attrs') {
7409 track(instance, "get" /* GET */, key);
7410 markAttrsAccessed();
7411 }
7412 return publicGetter(instance);
7413 }
7414 else if (
7415 // css module (injected by vue-loader)
7416 (cssModule = type.__cssModules) &&
7417 (cssModule = cssModule[key])) {
7418 return cssModule;
7419 }
7420 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7421 // user may set custom properties to `this` that start with `$`
7422 accessCache[key] = 3 /* CONTEXT */;
7423 return ctx[key];
7424 }
7425 else if (
7426 // global properties
7427 ((globalProperties = appContext.config.globalProperties),
7428 hasOwn(globalProperties, key))) {
7429 return globalProperties[key];
7430 }
7431 else if (currentRenderingInstance &&
7432 (!isString(key) ||
7433 // #1091 avoid internal isRef/isVNode checks on component instance leading
7434 // to infinite warning loop
7435 key.indexOf('__v') !== 0)) {
7436 if (data !== EMPTY_OBJ &&
7437 (key[0] === '$' || key[0] === '_') &&
7438 hasOwn(data, key)) {
7439 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
7440 `character ("$" or "_") and is not proxied on the render context.`);
7441 }
7442 else if (instance === currentRenderingInstance) {
7443 warn(`Property ${JSON.stringify(key)} was accessed during render ` +
7444 `but is not defined on instance.`);
7445 }
7446 }
7447 },
7448 set({ _: instance }, key, value) {
7449 const { data, setupState, ctx } = instance;
7450 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7451 setupState[key] = value;
7452 }
7453 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7454 data[key] = value;
7455 }
7456 else if (hasOwn(instance.props, key)) {
7457 warn(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
7458 return false;
7459 }
7460 if (key[0] === '$' && key.slice(1) in instance) {
7461 warn(`Attempting to mutate public property "${key}". ` +
7462 `Properties starting with $ are reserved and readonly.`, instance);
7463 return false;
7464 }
7465 else {
7466 if (key in instance.appContext.config.globalProperties) {
7467 Object.defineProperty(ctx, key, {
7468 enumerable: true,
7469 configurable: true,
7470 value
7471 });
7472 }
7473 else {
7474 ctx[key] = value;
7475 }
7476 }
7477 return true;
7478 },
7479 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7480 let normalizedProps;
7481 return (accessCache[key] !== undefined ||
7482 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7483 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7484 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
7485 hasOwn(ctx, key) ||
7486 hasOwn(publicPropertiesMap, key) ||
7487 hasOwn(appContext.config.globalProperties, key));
7488 }
7489};
7490{
7491 PublicInstanceProxyHandlers.ownKeys = (target) => {
7492 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
7493 `The keys will be empty in production mode to avoid performance overhead.`);
7494 return Reflect.ownKeys(target);
7495 };
7496}
7497const RuntimeCompiledPublicInstanceProxyHandlers = extend({}, PublicInstanceProxyHandlers, {
7498 get(target, key) {
7499 // fast path for unscopables when using `with` block
7500 if (key === Symbol.unscopables) {
7501 return;
7502 }
7503 return PublicInstanceProxyHandlers.get(target, key, target);
7504 },
7505 has(_, key) {
7506 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
7507 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
7508 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
7509 }
7510 return has;
7511 }
7512});
7513// In dev mode, the proxy target exposes the same properties as seen on `this`
7514// for easier console inspection. In prod mode it will be an empty object so
7515// these properties definitions can be skipped.
7516function createRenderContext(instance) {
7517 const target = {};
7518 // expose internal instance for proxy handlers
7519 Object.defineProperty(target, `_`, {
7520 configurable: true,
7521 enumerable: false,
7522 get: () => instance
7523 });
7524 // expose public properties
7525 Object.keys(publicPropertiesMap).forEach(key => {
7526 Object.defineProperty(target, key, {
7527 configurable: true,
7528 enumerable: false,
7529 get: () => publicPropertiesMap[key](instance),
7530 // intercepted by the proxy so no need for implementation,
7531 // but needed to prevent set errors
7532 set: NOOP
7533 });
7534 });
7535 // expose global properties
7536 const { globalProperties } = instance.appContext.config;
7537 Object.keys(globalProperties).forEach(key => {
7538 Object.defineProperty(target, key, {
7539 configurable: true,
7540 enumerable: false,
7541 get: () => globalProperties[key],
7542 set: NOOP
7543 });
7544 });
7545 return target;
7546}
7547// dev only
7548function exposePropsOnRenderContext(instance) {
7549 const { ctx, propsOptions: [propsOptions] } = instance;
7550 if (propsOptions) {
7551 Object.keys(propsOptions).forEach(key => {
7552 Object.defineProperty(ctx, key, {
7553 enumerable: true,
7554 configurable: true,
7555 get: () => instance.props[key],
7556 set: NOOP
7557 });
7558 });
7559 }
7560}
7561// dev only
7562function exposeSetupStateOnRenderContext(instance) {
7563 const { ctx, setupState } = instance;
7564 Object.keys(toRaw(setupState)).forEach(key => {
7565 if (key[0] === '$' || key[0] === '_') {
7566 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
7567 `which are reserved prefixes for Vue internals.`);
7568 return;
7569 }
7570 Object.defineProperty(ctx, key, {
7571 enumerable: true,
7572 configurable: true,
7573 get: () => setupState[key],
7574 set: NOOP
7575 });
7576 });
7577}
7578
7579const emptyAppContext = createAppContext();
7580let uid$2 = 0;
7581function createComponentInstance(vnode, parent, suspense) {
7582 const type = vnode.type;
7583 // inherit parent app context - or - if root, adopt from root vnode
7584 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
7585 const instance = {
7586 uid: uid$2++,
7587 vnode,
7588 type,
7589 parent,
7590 appContext,
7591 root: null,
7592 next: null,
7593 subTree: null,
7594 update: null,
7595 render: null,
7596 proxy: null,
7597 exposed: null,
7598 withProxy: null,
7599 effects: null,
7600 provides: parent ? parent.provides : Object.create(appContext.provides),
7601 accessCache: null,
7602 renderCache: [],
7603 // local resovled assets
7604 components: null,
7605 directives: null,
7606 // resolved props and emits options
7607 propsOptions: normalizePropsOptions(type, appContext),
7608 emitsOptions: normalizeEmitsOptions(type, appContext),
7609 // emit
7610 emit: null,
7611 emitted: null,
7612 // props default value
7613 propsDefaults: EMPTY_OBJ,
7614 // state
7615 ctx: EMPTY_OBJ,
7616 data: EMPTY_OBJ,
7617 props: EMPTY_OBJ,
7618 attrs: EMPTY_OBJ,
7619 slots: EMPTY_OBJ,
7620 refs: EMPTY_OBJ,
7621 setupState: EMPTY_OBJ,
7622 setupContext: null,
7623 // suspense related
7624 suspense,
7625 suspenseId: suspense ? suspense.pendingId : 0,
7626 asyncDep: null,
7627 asyncResolved: false,
7628 // lifecycle hooks
7629 // not using enums here because it results in computed properties
7630 isMounted: false,
7631 isUnmounted: false,
7632 isDeactivated: false,
7633 bc: null,
7634 c: null,
7635 bm: null,
7636 m: null,
7637 bu: null,
7638 u: null,
7639 um: null,
7640 bum: null,
7641 da: null,
7642 a: null,
7643 rtg: null,
7644 rtc: null,
7645 ec: null
7646 };
7647 {
7648 instance.ctx = createRenderContext(instance);
7649 }
7650 instance.root = parent ? parent.root : instance;
7651 instance.emit = emit.bind(null, instance);
7652 return instance;
7653}
7654let currentInstance = null;
7655const getCurrentInstance = () => currentInstance || currentRenderingInstance;
7656const setCurrentInstance = (instance) => {
7657 currentInstance = instance;
7658};
7659const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
7660function validateComponentName(name, config) {
7661 const appIsNativeTag = config.isNativeTag || NO;
7662 if (isBuiltInTag(name) || appIsNativeTag(name)) {
7663 warn('Do not use built-in or reserved HTML elements as component id: ' + name);
7664 }
7665}
7666function isStatefulComponent(instance) {
7667 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
7668}
7669let isInSSRComponentSetup = false;
7670function setupComponent(instance, isSSR = false) {
7671 isInSSRComponentSetup = isSSR;
7672 const { props, children } = instance.vnode;
7673 const isStateful = isStatefulComponent(instance);
7674 initProps(instance, props, isStateful, isSSR);
7675 initSlots(instance, children);
7676 const setupResult = isStateful
7677 ? setupStatefulComponent(instance, isSSR)
7678 : undefined;
7679 isInSSRComponentSetup = false;
7680 return setupResult;
7681}
7682function setupStatefulComponent(instance, isSSR) {
7683 const Component = instance.type;
7684 {
7685 if (Component.name) {
7686 validateComponentName(Component.name, instance.appContext.config);
7687 }
7688 if (Component.components) {
7689 const names = Object.keys(Component.components);
7690 for (let i = 0; i < names.length; i++) {
7691 validateComponentName(names[i], instance.appContext.config);
7692 }
7693 }
7694 if (Component.directives) {
7695 const names = Object.keys(Component.directives);
7696 for (let i = 0; i < names.length; i++) {
7697 validateDirectiveName(names[i]);
7698 }
7699 }
7700 }
7701 // 0. create render proxy property access cache
7702 instance.accessCache = Object.create(null);
7703 // 1. create public instance / render proxy
7704 // also mark it raw so it's never observed
7705 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
7706 {
7707 exposePropsOnRenderContext(instance);
7708 }
7709 // 2. call setup()
7710 const { setup } = Component;
7711 if (setup) {
7712 const setupContext = (instance.setupContext =
7713 setup.length > 1 ? createSetupContext(instance) : null);
7714 currentInstance = instance;
7715 pauseTracking();
7716 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
7717 resetTracking();
7718 currentInstance = null;
7719 if (isPromise(setupResult)) {
7720 if (isSSR) {
7721 // return the promise so server-renderer can wait on it
7722 return setupResult
7723 .then((resolvedResult) => {
7724 handleSetupResult(instance, resolvedResult, isSSR);
7725 })
7726 .catch(e => {
7727 handleError(e, instance, 0 /* SETUP_FUNCTION */);
7728 });
7729 }
7730 else {
7731 // async setup returned Promise.
7732 // bail here and wait for re-entry.
7733 instance.asyncDep = setupResult;
7734 }
7735 }
7736 else {
7737 handleSetupResult(instance, setupResult, isSSR);
7738 }
7739 }
7740 else {
7741 finishComponentSetup(instance, isSSR);
7742 }
7743}
7744function handleSetupResult(instance, setupResult, isSSR) {
7745 if (isFunction(setupResult)) {
7746 // setup returned an inline render function
7747 {
7748 instance.render = setupResult;
7749 }
7750 }
7751 else if (isObject(setupResult)) {
7752 if (isVNode(setupResult)) {
7753 warn(`setup() should not return VNodes directly - ` +
7754 `return a render function instead.`);
7755 }
7756 // setup returned bindings.
7757 // assuming a render function compiled from template is present.
7758 {
7759 instance.devtoolsRawSetupState = setupResult;
7760 }
7761 instance.setupState = proxyRefs(setupResult);
7762 {
7763 exposeSetupStateOnRenderContext(instance);
7764 }
7765 }
7766 else if (setupResult !== undefined) {
7767 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
7768 }
7769 finishComponentSetup(instance, isSSR);
7770}
7771let compile;
7772// dev only
7773const isRuntimeOnly = () => !compile;
7774/**
7775 * For runtime-dom to register the compiler.
7776 * Note the exported method uses any to avoid d.ts relying on the compiler types.
7777 */
7778function registerRuntimeCompiler(_compile) {
7779 compile = _compile;
7780}
7781function finishComponentSetup(instance, isSSR) {
7782 const Component = instance.type;
7783 // template / render function normalization
7784 if (!instance.render) {
7785 // could be set from setup()
7786 if (compile && Component.template && !Component.render) {
7787 {
7788 startMeasure(instance, `compile`);
7789 }
7790 Component.render = compile(Component.template, {
7791 isCustomElement: instance.appContext.config.isCustomElement,
7792 delimiters: Component.delimiters
7793 });
7794 {
7795 endMeasure(instance, `compile`);
7796 }
7797 }
7798 instance.render = (Component.render || NOOP);
7799 // for runtime-compiled render functions using `with` blocks, the render
7800 // proxy used needs a different `has` handler which is more performant and
7801 // also only allows a whitelist of globals to fallthrough.
7802 if (instance.render._rc) {
7803 instance.withProxy = new Proxy(instance.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
7804 }
7805 }
7806 // support for 2.x options
7807 {
7808 currentInstance = instance;
7809 pauseTracking();
7810 applyOptions(instance, Component);
7811 resetTracking();
7812 currentInstance = null;
7813 }
7814 // warn missing template/render
7815 // the runtime compilation of template in SSR is done by server-render
7816 if (!Component.render && instance.render === NOOP && !isSSR) {
7817 /* istanbul ignore if */
7818 if (!compile && Component.template) {
7819 warn(`Component provided template option but ` +
7820 `runtime compilation is not supported in this build of Vue.` +
7821 (` Use "vue.esm-browser.js" instead.`
7822 ) /* should not happen */);
7823 }
7824 else {
7825 warn(`Component is missing template or render function.`);
7826 }
7827 }
7828}
7829const attrHandlers = {
7830 get: (target, key) => {
7831 {
7832 markAttrsAccessed();
7833 }
7834 return target[key];
7835 },
7836 set: () => {
7837 warn(`setupContext.attrs is readonly.`);
7838 return false;
7839 },
7840 deleteProperty: () => {
7841 warn(`setupContext.attrs is readonly.`);
7842 return false;
7843 }
7844};
7845function createSetupContext(instance) {
7846 const expose = exposed => {
7847 if (instance.exposed) {
7848 warn(`expose() should be called only once per setup().`);
7849 }
7850 instance.exposed = proxyRefs(exposed);
7851 };
7852 {
7853 // We use getters in dev in case libs like test-utils overwrite instance
7854 // properties (overwrites should not be done in prod)
7855 return Object.freeze({
7856 get attrs() {
7857 return new Proxy(instance.attrs, attrHandlers);
7858 },
7859 get slots() {
7860 return shallowReadonly(instance.slots);
7861 },
7862 get emit() {
7863 return (event, ...args) => instance.emit(event, ...args);
7864 },
7865 expose
7866 });
7867 }
7868}
7869// record effects created during a component's setup() so that they can be
7870// stopped when the component unmounts
7871function recordInstanceBoundEffect(effect, instance = currentInstance) {
7872 if (instance) {
7873 (instance.effects || (instance.effects = [])).push(effect);
7874 }
7875}
7876const classifyRE = /(?:^|[-_])(\w)/g;
7877const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
7878function getComponentName(Component) {
7879 return isFunction(Component)
7880 ? Component.displayName || Component.name
7881 : Component.name;
7882}
7883/* istanbul ignore next */
7884function formatComponentName(instance, Component, isRoot = false) {
7885 let name = getComponentName(Component);
7886 if (!name && Component.__file) {
7887 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
7888 if (match) {
7889 name = match[1];
7890 }
7891 }
7892 if (!name && instance && instance.parent) {
7893 // try to infer the name based on reverse resolution
7894 const inferFromRegistry = (registry) => {
7895 for (const key in registry) {
7896 if (registry[key] === Component) {
7897 return key;
7898 }
7899 }
7900 };
7901 name =
7902 inferFromRegistry(instance.components ||
7903 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
7904 }
7905 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
7906}
7907function isClassComponent(value) {
7908 return isFunction(value) && '__vccOpts' in value;
7909}
7910
7911function computed$1(getterOrOptions) {
7912 const c = computed(getterOrOptions);
7913 recordInstanceBoundEffect(c.effect);
7914 return c;
7915}
7916
7917// implementation
7918function defineProps() {
7919 {
7920 warn(`defineProps() is a compiler-hint helper that is only usable inside ` +
7921 `<script setup> of a single file component. Its arguments should be ` +
7922 `compiled away and passing it at runtime has no effect.`);
7923 }
7924 return null;
7925}
7926// implementation
7927function defineEmit() {
7928 {
7929 warn(`defineEmit() is a compiler-hint helper that is only usable inside ` +
7930 `<script setup> of a single file component. Its arguments should be ` +
7931 `compiled away and passing it at runtime has no effect.`);
7932 }
7933 return null;
7934}
7935function useContext() {
7936 const i = getCurrentInstance();
7937 if (!i) {
7938 warn(`useContext() called without active instance.`);
7939 }
7940 return i.setupContext || (i.setupContext = createSetupContext(i));
7941}
7942
7943// Actual implementation
7944function h(type, propsOrChildren, children) {
7945 const l = arguments.length;
7946 if (l === 2) {
7947 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
7948 // single vnode without props
7949 if (isVNode(propsOrChildren)) {
7950 return createVNode(type, null, [propsOrChildren]);
7951 }
7952 // props without children
7953 return createVNode(type, propsOrChildren);
7954 }
7955 else {
7956 // omit props
7957 return createVNode(type, null, propsOrChildren);
7958 }
7959 }
7960 else {
7961 if (l > 3) {
7962 children = Array.prototype.slice.call(arguments, 2);
7963 }
7964 else if (l === 3 && isVNode(children)) {
7965 children = [children];
7966 }
7967 return createVNode(type, propsOrChildren, children);
7968 }
7969}
7970
7971const ssrContextKey = Symbol(`ssrContext` );
7972const useSSRContext = () => {
7973 {
7974 const ctx = inject(ssrContextKey);
7975 if (!ctx) {
7976 warn(`Server rendering context not provided. Make sure to only call ` +
7977 `useSSRContext() conditionally in the server build.`);
7978 }
7979 return ctx;
7980 }
7981};
7982
7983function initCustomFormatter() {
7984 /* eslint-disable no-restricted-globals */
7985 if (typeof window === 'undefined') {
7986 return;
7987 }
7988 const vueStyle = { style: 'color:#3ba776' };
7989 const numberStyle = { style: 'color:#0b1bc9' };
7990 const stringStyle = { style: 'color:#b62e24' };
7991 const keywordStyle = { style: 'color:#9d288c' };
7992 // custom formatter for Chrome
7993 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
7994 const formatter = {
7995 header(obj) {
7996 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
7997 if (!isObject(obj)) {
7998 return null;
7999 }
8000 if (obj.__isVue) {
8001 return ['div', vueStyle, `VueInstance`];
8002 }
8003 else if (isRef(obj)) {
8004 return [
8005 'div',
8006 {},
8007 ['span', vueStyle, genRefFlag(obj)],
8008 '<',
8009 formatValue(obj.value),
8010 `>`
8011 ];
8012 }
8013 else if (isReactive(obj)) {
8014 return [
8015 'div',
8016 {},
8017 ['span', vueStyle, 'Reactive'],
8018 '<',
8019 formatValue(obj),
8020 `>${isReadonly(obj) ? ` (readonly)` : ``}`
8021 ];
8022 }
8023 else if (isReadonly(obj)) {
8024 return [
8025 'div',
8026 {},
8027 ['span', vueStyle, 'Readonly'],
8028 '<',
8029 formatValue(obj),
8030 '>'
8031 ];
8032 }
8033 return null;
8034 },
8035 hasBody(obj) {
8036 return obj && obj.__isVue;
8037 },
8038 body(obj) {
8039 if (obj && obj.__isVue) {
8040 return [
8041 'div',
8042 {},
8043 ...formatInstance(obj.$)
8044 ];
8045 }
8046 }
8047 };
8048 function formatInstance(instance) {
8049 const blocks = [];
8050 if (instance.type.props && instance.props) {
8051 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
8052 }
8053 if (instance.setupState !== EMPTY_OBJ) {
8054 blocks.push(createInstanceBlock('setup', instance.setupState));
8055 }
8056 if (instance.data !== EMPTY_OBJ) {
8057 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
8058 }
8059 const computed = extractKeys(instance, 'computed');
8060 if (computed) {
8061 blocks.push(createInstanceBlock('computed', computed));
8062 }
8063 const injected = extractKeys(instance, 'inject');
8064 if (injected) {
8065 blocks.push(createInstanceBlock('injected', injected));
8066 }
8067 blocks.push([
8068 'div',
8069 {},
8070 [
8071 'span',
8072 {
8073 style: keywordStyle.style + ';opacity:0.66'
8074 },
8075 '$ (internal): '
8076 ],
8077 ['object', { object: instance }]
8078 ]);
8079 return blocks;
8080 }
8081 function createInstanceBlock(type, target) {
8082 target = extend({}, target);
8083 if (!Object.keys(target).length) {
8084 return ['span', {}];
8085 }
8086 return [
8087 'div',
8088 { style: 'line-height:1.25em;margin-bottom:0.6em' },
8089 [
8090 'div',
8091 {
8092 style: 'color:#476582'
8093 },
8094 type
8095 ],
8096 [
8097 'div',
8098 {
8099 style: 'padding-left:1.25em'
8100 },
8101 ...Object.keys(target).map(key => {
8102 return [
8103 'div',
8104 {},
8105 ['span', keywordStyle, key + ': '],
8106 formatValue(target[key], false)
8107 ];
8108 })
8109 ]
8110 ];
8111 }
8112 function formatValue(v, asRaw = true) {
8113 if (typeof v === 'number') {
8114 return ['span', numberStyle, v];
8115 }
8116 else if (typeof v === 'string') {
8117 return ['span', stringStyle, JSON.stringify(v)];
8118 }
8119 else if (typeof v === 'boolean') {
8120 return ['span', keywordStyle, v];
8121 }
8122 else if (isObject(v)) {
8123 return ['object', { object: asRaw ? toRaw(v) : v }];
8124 }
8125 else {
8126 return ['span', stringStyle, String(v)];
8127 }
8128 }
8129 function extractKeys(instance, type) {
8130 const Comp = instance.type;
8131 if (isFunction(Comp)) {
8132 return;
8133 }
8134 const extracted = {};
8135 for (const key in instance.ctx) {
8136 if (isKeyOfType(Comp, key, type)) {
8137 extracted[key] = instance.ctx[key];
8138 }
8139 }
8140 return extracted;
8141 }
8142 function isKeyOfType(Comp, key, type) {
8143 const opts = Comp[type];
8144 if ((isArray(opts) && opts.includes(key)) ||
8145 (isObject(opts) && key in opts)) {
8146 return true;
8147 }
8148 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
8149 return true;
8150 }
8151 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
8152 return true;
8153 }
8154 }
8155 function genRefFlag(v) {
8156 if (v._shallow) {
8157 return `ShallowRef`;
8158 }
8159 if (v.effect) {
8160 return `ComputedRef`;
8161 }
8162 return `Ref`;
8163 }
8164 if (window.devtoolsFormatters) {
8165 window.devtoolsFormatters.push(formatter);
8166 }
8167 else {
8168 window.devtoolsFormatters = [formatter];
8169 }
8170}
8171
8172/**
8173 * Actual implementation
8174 */
8175function renderList(source, renderItem) {
8176 let ret;
8177 if (isArray(source) || isString(source)) {
8178 ret = new Array(source.length);
8179 for (let i = 0, l = source.length; i < l; i++) {
8180 ret[i] = renderItem(source[i], i);
8181 }
8182 }
8183 else if (typeof source === 'number') {
8184 if (!Number.isInteger(source)) {
8185 warn(`The v-for range expect an integer value but got ${source}.`);
8186 return [];
8187 }
8188 ret = new Array(source);
8189 for (let i = 0; i < source; i++) {
8190 ret[i] = renderItem(i + 1, i);
8191 }
8192 }
8193 else if (isObject(source)) {
8194 if (source[Symbol.iterator]) {
8195 ret = Array.from(source, renderItem);
8196 }
8197 else {
8198 const keys = Object.keys(source);
8199 ret = new Array(keys.length);
8200 for (let i = 0, l = keys.length; i < l; i++) {
8201 const key = keys[i];
8202 ret[i] = renderItem(source[key], key, i);
8203 }
8204 }
8205 }
8206 else {
8207 ret = [];
8208 }
8209 return ret;
8210}
8211
8212/**
8213 * For prefixing keys in v-on="obj" with "on"
8214 * @private
8215 */
8216function toHandlers(obj) {
8217 const ret = {};
8218 if (!isObject(obj)) {
8219 warn(`v-on with no argument expects an object value.`);
8220 return ret;
8221 }
8222 for (const key in obj) {
8223 ret[toHandlerKey(key)] = obj[key];
8224 }
8225 return ret;
8226}
8227
8228/**
8229 * Compiler runtime helper for creating dynamic slots object
8230 * @private
8231 */
8232function createSlots(slots, dynamicSlots) {
8233 for (let i = 0; i < dynamicSlots.length; i++) {
8234 const slot = dynamicSlots[i];
8235 // array of dynamic slot generated by <template v-for="..." #[...]>
8236 if (isArray(slot)) {
8237 for (let j = 0; j < slot.length; j++) {
8238 slots[slot[j].name] = slot[j].fn;
8239 }
8240 }
8241 else if (slot) {
8242 // conditional single slot generated by <template v-if="..." #foo>
8243 slots[slot.name] = slot.fn;
8244 }
8245 }
8246 return slots;
8247}
8248
8249// Core API ------------------------------------------------------------------
8250const version = "3.0.11";
8251/**
8252 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
8253 * @internal
8254 */
8255const ssrUtils = (null);
8256
8257const svgNS = 'http://www.w3.org/2000/svg';
8258const doc = (typeof document !== 'undefined' ? document : null);
8259let tempContainer;
8260let tempSVGContainer;
8261const nodeOps = {
8262 insert: (child, parent, anchor) => {
8263 parent.insertBefore(child, anchor || null);
8264 },
8265 remove: child => {
8266 const parent = child.parentNode;
8267 if (parent) {
8268 parent.removeChild(child);
8269 }
8270 },
8271 createElement: (tag, isSVG, is, props) => {
8272 const el = isSVG
8273 ? doc.createElementNS(svgNS, tag)
8274 : doc.createElement(tag, is ? { is } : undefined);
8275 if (tag === 'select' && props && props.multiple != null) {
8276 el.setAttribute('multiple', props.multiple);
8277 }
8278 return el;
8279 },
8280 createText: text => doc.createTextNode(text),
8281 createComment: text => doc.createComment(text),
8282 setText: (node, text) => {
8283 node.nodeValue = text;
8284 },
8285 setElementText: (el, text) => {
8286 el.textContent = text;
8287 },
8288 parentNode: node => node.parentNode,
8289 nextSibling: node => node.nextSibling,
8290 querySelector: selector => doc.querySelector(selector),
8291 setScopeId(el, id) {
8292 el.setAttribute(id, '');
8293 },
8294 cloneNode(el) {
8295 const cloned = el.cloneNode(true);
8296 // #3072
8297 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
8298 // - normally, elements using `:value` bindings will not be hoisted, but if
8299 // the bound value is a constant, e.g. `:value="true"` - they do get
8300 // hoisted.
8301 // - in production, hoisted nodes are cloned when subsequent inserts, but
8302 // cloneNode() does not copy the custom property we attached.
8303 // - This may need to account for other custom DOM properties we attach to
8304 // elements in addition to `_value` in the future.
8305 if (`_value` in el) {
8306 cloned._value = el._value;
8307 }
8308 return cloned;
8309 },
8310 // __UNSAFE__
8311 // Reason: innerHTML.
8312 // Static content here can only come from compiled templates.
8313 // As long as the user only uses trusted templates, this is safe.
8314 insertStaticContent(content, parent, anchor, isSVG) {
8315 const temp = isSVG
8316 ? tempSVGContainer ||
8317 (tempSVGContainer = doc.createElementNS(svgNS, 'svg'))
8318 : tempContainer || (tempContainer = doc.createElement('div'));
8319 temp.innerHTML = content;
8320 const first = temp.firstChild;
8321 let node = first;
8322 let last = node;
8323 while (node) {
8324 last = node;
8325 nodeOps.insert(node, parent, anchor);
8326 node = temp.firstChild;
8327 }
8328 return [first, last];
8329 }
8330};
8331
8332// compiler should normalize class + :class bindings on the same element
8333// into a single binding ['staticClass', dynamic]
8334function patchClass(el, value, isSVG) {
8335 if (value == null) {
8336 value = '';
8337 }
8338 if (isSVG) {
8339 el.setAttribute('class', value);
8340 }
8341 else {
8342 // directly setting className should be faster than setAttribute in theory
8343 // if this is an element during a transition, take the temporary transition
8344 // classes into account.
8345 const transitionClasses = el._vtc;
8346 if (transitionClasses) {
8347 value = (value
8348 ? [value, ...transitionClasses]
8349 : [...transitionClasses]).join(' ');
8350 }
8351 el.className = value;
8352 }
8353}
8354
8355function patchStyle(el, prev, next) {
8356 const style = el.style;
8357 if (!next) {
8358 el.removeAttribute('style');
8359 }
8360 else if (isString(next)) {
8361 if (prev !== next) {
8362 const current = style.display;
8363 style.cssText = next;
8364 // indicates that the `display` of the element is controlled by `v-show`,
8365 // so we always keep the current `display` value regardless of the `style` value,
8366 // thus handing over control to `v-show`.
8367 if ('_vod' in el) {
8368 style.display = current;
8369 }
8370 }
8371 }
8372 else {
8373 for (const key in next) {
8374 setStyle(style, key, next[key]);
8375 }
8376 if (prev && !isString(prev)) {
8377 for (const key in prev) {
8378 if (next[key] == null) {
8379 setStyle(style, key, '');
8380 }
8381 }
8382 }
8383 }
8384}
8385const importantRE = /\s*!important$/;
8386function setStyle(style, name, val) {
8387 if (isArray(val)) {
8388 val.forEach(v => setStyle(style, name, v));
8389 }
8390 else {
8391 if (name.startsWith('--')) {
8392 // custom property definition
8393 style.setProperty(name, val);
8394 }
8395 else {
8396 const prefixed = autoPrefix(style, name);
8397 if (importantRE.test(val)) {
8398 // !important
8399 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
8400 }
8401 else {
8402 style[prefixed] = val;
8403 }
8404 }
8405 }
8406}
8407const prefixes = ['Webkit', 'Moz', 'ms'];
8408const prefixCache = {};
8409function autoPrefix(style, rawName) {
8410 const cached = prefixCache[rawName];
8411 if (cached) {
8412 return cached;
8413 }
8414 let name = camelize(rawName);
8415 if (name !== 'filter' && name in style) {
8416 return (prefixCache[rawName] = name);
8417 }
8418 name = capitalize(name);
8419 for (let i = 0; i < prefixes.length; i++) {
8420 const prefixed = prefixes[i] + name;
8421 if (prefixed in style) {
8422 return (prefixCache[rawName] = prefixed);
8423 }
8424 }
8425 return rawName;
8426}
8427
8428const xlinkNS = 'http://www.w3.org/1999/xlink';
8429function patchAttr(el, key, value, isSVG) {
8430 if (isSVG && key.startsWith('xlink:')) {
8431 if (value == null) {
8432 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
8433 }
8434 else {
8435 el.setAttributeNS(xlinkNS, key, value);
8436 }
8437 }
8438 else {
8439 // note we are only checking boolean attributes that don't have a
8440 // corresponding dom prop of the same name here.
8441 const isBoolean = isSpecialBooleanAttr(key);
8442 if (value == null || (isBoolean && value === false)) {
8443 el.removeAttribute(key);
8444 }
8445 else {
8446 el.setAttribute(key, isBoolean ? '' : value);
8447 }
8448 }
8449}
8450
8451// __UNSAFE__
8452// functions. The user is responsible for using them with only trusted content.
8453function patchDOMProp(el, key, value,
8454// the following args are passed only due to potential innerHTML/textContent
8455// overriding existing VNodes, in which case the old tree must be properly
8456// unmounted.
8457prevChildren, parentComponent, parentSuspense, unmountChildren) {
8458 if (key === 'innerHTML' || key === 'textContent') {
8459 if (prevChildren) {
8460 unmountChildren(prevChildren, parentComponent, parentSuspense);
8461 }
8462 el[key] = value == null ? '' : value;
8463 return;
8464 }
8465 if (key === 'value' && el.tagName !== 'PROGRESS') {
8466 // store value as _value as well since
8467 // non-string values will be stringified.
8468 el._value = value;
8469 const newValue = value == null ? '' : value;
8470 if (el.value !== newValue) {
8471 el.value = newValue;
8472 }
8473 return;
8474 }
8475 if (value === '' || value == null) {
8476 const type = typeof el[key];
8477 if (value === '' && type === 'boolean') {
8478 // e.g. <select multiple> compiles to { multiple: '' }
8479 el[key] = true;
8480 return;
8481 }
8482 else if (value == null && type === 'string') {
8483 // e.g. <div :id="null">
8484 el[key] = '';
8485 el.removeAttribute(key);
8486 return;
8487 }
8488 else if (type === 'number') {
8489 // e.g. <img :width="null">
8490 el[key] = 0;
8491 el.removeAttribute(key);
8492 return;
8493 }
8494 }
8495 // some properties perform value validation and throw
8496 try {
8497 el[key] = value;
8498 }
8499 catch (e) {
8500 {
8501 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
8502 `value ${value} is invalid.`, e);
8503 }
8504 }
8505}
8506
8507// Async edge case fix requires storing an event listener's attach timestamp.
8508let _getNow = Date.now;
8509let skipTimestampCheck = false;
8510if (typeof window !== 'undefined') {
8511 // Determine what event timestamp the browser is using. Annoyingly, the
8512 // timestamp can either be hi-res (relative to page load) or low-res
8513 // (relative to UNIX epoch), so in order to compare time we have to use the
8514 // same timestamp type when saving the flush timestamp.
8515 if (_getNow() > document.createEvent('Event').timeStamp) {
8516 // if the low-res timestamp which is bigger than the event timestamp
8517 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
8518 // and we need to use the hi-res version for event listeners as well.
8519 _getNow = () => performance.now();
8520 }
8521 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
8522 // and does not fire microtasks in between event propagation, so safe to exclude.
8523 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
8524 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
8525}
8526// To avoid the overhead of repeatedly calling performance.now(), we cache
8527// and use the same timestamp for all event listeners attached in the same tick.
8528let cachedNow = 0;
8529const p = Promise.resolve();
8530const reset = () => {
8531 cachedNow = 0;
8532};
8533const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
8534function addEventListener(el, event, handler, options) {
8535 el.addEventListener(event, handler, options);
8536}
8537function removeEventListener(el, event, handler, options) {
8538 el.removeEventListener(event, handler, options);
8539}
8540function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
8541 // vei = vue event invokers
8542 const invokers = el._vei || (el._vei = {});
8543 const existingInvoker = invokers[rawName];
8544 if (nextValue && existingInvoker) {
8545 // patch
8546 existingInvoker.value = nextValue;
8547 }
8548 else {
8549 const [name, options] = parseName(rawName);
8550 if (nextValue) {
8551 // add
8552 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
8553 addEventListener(el, name, invoker, options);
8554 }
8555 else if (existingInvoker) {
8556 // remove
8557 removeEventListener(el, name, existingInvoker, options);
8558 invokers[rawName] = undefined;
8559 }
8560 }
8561}
8562const optionsModifierRE = /(?:Once|Passive|Capture)$/;
8563function parseName(name) {
8564 let options;
8565 if (optionsModifierRE.test(name)) {
8566 options = {};
8567 let m;
8568 while ((m = name.match(optionsModifierRE))) {
8569 name = name.slice(0, name.length - m[0].length);
8570 options[m[0].toLowerCase()] = true;
8571 }
8572 }
8573 return [hyphenate(name.slice(2)), options];
8574}
8575function createInvoker(initialValue, instance) {
8576 const invoker = (e) => {
8577 // async edge case #6566: inner click event triggers patch, event handler
8578 // attached to outer element during patch, and triggered again. This
8579 // happens because browsers fire microtask ticks between event propagation.
8580 // the solution is simple: we save the timestamp when a handler is attached,
8581 // and the handler would only fire if the event passed to it was fired
8582 // AFTER it was attached.
8583 const timeStamp = e.timeStamp || _getNow();
8584 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
8585 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
8586 }
8587 };
8588 invoker.value = initialValue;
8589 invoker.attached = getNow();
8590 return invoker;
8591}
8592function patchStopImmediatePropagation(e, value) {
8593 if (isArray(value)) {
8594 const originalStop = e.stopImmediatePropagation;
8595 e.stopImmediatePropagation = () => {
8596 originalStop.call(e);
8597 e._stopped = true;
8598 };
8599 return value.map(fn => (e) => !e._stopped && fn(e));
8600 }
8601 else {
8602 return value;
8603 }
8604}
8605
8606const nativeOnRE = /^on[a-z]/;
8607const forcePatchProp = (_, key) => key === 'value';
8608const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
8609 switch (key) {
8610 // special
8611 case 'class':
8612 patchClass(el, nextValue, isSVG);
8613 break;
8614 case 'style':
8615 patchStyle(el, prevValue, nextValue);
8616 break;
8617 default:
8618 if (isOn(key)) {
8619 // ignore v-model listeners
8620 if (!isModelListener(key)) {
8621 patchEvent(el, key, prevValue, nextValue, parentComponent);
8622 }
8623 }
8624 else if (shouldSetAsProp(el, key, nextValue, isSVG)) {
8625 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
8626 }
8627 else {
8628 // special case for <input v-model type="checkbox"> with
8629 // :true-value & :false-value
8630 // store value as dom properties since non-string values will be
8631 // stringified.
8632 if (key === 'true-value') {
8633 el._trueValue = nextValue;
8634 }
8635 else if (key === 'false-value') {
8636 el._falseValue = nextValue;
8637 }
8638 patchAttr(el, key, nextValue, isSVG);
8639 }
8640 break;
8641 }
8642};
8643function shouldSetAsProp(el, key, value, isSVG) {
8644 if (isSVG) {
8645 // most keys must be set as attribute on svg elements to work
8646 // ...except innerHTML
8647 if (key === 'innerHTML') {
8648 return true;
8649 }
8650 // or native onclick with function values
8651 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
8652 return true;
8653 }
8654 return false;
8655 }
8656 // spellcheck and draggable are numerated attrs, however their
8657 // corresponding DOM properties are actually booleans - this leads to
8658 // setting it with a string "false" value leading it to be coerced to
8659 // `true`, so we need to always treat them as attributes.
8660 // Note that `contentEditable` doesn't have this problem: its DOM
8661 // property is also enumerated string values.
8662 if (key === 'spellcheck' || key === 'draggable') {
8663 return false;
8664 }
8665 // #1787, #2840 form property on form elements is readonly and must be set as
8666 // attribute.
8667 if (key === 'form') {
8668 return false;
8669 }
8670 // #1526 <input list> must be set as attribute
8671 if (key === 'list' && el.tagName === 'INPUT') {
8672 return false;
8673 }
8674 // #2766 <textarea type> must be set as attribute
8675 if (key === 'type' && el.tagName === 'TEXTAREA') {
8676 return false;
8677 }
8678 // native onclick with string value, must be set as attribute
8679 if (nativeOnRE.test(key) && isString(value)) {
8680 return false;
8681 }
8682 return key in el;
8683}
8684
8685function useCssModule(name = '$style') {
8686 /* istanbul ignore else */
8687 {
8688 const instance = getCurrentInstance();
8689 if (!instance) {
8690 warn(`useCssModule must be called inside setup()`);
8691 return EMPTY_OBJ;
8692 }
8693 const modules = instance.type.__cssModules;
8694 if (!modules) {
8695 warn(`Current instance does not have CSS modules injected.`);
8696 return EMPTY_OBJ;
8697 }
8698 const mod = modules[name];
8699 if (!mod) {
8700 warn(`Current instance does not have CSS module named "${name}".`);
8701 return EMPTY_OBJ;
8702 }
8703 return mod;
8704 }
8705}
8706
8707/**
8708 * Runtime helper for SFC's CSS variable injection feature.
8709 * @private
8710 */
8711function useCssVars(getter) {
8712 const instance = getCurrentInstance();
8713 /* istanbul ignore next */
8714 if (!instance) {
8715 warn(`useCssVars is called without current active component instance.`);
8716 return;
8717 }
8718 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
8719 onMounted(() => watchEffect(setVars, { flush: 'post' }));
8720 onUpdated(setVars);
8721}
8722function setVarsOnVNode(vnode, vars) {
8723 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
8724 const suspense = vnode.suspense;
8725 vnode = suspense.activeBranch;
8726 if (suspense.pendingBranch && !suspense.isHydrating) {
8727 suspense.effects.push(() => {
8728 setVarsOnVNode(suspense.activeBranch, vars);
8729 });
8730 }
8731 }
8732 // drill down HOCs until it's a non-component vnode
8733 while (vnode.component) {
8734 vnode = vnode.component.subTree;
8735 }
8736 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
8737 const style = vnode.el.style;
8738 for (const key in vars) {
8739 style.setProperty(`--${key}`, vars[key]);
8740 }
8741 }
8742 else if (vnode.type === Fragment) {
8743 vnode.children.forEach(c => setVarsOnVNode(c, vars));
8744 }
8745}
8746
8747const TRANSITION = 'transition';
8748const ANIMATION = 'animation';
8749// DOM Transition is a higher-order-component based on the platform-agnostic
8750// base Transition component, with DOM-specific logic.
8751const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
8752Transition.displayName = 'Transition';
8753const DOMTransitionPropsValidators = {
8754 name: String,
8755 type: String,
8756 css: {
8757 type: Boolean,
8758 default: true
8759 },
8760 duration: [String, Number, Object],
8761 enterFromClass: String,
8762 enterActiveClass: String,
8763 enterToClass: String,
8764 appearFromClass: String,
8765 appearActiveClass: String,
8766 appearToClass: String,
8767 leaveFromClass: String,
8768 leaveActiveClass: String,
8769 leaveToClass: String
8770};
8771const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
8772function resolveTransitionProps(rawProps) {
8773 let { name = 'v', type, css = true, 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;
8774 const baseProps = {};
8775 for (const key in rawProps) {
8776 if (!(key in DOMTransitionPropsValidators)) {
8777 baseProps[key] = rawProps[key];
8778 }
8779 }
8780 if (!css) {
8781 return baseProps;
8782 }
8783 const durations = normalizeDuration(duration);
8784 const enterDuration = durations && durations[0];
8785 const leaveDuration = durations && durations[1];
8786 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
8787 const finishEnter = (el, isAppear, done) => {
8788 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
8789 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
8790 done && done();
8791 };
8792 const finishLeave = (el, done) => {
8793 removeTransitionClass(el, leaveToClass);
8794 removeTransitionClass(el, leaveActiveClass);
8795 done && done();
8796 };
8797 const makeEnterHook = (isAppear) => {
8798 return (el, done) => {
8799 const hook = isAppear ? onAppear : onEnter;
8800 const resolve = () => finishEnter(el, isAppear, done);
8801 hook && hook(el, resolve);
8802 nextFrame(() => {
8803 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
8804 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
8805 if (!(hook && hook.length > 1)) {
8806 whenTransitionEnds(el, type, enterDuration, resolve);
8807 }
8808 });
8809 };
8810 };
8811 return extend(baseProps, {
8812 onBeforeEnter(el) {
8813 onBeforeEnter && onBeforeEnter(el);
8814 addTransitionClass(el, enterFromClass);
8815 addTransitionClass(el, enterActiveClass);
8816 },
8817 onBeforeAppear(el) {
8818 onBeforeAppear && onBeforeAppear(el);
8819 addTransitionClass(el, appearFromClass);
8820 addTransitionClass(el, appearActiveClass);
8821 },
8822 onEnter: makeEnterHook(false),
8823 onAppear: makeEnterHook(true),
8824 onLeave(el, done) {
8825 const resolve = () => finishLeave(el, done);
8826 addTransitionClass(el, leaveFromClass);
8827 // force reflow so *-leave-from classes immediately take effect (#2593)
8828 forceReflow();
8829 addTransitionClass(el, leaveActiveClass);
8830 nextFrame(() => {
8831 removeTransitionClass(el, leaveFromClass);
8832 addTransitionClass(el, leaveToClass);
8833 if (!(onLeave && onLeave.length > 1)) {
8834 whenTransitionEnds(el, type, leaveDuration, resolve);
8835 }
8836 });
8837 onLeave && onLeave(el, resolve);
8838 },
8839 onEnterCancelled(el) {
8840 finishEnter(el, false);
8841 onEnterCancelled && onEnterCancelled(el);
8842 },
8843 onAppearCancelled(el) {
8844 finishEnter(el, true);
8845 onAppearCancelled && onAppearCancelled(el);
8846 },
8847 onLeaveCancelled(el) {
8848 finishLeave(el);
8849 onLeaveCancelled && onLeaveCancelled(el);
8850 }
8851 });
8852}
8853function normalizeDuration(duration) {
8854 if (duration == null) {
8855 return null;
8856 }
8857 else if (isObject(duration)) {
8858 return [NumberOf(duration.enter), NumberOf(duration.leave)];
8859 }
8860 else {
8861 const n = NumberOf(duration);
8862 return [n, n];
8863 }
8864}
8865function NumberOf(val) {
8866 const res = toNumber(val);
8867 validateDuration(res);
8868 return res;
8869}
8870function validateDuration(val) {
8871 if (typeof val !== 'number') {
8872 warn(`<transition> explicit duration is not a valid number - ` +
8873 `got ${JSON.stringify(val)}.`);
8874 }
8875 else if (isNaN(val)) {
8876 warn(`<transition> explicit duration is NaN - ` +
8877 'the duration expression might be incorrect.');
8878 }
8879}
8880function addTransitionClass(el, cls) {
8881 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
8882 (el._vtc ||
8883 (el._vtc = new Set())).add(cls);
8884}
8885function removeTransitionClass(el, cls) {
8886 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
8887 const { _vtc } = el;
8888 if (_vtc) {
8889 _vtc.delete(cls);
8890 if (!_vtc.size) {
8891 el._vtc = undefined;
8892 }
8893 }
8894}
8895function nextFrame(cb) {
8896 requestAnimationFrame(() => {
8897 requestAnimationFrame(cb);
8898 });
8899}
8900let endId = 0;
8901function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
8902 const id = (el._endId = ++endId);
8903 const resolveIfNotStale = () => {
8904 if (id === el._endId) {
8905 resolve();
8906 }
8907 };
8908 if (explicitTimeout) {
8909 return setTimeout(resolveIfNotStale, explicitTimeout);
8910 }
8911 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
8912 if (!type) {
8913 return resolve();
8914 }
8915 const endEvent = type + 'end';
8916 let ended = 0;
8917 const end = () => {
8918 el.removeEventListener(endEvent, onEnd);
8919 resolveIfNotStale();
8920 };
8921 const onEnd = (e) => {
8922 if (e.target === el && ++ended >= propCount) {
8923 end();
8924 }
8925 };
8926 setTimeout(() => {
8927 if (ended < propCount) {
8928 end();
8929 }
8930 }, timeout + 1);
8931 el.addEventListener(endEvent, onEnd);
8932}
8933function getTransitionInfo(el, expectedType) {
8934 const styles = window.getComputedStyle(el);
8935 // JSDOM may return undefined for transition properties
8936 const getStyleProperties = (key) => (styles[key] || '').split(', ');
8937 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
8938 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
8939 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
8940 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
8941 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
8942 const animationTimeout = getTimeout(animationDelays, animationDurations);
8943 let type = null;
8944 let timeout = 0;
8945 let propCount = 0;
8946 /* istanbul ignore if */
8947 if (expectedType === TRANSITION) {
8948 if (transitionTimeout > 0) {
8949 type = TRANSITION;
8950 timeout = transitionTimeout;
8951 propCount = transitionDurations.length;
8952 }
8953 }
8954 else if (expectedType === ANIMATION) {
8955 if (animationTimeout > 0) {
8956 type = ANIMATION;
8957 timeout = animationTimeout;
8958 propCount = animationDurations.length;
8959 }
8960 }
8961 else {
8962 timeout = Math.max(transitionTimeout, animationTimeout);
8963 type =
8964 timeout > 0
8965 ? transitionTimeout > animationTimeout
8966 ? TRANSITION
8967 : ANIMATION
8968 : null;
8969 propCount = type
8970 ? type === TRANSITION
8971 ? transitionDurations.length
8972 : animationDurations.length
8973 : 0;
8974 }
8975 const hasTransform = type === TRANSITION &&
8976 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
8977 return {
8978 type,
8979 timeout,
8980 propCount,
8981 hasTransform
8982 };
8983}
8984function getTimeout(delays, durations) {
8985 while (delays.length < durations.length) {
8986 delays = delays.concat(delays);
8987 }
8988 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
8989}
8990// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
8991// numbers in a locale-dependent way, using a comma instead of a dot.
8992// If comma is not replaced with a dot, the input will be rounded down
8993// (i.e. acting as a floor function) causing unexpected behaviors
8994function toMs(s) {
8995 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
8996}
8997// synchronously force layout to put elements into a certain state
8998function forceReflow() {
8999 return document.body.offsetHeight;
9000}
9001
9002const positionMap = new WeakMap();
9003const newPositionMap = new WeakMap();
9004const TransitionGroupImpl = {
9005 name: 'TransitionGroup',
9006 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
9007 tag: String,
9008 moveClass: String
9009 }),
9010 setup(props, { slots }) {
9011 const instance = getCurrentInstance();
9012 const state = useTransitionState();
9013 let prevChildren;
9014 let children;
9015 onUpdated(() => {
9016 // children is guaranteed to exist after initial render
9017 if (!prevChildren.length) {
9018 return;
9019 }
9020 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
9021 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
9022 return;
9023 }
9024 // we divide the work into three loops to avoid mixing DOM reads and writes
9025 // in each iteration - which helps prevent layout thrashing.
9026 prevChildren.forEach(callPendingCbs);
9027 prevChildren.forEach(recordPosition);
9028 const movedChildren = prevChildren.filter(applyTranslation);
9029 // force reflow to put everything in position
9030 forceReflow();
9031 movedChildren.forEach(c => {
9032 const el = c.el;
9033 const style = el.style;
9034 addTransitionClass(el, moveClass);
9035 style.transform = style.webkitTransform = style.transitionDuration = '';
9036 const cb = (el._moveCb = (e) => {
9037 if (e && e.target !== el) {
9038 return;
9039 }
9040 if (!e || /transform$/.test(e.propertyName)) {
9041 el.removeEventListener('transitionend', cb);
9042 el._moveCb = null;
9043 removeTransitionClass(el, moveClass);
9044 }
9045 });
9046 el.addEventListener('transitionend', cb);
9047 });
9048 });
9049 return () => {
9050 const rawProps = toRaw(props);
9051 const cssTransitionProps = resolveTransitionProps(rawProps);
9052 const tag = rawProps.tag || Fragment;
9053 prevChildren = children;
9054 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
9055 for (let i = 0; i < children.length; i++) {
9056 const child = children[i];
9057 if (child.key != null) {
9058 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
9059 }
9060 else {
9061 warn(`<TransitionGroup> children must be keyed.`);
9062 }
9063 }
9064 if (prevChildren) {
9065 for (let i = 0; i < prevChildren.length; i++) {
9066 const child = prevChildren[i];
9067 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
9068 positionMap.set(child, child.el.getBoundingClientRect());
9069 }
9070 }
9071 return createVNode(tag, null, children);
9072 };
9073 }
9074};
9075const TransitionGroup = TransitionGroupImpl;
9076function callPendingCbs(c) {
9077 const el = c.el;
9078 if (el._moveCb) {
9079 el._moveCb();
9080 }
9081 if (el._enterCb) {
9082 el._enterCb();
9083 }
9084}
9085function recordPosition(c) {
9086 newPositionMap.set(c, c.el.getBoundingClientRect());
9087}
9088function applyTranslation(c) {
9089 const oldPos = positionMap.get(c);
9090 const newPos = newPositionMap.get(c);
9091 const dx = oldPos.left - newPos.left;
9092 const dy = oldPos.top - newPos.top;
9093 if (dx || dy) {
9094 const s = c.el.style;
9095 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
9096 s.transitionDuration = '0s';
9097 return c;
9098 }
9099}
9100function hasCSSTransform(el, root, moveClass) {
9101 // Detect whether an element with the move class applied has
9102 // CSS transitions. Since the element may be inside an entering
9103 // transition at this very moment, we make a clone of it and remove
9104 // all other transition classes applied to ensure only the move class
9105 // is applied.
9106 const clone = el.cloneNode();
9107 if (el._vtc) {
9108 el._vtc.forEach(cls => {
9109 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
9110 });
9111 }
9112 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
9113 clone.style.display = 'none';
9114 const container = (root.nodeType === 1
9115 ? root
9116 : root.parentNode);
9117 container.appendChild(clone);
9118 const { hasTransform } = getTransitionInfo(clone);
9119 container.removeChild(clone);
9120 return hasTransform;
9121}
9122
9123const getModelAssigner = (vnode) => {
9124 const fn = vnode.props['onUpdate:modelValue'];
9125 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
9126};
9127function onCompositionStart(e) {
9128 e.target.composing = true;
9129}
9130function onCompositionEnd(e) {
9131 const target = e.target;
9132 if (target.composing) {
9133 target.composing = false;
9134 trigger$1(target, 'input');
9135 }
9136}
9137function trigger$1(el, type) {
9138 const e = document.createEvent('HTMLEvents');
9139 e.initEvent(type, true, true);
9140 el.dispatchEvent(e);
9141}
9142// We are exporting the v-model runtime directly as vnode hooks so that it can
9143// be tree-shaken in case v-model is never used.
9144const vModelText = {
9145 created(el, { modifiers: { lazy, trim, number } }, vnode) {
9146 el._assign = getModelAssigner(vnode);
9147 const castToNumber = number || el.type === 'number';
9148 addEventListener(el, lazy ? 'change' : 'input', e => {
9149 if (e.target.composing)
9150 return;
9151 let domValue = el.value;
9152 if (trim) {
9153 domValue = domValue.trim();
9154 }
9155 else if (castToNumber) {
9156 domValue = toNumber(domValue);
9157 }
9158 el._assign(domValue);
9159 });
9160 if (trim) {
9161 addEventListener(el, 'change', () => {
9162 el.value = el.value.trim();
9163 });
9164 }
9165 if (!lazy) {
9166 addEventListener(el, 'compositionstart', onCompositionStart);
9167 addEventListener(el, 'compositionend', onCompositionEnd);
9168 // Safari < 10.2 & UIWebView doesn't fire compositionend when
9169 // switching focus before confirming composition choice
9170 // this also fixes the issue where some browsers e.g. iOS Chrome
9171 // fires "change" instead of "input" on autocomplete.
9172 addEventListener(el, 'change', onCompositionEnd);
9173 }
9174 },
9175 // set value on mounted so it's after min/max for type="range"
9176 mounted(el, { value }) {
9177 el.value = value == null ? '' : value;
9178 },
9179 beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
9180 el._assign = getModelAssigner(vnode);
9181 // avoid clearing unresolved text. #2302
9182 if (el.composing)
9183 return;
9184 if (document.activeElement === el) {
9185 if (trim && el.value.trim() === value) {
9186 return;
9187 }
9188 if ((number || el.type === 'number') && toNumber(el.value) === value) {
9189 return;
9190 }
9191 }
9192 const newValue = value == null ? '' : value;
9193 if (el.value !== newValue) {
9194 el.value = newValue;
9195 }
9196 }
9197};
9198const vModelCheckbox = {
9199 created(el, _, vnode) {
9200 el._assign = getModelAssigner(vnode);
9201 addEventListener(el, 'change', () => {
9202 const modelValue = el._modelValue;
9203 const elementValue = getValue(el);
9204 const checked = el.checked;
9205 const assign = el._assign;
9206 if (isArray(modelValue)) {
9207 const index = looseIndexOf(modelValue, elementValue);
9208 const found = index !== -1;
9209 if (checked && !found) {
9210 assign(modelValue.concat(elementValue));
9211 }
9212 else if (!checked && found) {
9213 const filtered = [...modelValue];
9214 filtered.splice(index, 1);
9215 assign(filtered);
9216 }
9217 }
9218 else if (isSet(modelValue)) {
9219 const cloned = new Set(modelValue);
9220 if (checked) {
9221 cloned.add(elementValue);
9222 }
9223 else {
9224 cloned.delete(elementValue);
9225 }
9226 assign(cloned);
9227 }
9228 else {
9229 assign(getCheckboxValue(el, checked));
9230 }
9231 });
9232 },
9233 // set initial checked on mount to wait for true-value/false-value
9234 mounted: setChecked,
9235 beforeUpdate(el, binding, vnode) {
9236 el._assign = getModelAssigner(vnode);
9237 setChecked(el, binding, vnode);
9238 }
9239};
9240function setChecked(el, { value, oldValue }, vnode) {
9241 el._modelValue = value;
9242 if (isArray(value)) {
9243 el.checked = looseIndexOf(value, vnode.props.value) > -1;
9244 }
9245 else if (isSet(value)) {
9246 el.checked = value.has(vnode.props.value);
9247 }
9248 else if (value !== oldValue) {
9249 el.checked = looseEqual(value, getCheckboxValue(el, true));
9250 }
9251}
9252const vModelRadio = {
9253 created(el, { value }, vnode) {
9254 el.checked = looseEqual(value, vnode.props.value);
9255 el._assign = getModelAssigner(vnode);
9256 addEventListener(el, 'change', () => {
9257 el._assign(getValue(el));
9258 });
9259 },
9260 beforeUpdate(el, { value, oldValue }, vnode) {
9261 el._assign = getModelAssigner(vnode);
9262 if (value !== oldValue) {
9263 el.checked = looseEqual(value, vnode.props.value);
9264 }
9265 }
9266};
9267const vModelSelect = {
9268 created(el, { value, modifiers: { number } }, vnode) {
9269 const isSetModel = isSet(value);
9270 addEventListener(el, 'change', () => {
9271 const selectedVal = Array.prototype.filter
9272 .call(el.options, (o) => o.selected)
9273 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
9274 el._assign(el.multiple
9275 ? isSetModel
9276 ? new Set(selectedVal)
9277 : selectedVal
9278 : selectedVal[0]);
9279 });
9280 el._assign = getModelAssigner(vnode);
9281 },
9282 // set value in mounted & updated because <select> relies on its children
9283 // <option>s.
9284 mounted(el, { value }) {
9285 setSelected(el, value);
9286 },
9287 beforeUpdate(el, _binding, vnode) {
9288 el._assign = getModelAssigner(vnode);
9289 },
9290 updated(el, { value }) {
9291 setSelected(el, value);
9292 }
9293};
9294function setSelected(el, value) {
9295 const isMultiple = el.multiple;
9296 if (isMultiple && !isArray(value) && !isSet(value)) {
9297 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
9298 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
9299 return;
9300 }
9301 for (let i = 0, l = el.options.length; i < l; i++) {
9302 const option = el.options[i];
9303 const optionValue = getValue(option);
9304 if (isMultiple) {
9305 if (isArray(value)) {
9306 option.selected = looseIndexOf(value, optionValue) > -1;
9307 }
9308 else {
9309 option.selected = value.has(optionValue);
9310 }
9311 }
9312 else {
9313 if (looseEqual(getValue(option), value)) {
9314 el.selectedIndex = i;
9315 return;
9316 }
9317 }
9318 }
9319 if (!isMultiple) {
9320 el.selectedIndex = -1;
9321 }
9322}
9323// retrieve raw value set via :value bindings
9324function getValue(el) {
9325 return '_value' in el ? el._value : el.value;
9326}
9327// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
9328function getCheckboxValue(el, checked) {
9329 const key = checked ? '_trueValue' : '_falseValue';
9330 return key in el ? el[key] : checked;
9331}
9332const vModelDynamic = {
9333 created(el, binding, vnode) {
9334 callModelHook(el, binding, vnode, null, 'created');
9335 },
9336 mounted(el, binding, vnode) {
9337 callModelHook(el, binding, vnode, null, 'mounted');
9338 },
9339 beforeUpdate(el, binding, vnode, prevVNode) {
9340 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
9341 },
9342 updated(el, binding, vnode, prevVNode) {
9343 callModelHook(el, binding, vnode, prevVNode, 'updated');
9344 }
9345};
9346function callModelHook(el, binding, vnode, prevVNode, hook) {
9347 let modelToUse;
9348 switch (el.tagName) {
9349 case 'SELECT':
9350 modelToUse = vModelSelect;
9351 break;
9352 case 'TEXTAREA':
9353 modelToUse = vModelText;
9354 break;
9355 default:
9356 switch (vnode.props && vnode.props.type) {
9357 case 'checkbox':
9358 modelToUse = vModelCheckbox;
9359 break;
9360 case 'radio':
9361 modelToUse = vModelRadio;
9362 break;
9363 default:
9364 modelToUse = vModelText;
9365 }
9366 }
9367 const fn = modelToUse[hook];
9368 fn && fn(el, binding, vnode, prevVNode);
9369}
9370
9371const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
9372const modifierGuards = {
9373 stop: e => e.stopPropagation(),
9374 prevent: e => e.preventDefault(),
9375 self: e => e.target !== e.currentTarget,
9376 ctrl: e => !e.ctrlKey,
9377 shift: e => !e.shiftKey,
9378 alt: e => !e.altKey,
9379 meta: e => !e.metaKey,
9380 left: e => 'button' in e && e.button !== 0,
9381 middle: e => 'button' in e && e.button !== 1,
9382 right: e => 'button' in e && e.button !== 2,
9383 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
9384};
9385/**
9386 * @private
9387 */
9388const withModifiers = (fn, modifiers) => {
9389 return (event, ...args) => {
9390 for (let i = 0; i < modifiers.length; i++) {
9391 const guard = modifierGuards[modifiers[i]];
9392 if (guard && guard(event, modifiers))
9393 return;
9394 }
9395 return fn(event, ...args);
9396 };
9397};
9398// Kept for 2.x compat.
9399// Note: IE11 compat for `spacebar` and `del` is removed for now.
9400const keyNames = {
9401 esc: 'escape',
9402 space: ' ',
9403 up: 'arrow-up',
9404 left: 'arrow-left',
9405 right: 'arrow-right',
9406 down: 'arrow-down',
9407 delete: 'backspace'
9408};
9409/**
9410 * @private
9411 */
9412const withKeys = (fn, modifiers) => {
9413 return (event) => {
9414 if (!('key' in event))
9415 return;
9416 const eventKey = hyphenate(event.key);
9417 if (
9418 // None of the provided key modifiers match the current event key
9419 !modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
9420 return;
9421 }
9422 return fn(event);
9423 };
9424};
9425
9426const vShow = {
9427 beforeMount(el, { value }, { transition }) {
9428 el._vod = el.style.display === 'none' ? '' : el.style.display;
9429 if (transition && value) {
9430 transition.beforeEnter(el);
9431 }
9432 else {
9433 setDisplay(el, value);
9434 }
9435 },
9436 mounted(el, { value }, { transition }) {
9437 if (transition && value) {
9438 transition.enter(el);
9439 }
9440 },
9441 updated(el, { value, oldValue }, { transition }) {
9442 if (!value === !oldValue)
9443 return;
9444 if (transition) {
9445 if (value) {
9446 transition.beforeEnter(el);
9447 setDisplay(el, true);
9448 transition.enter(el);
9449 }
9450 else {
9451 transition.leave(el, () => {
9452 setDisplay(el, false);
9453 });
9454 }
9455 }
9456 else {
9457 setDisplay(el, value);
9458 }
9459 },
9460 beforeUnmount(el, { value }) {
9461 setDisplay(el, value);
9462 }
9463};
9464function setDisplay(el, value) {
9465 el.style.display = value ? el._vod : 'none';
9466}
9467
9468const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps);
9469// lazy create the renderer - this makes core renderer logic tree-shakable
9470// in case the user only imports reactivity utilities from Vue.
9471let renderer;
9472let enabledHydration = false;
9473function ensureRenderer() {
9474 return renderer || (renderer = createRenderer(rendererOptions));
9475}
9476function ensureHydrationRenderer() {
9477 renderer = enabledHydration
9478 ? renderer
9479 : createHydrationRenderer(rendererOptions);
9480 enabledHydration = true;
9481 return renderer;
9482}
9483// use explicit type casts here to avoid import() calls in rolled-up d.ts
9484const render = ((...args) => {
9485 ensureRenderer().render(...args);
9486});
9487const hydrate = ((...args) => {
9488 ensureHydrationRenderer().hydrate(...args);
9489});
9490const createApp = ((...args) => {
9491 const app = ensureRenderer().createApp(...args);
9492 {
9493 injectNativeTagCheck(app);
9494 injectCustomElementCheck(app);
9495 }
9496 const { mount } = app;
9497 app.mount = (containerOrSelector) => {
9498 const container = normalizeContainer(containerOrSelector);
9499 if (!container)
9500 return;
9501 const component = app._component;
9502 if (!isFunction(component) && !component.render && !component.template) {
9503 component.template = container.innerHTML;
9504 }
9505 // clear content before mounting
9506 container.innerHTML = '';
9507 const proxy = mount(container, false, container instanceof SVGElement);
9508 if (container instanceof Element) {
9509 container.removeAttribute('v-cloak');
9510 container.setAttribute('data-v-app', '');
9511 }
9512 return proxy;
9513 };
9514 return app;
9515});
9516const createSSRApp = ((...args) => {
9517 const app = ensureHydrationRenderer().createApp(...args);
9518 {
9519 injectNativeTagCheck(app);
9520 injectCustomElementCheck(app);
9521 }
9522 const { mount } = app;
9523 app.mount = (containerOrSelector) => {
9524 const container = normalizeContainer(containerOrSelector);
9525 if (container) {
9526 return mount(container, true, container instanceof SVGElement);
9527 }
9528 };
9529 return app;
9530});
9531function injectNativeTagCheck(app) {
9532 // Inject `isNativeTag`
9533 // this is used for component name validation (dev only)
9534 Object.defineProperty(app.config, 'isNativeTag', {
9535 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
9536 writable: false
9537 });
9538}
9539// dev only
9540function injectCustomElementCheck(app) {
9541 if (isRuntimeOnly()) {
9542 const value = app.config.isCustomElement;
9543 Object.defineProperty(app.config, 'isCustomElement', {
9544 get() {
9545 return value;
9546 },
9547 set() {
9548 warn(`The \`isCustomElement\` config option is only respected when using the runtime compiler.` +
9549 `If you are using the runtime-only build, \`isCustomElement\` must be passed to \`@vue/compiler-dom\` in the build setup instead` +
9550 `- for example, via the \`compilerOptions\` option in vue-loader: https://vue-loader.vuejs.org/options.html#compileroptions.`);
9551 }
9552 });
9553 }
9554}
9555function normalizeContainer(container) {
9556 if (isString(container)) {
9557 const res = document.querySelector(container);
9558 if (!res) {
9559 warn(`Failed to mount app: mount target selector "${container}" returned null.`);
9560 }
9561 return res;
9562 }
9563 if (container instanceof window.ShadowRoot &&
9564 container.mode === 'closed') {
9565 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
9566 }
9567 return container;
9568}
9569
9570var runtimeDom = /*#__PURE__*/Object.freeze({
9571 __proto__: null,
9572 render: render,
9573 hydrate: hydrate,
9574 createApp: createApp,
9575 createSSRApp: createSSRApp,
9576 useCssModule: useCssModule,
9577 useCssVars: useCssVars,
9578 Transition: Transition,
9579 TransitionGroup: TransitionGroup,
9580 vModelText: vModelText,
9581 vModelCheckbox: vModelCheckbox,
9582 vModelRadio: vModelRadio,
9583 vModelSelect: vModelSelect,
9584 vModelDynamic: vModelDynamic,
9585 withModifiers: withModifiers,
9586 withKeys: withKeys,
9587 vShow: vShow,
9588 reactive: reactive,
9589 ref: ref,
9590 readonly: readonly,
9591 unref: unref,
9592 proxyRefs: proxyRefs,
9593 isRef: isRef,
9594 toRef: toRef,
9595 toRefs: toRefs,
9596 isProxy: isProxy,
9597 isReactive: isReactive,
9598 isReadonly: isReadonly,
9599 customRef: customRef,
9600 triggerRef: triggerRef,
9601 shallowRef: shallowRef,
9602 shallowReactive: shallowReactive,
9603 shallowReadonly: shallowReadonly,
9604 markRaw: markRaw,
9605 toRaw: toRaw,
9606 computed: computed$1,
9607 watch: watch,
9608 watchEffect: watchEffect,
9609 onBeforeMount: onBeforeMount,
9610 onMounted: onMounted,
9611 onBeforeUpdate: onBeforeUpdate,
9612 onUpdated: onUpdated,
9613 onBeforeUnmount: onBeforeUnmount,
9614 onUnmounted: onUnmounted,
9615 onActivated: onActivated,
9616 onDeactivated: onDeactivated,
9617 onRenderTracked: onRenderTracked,
9618 onRenderTriggered: onRenderTriggered,
9619 onErrorCaptured: onErrorCaptured,
9620 provide: provide,
9621 inject: inject,
9622 nextTick: nextTick,
9623 defineComponent: defineComponent,
9624 defineAsyncComponent: defineAsyncComponent,
9625 defineProps: defineProps,
9626 defineEmit: defineEmit,
9627 useContext: useContext,
9628 getCurrentInstance: getCurrentInstance,
9629 h: h,
9630 createVNode: createVNode,
9631 cloneVNode: cloneVNode,
9632 mergeProps: mergeProps,
9633 isVNode: isVNode,
9634 Fragment: Fragment,
9635 Text: Text,
9636 Comment: Comment,
9637 Static: Static,
9638 Teleport: Teleport,
9639 Suspense: Suspense,
9640 KeepAlive: KeepAlive,
9641 BaseTransition: BaseTransition,
9642 withDirectives: withDirectives,
9643 useSSRContext: useSSRContext,
9644 ssrContextKey: ssrContextKey,
9645 createRenderer: createRenderer,
9646 createHydrationRenderer: createHydrationRenderer,
9647 queuePostFlushCb: queuePostFlushCb,
9648 warn: warn,
9649 handleError: handleError,
9650 callWithErrorHandling: callWithErrorHandling,
9651 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
9652 resolveComponent: resolveComponent,
9653 resolveDirective: resolveDirective,
9654 resolveDynamicComponent: resolveDynamicComponent,
9655 registerRuntimeCompiler: registerRuntimeCompiler,
9656 isRuntimeOnly: isRuntimeOnly,
9657 useTransitionState: useTransitionState,
9658 resolveTransitionHooks: resolveTransitionHooks,
9659 setTransitionHooks: setTransitionHooks,
9660 getTransitionRawChildren: getTransitionRawChildren,
9661 initCustomFormatter: initCustomFormatter,
9662 get devtools () { return devtools; },
9663 setDevtoolsHook: setDevtoolsHook,
9664 withCtx: withCtx,
9665 pushScopeId: pushScopeId,
9666 popScopeId: popScopeId,
9667 withScopeId: withScopeId,
9668 renderList: renderList,
9669 toHandlers: toHandlers,
9670 renderSlot: renderSlot,
9671 createSlots: createSlots,
9672 openBlock: openBlock,
9673 createBlock: createBlock,
9674 setBlockTracking: setBlockTracking,
9675 createTextVNode: createTextVNode,
9676 createCommentVNode: createCommentVNode,
9677 createStaticVNode: createStaticVNode,
9678 toDisplayString: toDisplayString,
9679 camelize: camelize,
9680 capitalize: capitalize,
9681 toHandlerKey: toHandlerKey,
9682 transformVNodeArgs: transformVNodeArgs,
9683 version: version,
9684 ssrUtils: ssrUtils
9685});
9686
9687function initDev() {
9688 {
9689 {
9690 console.info(`You are running a development build of Vue.\n` +
9691 `Make sure to use the production build (*.prod.js) when deploying for production.`);
9692 }
9693 initCustomFormatter();
9694 }
9695}
9696
9697function defaultOnError(error) {
9698 throw error;
9699}
9700function createCompilerError(code, loc, messages, additionalMessage) {
9701 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
9702 ;
9703 const error = new SyntaxError(String(msg));
9704 error.code = code;
9705 error.loc = loc;
9706 return error;
9707}
9708const errorMessages = {
9709 // parse errors
9710 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
9711 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
9712 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
9713 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
9714 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
9715 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
9716 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
9717 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
9718 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
9719 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
9720 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
9721 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
9722 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
9723 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
9724 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
9725 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
9726 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
9727 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
9728 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
9729 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
9730 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
9731 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
9732 // Vue-specific parse errors
9733 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
9734 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
9735 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
9736 [26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
9737 'Note that dynamic directive argument cannot contain spaces.',
9738 // transform errors
9739 [27 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
9740 [28 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
9741 [29 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if.`,
9742 [30 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
9743 [31 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
9744 [32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
9745 [33 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
9746 [34 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
9747 [35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
9748 [36 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
9749 `When there are multiple named slots, all slots should use <template> ` +
9750 `syntax to avoid scope ambiguity.`,
9751 [37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
9752 [38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
9753 `default slot. These children will be ignored.`,
9754 [39 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
9755 [40 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
9756 [41 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
9757 [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.`,
9758 [43 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
9759 [44 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
9760 // generic errors
9761 [45 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
9762 [46 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
9763 [47 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
9764 [48 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`
9765};
9766
9767const FRAGMENT = Symbol(`Fragment` );
9768const TELEPORT = Symbol(`Teleport` );
9769const SUSPENSE = Symbol(`Suspense` );
9770const KEEP_ALIVE = Symbol(`KeepAlive` );
9771const BASE_TRANSITION = Symbol(`BaseTransition` );
9772const OPEN_BLOCK = Symbol(`openBlock` );
9773const CREATE_BLOCK = Symbol(`createBlock` );
9774const CREATE_VNODE = Symbol(`createVNode` );
9775const CREATE_COMMENT = Symbol(`createCommentVNode` );
9776const CREATE_TEXT = Symbol(`createTextVNode` );
9777const CREATE_STATIC = Symbol(`createStaticVNode` );
9778const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
9779const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
9780const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
9781const WITH_DIRECTIVES = Symbol(`withDirectives` );
9782const RENDER_LIST = Symbol(`renderList` );
9783const RENDER_SLOT = Symbol(`renderSlot` );
9784const CREATE_SLOTS = Symbol(`createSlots` );
9785const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
9786const MERGE_PROPS = Symbol(`mergeProps` );
9787const TO_HANDLERS = Symbol(`toHandlers` );
9788const CAMELIZE = Symbol(`camelize` );
9789const CAPITALIZE = Symbol(`capitalize` );
9790const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
9791const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
9792const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
9793const POP_SCOPE_ID = Symbol(`popScopeId` );
9794const WITH_SCOPE_ID = Symbol(`withScopeId` );
9795const WITH_CTX = Symbol(`withCtx` );
9796const UNREF = Symbol(`unref` );
9797const IS_REF = Symbol(`isRef` );
9798// Name mapping for runtime helpers that need to be imported from 'vue' in
9799// generated code. Make sure these are correctly exported in the runtime!
9800// Using `any` here because TS doesn't allow symbols as index type.
9801const helperNameMap = {
9802 [FRAGMENT]: `Fragment`,
9803 [TELEPORT]: `Teleport`,
9804 [SUSPENSE]: `Suspense`,
9805 [KEEP_ALIVE]: `KeepAlive`,
9806 [BASE_TRANSITION]: `BaseTransition`,
9807 [OPEN_BLOCK]: `openBlock`,
9808 [CREATE_BLOCK]: `createBlock`,
9809 [CREATE_VNODE]: `createVNode`,
9810 [CREATE_COMMENT]: `createCommentVNode`,
9811 [CREATE_TEXT]: `createTextVNode`,
9812 [CREATE_STATIC]: `createStaticVNode`,
9813 [RESOLVE_COMPONENT]: `resolveComponent`,
9814 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
9815 [RESOLVE_DIRECTIVE]: `resolveDirective`,
9816 [WITH_DIRECTIVES]: `withDirectives`,
9817 [RENDER_LIST]: `renderList`,
9818 [RENDER_SLOT]: `renderSlot`,
9819 [CREATE_SLOTS]: `createSlots`,
9820 [TO_DISPLAY_STRING]: `toDisplayString`,
9821 [MERGE_PROPS]: `mergeProps`,
9822 [TO_HANDLERS]: `toHandlers`,
9823 [CAMELIZE]: `camelize`,
9824 [CAPITALIZE]: `capitalize`,
9825 [TO_HANDLER_KEY]: `toHandlerKey`,
9826 [SET_BLOCK_TRACKING]: `setBlockTracking`,
9827 [PUSH_SCOPE_ID]: `pushScopeId`,
9828 [POP_SCOPE_ID]: `popScopeId`,
9829 [WITH_SCOPE_ID]: `withScopeId`,
9830 [WITH_CTX]: `withCtx`,
9831 [UNREF]: `unref`,
9832 [IS_REF]: `isRef`
9833};
9834function registerRuntimeHelpers(helpers) {
9835 Object.getOwnPropertySymbols(helpers).forEach(s => {
9836 helperNameMap[s] = helpers[s];
9837 });
9838}
9839
9840// AST Utilities ---------------------------------------------------------------
9841// Some expressions, e.g. sequence and conditional expressions, are never
9842// associated with template nodes, so their source locations are just a stub.
9843// Container types like CompoundExpression also don't need a real location.
9844const locStub = {
9845 source: '',
9846 start: { line: 1, column: 1, offset: 0 },
9847 end: { line: 1, column: 1, offset: 0 }
9848};
9849function createRoot(children, loc = locStub) {
9850 return {
9851 type: 0 /* ROOT */,
9852 children,
9853 helpers: [],
9854 components: [],
9855 directives: [],
9856 hoists: [],
9857 imports: [],
9858 cached: 0,
9859 temps: 0,
9860 codegenNode: undefined,
9861 loc
9862 };
9863}
9864function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) {
9865 if (context) {
9866 if (isBlock) {
9867 context.helper(OPEN_BLOCK);
9868 context.helper(CREATE_BLOCK);
9869 }
9870 else {
9871 context.helper(CREATE_VNODE);
9872 }
9873 if (directives) {
9874 context.helper(WITH_DIRECTIVES);
9875 }
9876 }
9877 return {
9878 type: 13 /* VNODE_CALL */,
9879 tag,
9880 props,
9881 children,
9882 patchFlag,
9883 dynamicProps,
9884 directives,
9885 isBlock,
9886 disableTracking,
9887 loc
9888 };
9889}
9890function createArrayExpression(elements, loc = locStub) {
9891 return {
9892 type: 17 /* JS_ARRAY_EXPRESSION */,
9893 loc,
9894 elements
9895 };
9896}
9897function createObjectExpression(properties, loc = locStub) {
9898 return {
9899 type: 15 /* JS_OBJECT_EXPRESSION */,
9900 loc,
9901 properties
9902 };
9903}
9904function createObjectProperty(key, value) {
9905 return {
9906 type: 16 /* JS_PROPERTY */,
9907 loc: locStub,
9908 key: isString(key) ? createSimpleExpression(key, true) : key,
9909 value
9910 };
9911}
9912function createSimpleExpression(content, isStatic, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
9913 return {
9914 type: 4 /* SIMPLE_EXPRESSION */,
9915 loc,
9916 content,
9917 isStatic,
9918 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
9919 };
9920}
9921function createCompoundExpression(children, loc = locStub) {
9922 return {
9923 type: 8 /* COMPOUND_EXPRESSION */,
9924 loc,
9925 children
9926 };
9927}
9928function createCallExpression(callee, args = [], loc = locStub) {
9929 return {
9930 type: 14 /* JS_CALL_EXPRESSION */,
9931 loc,
9932 callee,
9933 arguments: args
9934 };
9935}
9936function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
9937 return {
9938 type: 18 /* JS_FUNCTION_EXPRESSION */,
9939 params,
9940 returns,
9941 newline,
9942 isSlot,
9943 loc
9944 };
9945}
9946function createConditionalExpression(test, consequent, alternate, newline = true) {
9947 return {
9948 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
9949 test,
9950 consequent,
9951 alternate,
9952 newline,
9953 loc: locStub
9954 };
9955}
9956function createCacheExpression(index, value, isVNode = false) {
9957 return {
9958 type: 20 /* JS_CACHE_EXPRESSION */,
9959 index,
9960 value,
9961 isVNode,
9962 loc: locStub
9963 };
9964}
9965
9966const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
9967const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
9968function isCoreComponent(tag) {
9969 if (isBuiltInType(tag, 'Teleport')) {
9970 return TELEPORT;
9971 }
9972 else if (isBuiltInType(tag, 'Suspense')) {
9973 return SUSPENSE;
9974 }
9975 else if (isBuiltInType(tag, 'KeepAlive')) {
9976 return KEEP_ALIVE;
9977 }
9978 else if (isBuiltInType(tag, 'BaseTransition')) {
9979 return BASE_TRANSITION;
9980 }
9981}
9982const nonIdentifierRE = /^\d|[^\$\w]/;
9983const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
9984const memberExpRE = /^[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*(?:\s*\.\s*[A-Za-z_$\xA0-\uFFFF][\w$\xA0-\uFFFF]*|\[[^\]]+\])*$/;
9985const isMemberExpression = (path) => {
9986 if (!path)
9987 return false;
9988 return memberExpRE.test(path.trim());
9989};
9990function getInnerRange(loc, offset, length) {
9991 const source = loc.source.substr(offset, length);
9992 const newLoc = {
9993 source,
9994 start: advancePositionWithClone(loc.start, loc.source, offset),
9995 end: loc.end
9996 };
9997 if (length != null) {
9998 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
9999 }
10000 return newLoc;
10001}
10002function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
10003 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
10004}
10005// advance by mutation without cloning (for performance reasons), since this
10006// gets called a lot in the parser
10007function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
10008 let linesCount = 0;
10009 let lastNewLinePos = -1;
10010 for (let i = 0; i < numberOfCharacters; i++) {
10011 if (source.charCodeAt(i) === 10 /* newline char code */) {
10012 linesCount++;
10013 lastNewLinePos = i;
10014 }
10015 }
10016 pos.offset += numberOfCharacters;
10017 pos.line += linesCount;
10018 pos.column =
10019 lastNewLinePos === -1
10020 ? pos.column + numberOfCharacters
10021 : numberOfCharacters - lastNewLinePos;
10022 return pos;
10023}
10024function assert(condition, msg) {
10025 /* istanbul ignore if */
10026 if (!condition) {
10027 throw new Error(msg || `unexpected compiler condition`);
10028 }
10029}
10030function findDir(node, name, allowEmpty = false) {
10031 for (let i = 0; i < node.props.length; i++) {
10032 const p = node.props[i];
10033 if (p.type === 7 /* DIRECTIVE */ &&
10034 (allowEmpty || p.exp) &&
10035 (isString(name) ? p.name === name : name.test(p.name))) {
10036 return p;
10037 }
10038 }
10039}
10040function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
10041 for (let i = 0; i < node.props.length; i++) {
10042 const p = node.props[i];
10043 if (p.type === 6 /* ATTRIBUTE */) {
10044 if (dynamicOnly)
10045 continue;
10046 if (p.name === name && (p.value || allowEmpty)) {
10047 return p;
10048 }
10049 }
10050 else if (p.name === 'bind' &&
10051 (p.exp || allowEmpty) &&
10052 isBindKey(p.arg, name)) {
10053 return p;
10054 }
10055 }
10056}
10057function isBindKey(arg, name) {
10058 return !!(arg && isStaticExp(arg) && arg.content === name);
10059}
10060function hasDynamicKeyVBind(node) {
10061 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
10062 p.name === 'bind' &&
10063 (!p.arg || // v-bind="obj"
10064 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
10065 !p.arg.isStatic) // v-bind:[foo]
10066 );
10067}
10068function isText(node) {
10069 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
10070}
10071function isVSlot(p) {
10072 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
10073}
10074function isTemplateNode(node) {
10075 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
10076}
10077function isSlotOutlet(node) {
10078 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
10079}
10080function injectProp(node, prop, context) {
10081 let propsWithInjection;
10082 const props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
10083 if (props == null || isString(props)) {
10084 propsWithInjection = createObjectExpression([prop]);
10085 }
10086 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
10087 // merged props... add ours
10088 // only inject key to object literal if it's the first argument so that
10089 // if doesn't override user provided keys
10090 const first = props.arguments[0];
10091 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
10092 first.properties.unshift(prop);
10093 }
10094 else {
10095 if (props.callee === TO_HANDLERS) {
10096 // #2366
10097 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
10098 createObjectExpression([prop]),
10099 props
10100 ]);
10101 }
10102 else {
10103 props.arguments.unshift(createObjectExpression([prop]));
10104 }
10105 }
10106 !propsWithInjection && (propsWithInjection = props);
10107 }
10108 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
10109 let alreadyExists = false;
10110 // check existing key to avoid overriding user provided keys
10111 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
10112 const propKeyName = prop.key.content;
10113 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
10114 p.key.content === propKeyName);
10115 }
10116 if (!alreadyExists) {
10117 props.properties.unshift(prop);
10118 }
10119 propsWithInjection = props;
10120 }
10121 else {
10122 // single v-bind with expression, return a merged replacement
10123 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
10124 createObjectExpression([prop]),
10125 props
10126 ]);
10127 }
10128 if (node.type === 13 /* VNODE_CALL */) {
10129 node.props = propsWithInjection;
10130 }
10131 else {
10132 node.arguments[2] = propsWithInjection;
10133 }
10134}
10135function toValidAssetId(name, type) {
10136 return `_${type}_${name.replace(/[^\w]/g, '_')}`;
10137}
10138
10139// The default decoder only provides escapes for characters reserved as part of
10140// the template syntax, and is only used if the custom renderer did not provide
10141// a platform-specific decoder.
10142const decodeRE = /&(gt|lt|amp|apos|quot);/g;
10143const decodeMap = {
10144 gt: '>',
10145 lt: '<',
10146 amp: '&',
10147 apos: "'",
10148 quot: '"'
10149};
10150const defaultParserOptions = {
10151 delimiters: [`{{`, `}}`],
10152 getNamespace: () => 0 /* HTML */,
10153 getTextMode: () => 0 /* DATA */,
10154 isVoidTag: NO,
10155 isPreTag: NO,
10156 isCustomElement: NO,
10157 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
10158 onError: defaultOnError,
10159 comments: false
10160};
10161function baseParse(content, options = {}) {
10162 const context = createParserContext(content, options);
10163 const start = getCursor(context);
10164 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
10165}
10166function createParserContext(content, rawOptions) {
10167 const options = extend({}, defaultParserOptions);
10168 for (const key in rawOptions) {
10169 // @ts-ignore
10170 options[key] = rawOptions[key] || defaultParserOptions[key];
10171 }
10172 return {
10173 options,
10174 column: 1,
10175 line: 1,
10176 offset: 0,
10177 originalSource: content,
10178 source: content,
10179 inPre: false,
10180 inVPre: false
10181 };
10182}
10183function parseChildren(context, mode, ancestors) {
10184 const parent = last(ancestors);
10185 const ns = parent ? parent.ns : 0 /* HTML */;
10186 const nodes = [];
10187 while (!isEnd(context, mode, ancestors)) {
10188 const s = context.source;
10189 let node = undefined;
10190 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
10191 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
10192 // '{{'
10193 node = parseInterpolation(context, mode);
10194 }
10195 else if (mode === 0 /* DATA */ && s[0] === '<') {
10196 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
10197 if (s.length === 1) {
10198 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
10199 }
10200 else if (s[1] === '!') {
10201 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
10202 if (startsWith(s, '<!--')) {
10203 node = parseComment(context);
10204 }
10205 else if (startsWith(s, '<!DOCTYPE')) {
10206 // Ignore DOCTYPE by a limitation.
10207 node = parseBogusComment(context);
10208 }
10209 else if (startsWith(s, '<![CDATA[')) {
10210 if (ns !== 0 /* HTML */) {
10211 node = parseCDATA(context, ancestors);
10212 }
10213 else {
10214 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
10215 node = parseBogusComment(context);
10216 }
10217 }
10218 else {
10219 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
10220 node = parseBogusComment(context);
10221 }
10222 }
10223 else if (s[1] === '/') {
10224 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
10225 if (s.length === 2) {
10226 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
10227 }
10228 else if (s[2] === '>') {
10229 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
10230 advanceBy(context, 3);
10231 continue;
10232 }
10233 else if (/[a-z]/i.test(s[2])) {
10234 emitError(context, 23 /* X_INVALID_END_TAG */);
10235 parseTag(context, 1 /* End */, parent);
10236 continue;
10237 }
10238 else {
10239 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
10240 node = parseBogusComment(context);
10241 }
10242 }
10243 else if (/[a-z]/i.test(s[1])) {
10244 node = parseElement(context, ancestors);
10245 }
10246 else if (s[1] === '?') {
10247 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
10248 node = parseBogusComment(context);
10249 }
10250 else {
10251 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
10252 }
10253 }
10254 }
10255 if (!node) {
10256 node = parseText(context, mode);
10257 }
10258 if (isArray(node)) {
10259 for (let i = 0; i < node.length; i++) {
10260 pushNode(nodes, node[i]);
10261 }
10262 }
10263 else {
10264 pushNode(nodes, node);
10265 }
10266 }
10267 // Whitespace management for more efficient output
10268 // (same as v2 whitespace: 'condense')
10269 let removedWhitespace = false;
10270 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
10271 for (let i = 0; i < nodes.length; i++) {
10272 const node = nodes[i];
10273 if (!context.inPre && node.type === 2 /* TEXT */) {
10274 if (!/[^\t\r\n\f ]/.test(node.content)) {
10275 const prev = nodes[i - 1];
10276 const next = nodes[i + 1];
10277 // If:
10278 // - the whitespace is the first or last node, or:
10279 // - the whitespace is adjacent to a comment, or:
10280 // - the whitespace is between two elements AND contains newline
10281 // Then the whitespace is ignored.
10282 if (!prev ||
10283 !next ||
10284 prev.type === 3 /* COMMENT */ ||
10285 next.type === 3 /* COMMENT */ ||
10286 (prev.type === 1 /* ELEMENT */ &&
10287 next.type === 1 /* ELEMENT */ &&
10288 /[\r\n]/.test(node.content))) {
10289 removedWhitespace = true;
10290 nodes[i] = null;
10291 }
10292 else {
10293 // Otherwise, condensed consecutive whitespace inside the text
10294 // down to a single space
10295 node.content = ' ';
10296 }
10297 }
10298 else {
10299 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
10300 }
10301 }
10302 }
10303 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
10304 // remove leading newline per html spec
10305 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
10306 const first = nodes[0];
10307 if (first && first.type === 2 /* TEXT */) {
10308 first.content = first.content.replace(/^\r?\n/, '');
10309 }
10310 }
10311 }
10312 return removedWhitespace ? nodes.filter(Boolean) : nodes;
10313}
10314function pushNode(nodes, node) {
10315 if (node.type === 2 /* TEXT */) {
10316 const prev = last(nodes);
10317 // Merge if both this and the previous node are text and those are
10318 // consecutive. This happens for cases like "a < b".
10319 if (prev &&
10320 prev.type === 2 /* TEXT */ &&
10321 prev.loc.end.offset === node.loc.start.offset) {
10322 prev.content += node.content;
10323 prev.loc.end = node.loc.end;
10324 prev.loc.source += node.loc.source;
10325 return;
10326 }
10327 }
10328 nodes.push(node);
10329}
10330function parseCDATA(context, ancestors) {
10331 advanceBy(context, 9);
10332 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
10333 if (context.source.length === 0) {
10334 emitError(context, 6 /* EOF_IN_CDATA */);
10335 }
10336 else {
10337 advanceBy(context, 3);
10338 }
10339 return nodes;
10340}
10341function parseComment(context) {
10342 const start = getCursor(context);
10343 let content;
10344 // Regular comment.
10345 const match = /--(\!)?>/.exec(context.source);
10346 if (!match) {
10347 content = context.source.slice(4);
10348 advanceBy(context, context.source.length);
10349 emitError(context, 7 /* EOF_IN_COMMENT */);
10350 }
10351 else {
10352 if (match.index <= 3) {
10353 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
10354 }
10355 if (match[1]) {
10356 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
10357 }
10358 content = context.source.slice(4, match.index);
10359 // Advancing with reporting nested comments.
10360 const s = context.source.slice(0, match.index);
10361 let prevIndex = 1, nestedIndex = 0;
10362 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
10363 advanceBy(context, nestedIndex - prevIndex + 1);
10364 if (nestedIndex + 4 < s.length) {
10365 emitError(context, 16 /* NESTED_COMMENT */);
10366 }
10367 prevIndex = nestedIndex + 1;
10368 }
10369 advanceBy(context, match.index + match[0].length - prevIndex + 1);
10370 }
10371 return {
10372 type: 3 /* COMMENT */,
10373 content,
10374 loc: getSelection(context, start)
10375 };
10376}
10377function parseBogusComment(context) {
10378 const start = getCursor(context);
10379 const contentStart = context.source[1] === '?' ? 1 : 2;
10380 let content;
10381 const closeIndex = context.source.indexOf('>');
10382 if (closeIndex === -1) {
10383 content = context.source.slice(contentStart);
10384 advanceBy(context, context.source.length);
10385 }
10386 else {
10387 content = context.source.slice(contentStart, closeIndex);
10388 advanceBy(context, closeIndex + 1);
10389 }
10390 return {
10391 type: 3 /* COMMENT */,
10392 content,
10393 loc: getSelection(context, start)
10394 };
10395}
10396function parseElement(context, ancestors) {
10397 // Start tag.
10398 const wasInPre = context.inPre;
10399 const wasInVPre = context.inVPre;
10400 const parent = last(ancestors);
10401 const element = parseTag(context, 0 /* Start */, parent);
10402 const isPreBoundary = context.inPre && !wasInPre;
10403 const isVPreBoundary = context.inVPre && !wasInVPre;
10404 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
10405 return element;
10406 }
10407 // Children.
10408 ancestors.push(element);
10409 const mode = context.options.getTextMode(element, parent);
10410 const children = parseChildren(context, mode, ancestors);
10411 ancestors.pop();
10412 element.children = children;
10413 // End tag.
10414 if (startsWithEndTagOpen(context.source, element.tag)) {
10415 parseTag(context, 1 /* End */, parent);
10416 }
10417 else {
10418 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
10419 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
10420 const first = children[0];
10421 if (first && startsWith(first.loc.source, '<!--')) {
10422 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
10423 }
10424 }
10425 }
10426 element.loc = getSelection(context, element.loc.start);
10427 if (isPreBoundary) {
10428 context.inPre = false;
10429 }
10430 if (isVPreBoundary) {
10431 context.inVPre = false;
10432 }
10433 return element;
10434}
10435const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
10436/**
10437 * Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
10438 */
10439function parseTag(context, type, parent) {
10440 // Tag open.
10441 const start = getCursor(context);
10442 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
10443 const tag = match[1];
10444 const ns = context.options.getNamespace(tag, parent);
10445 advanceBy(context, match[0].length);
10446 advanceSpaces(context);
10447 // save current state in case we need to re-parse attributes with v-pre
10448 const cursor = getCursor(context);
10449 const currentSource = context.source;
10450 // Attributes.
10451 let props = parseAttributes(context, type);
10452 // check <pre> tag
10453 if (context.options.isPreTag(tag)) {
10454 context.inPre = true;
10455 }
10456 // check v-pre
10457 if (!context.inVPre &&
10458 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
10459 context.inVPre = true;
10460 // reset context
10461 extend(context, cursor);
10462 context.source = currentSource;
10463 // re-parse attrs and filter out v-pre itself
10464 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
10465 }
10466 // Tag close.
10467 let isSelfClosing = false;
10468 if (context.source.length === 0) {
10469 emitError(context, 9 /* EOF_IN_TAG */);
10470 }
10471 else {
10472 isSelfClosing = startsWith(context.source, '/>');
10473 if (type === 1 /* End */ && isSelfClosing) {
10474 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
10475 }
10476 advanceBy(context, isSelfClosing ? 2 : 1);
10477 }
10478 let tagType = 0 /* ELEMENT */;
10479 const options = context.options;
10480 if (!context.inVPre && !options.isCustomElement(tag)) {
10481 const hasVIs = props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'is');
10482 if (options.isNativeTag && !hasVIs) {
10483 if (!options.isNativeTag(tag))
10484 tagType = 1 /* COMPONENT */;
10485 }
10486 else if (hasVIs ||
10487 isCoreComponent(tag) ||
10488 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
10489 /^[A-Z]/.test(tag) ||
10490 tag === 'component') {
10491 tagType = 1 /* COMPONENT */;
10492 }
10493 if (tag === 'slot') {
10494 tagType = 2 /* SLOT */;
10495 }
10496 else if (tag === 'template' &&
10497 props.some(p => {
10498 return (p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name));
10499 })) {
10500 tagType = 3 /* TEMPLATE */;
10501 }
10502 }
10503 return {
10504 type: 1 /* ELEMENT */,
10505 ns,
10506 tag,
10507 tagType,
10508 props,
10509 isSelfClosing,
10510 children: [],
10511 loc: getSelection(context, start),
10512 codegenNode: undefined // to be created during transform phase
10513 };
10514}
10515function parseAttributes(context, type) {
10516 const props = [];
10517 const attributeNames = new Set();
10518 while (context.source.length > 0 &&
10519 !startsWith(context.source, '>') &&
10520 !startsWith(context.source, '/>')) {
10521 if (startsWith(context.source, '/')) {
10522 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
10523 advanceBy(context, 1);
10524 advanceSpaces(context);
10525 continue;
10526 }
10527 if (type === 1 /* End */) {
10528 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
10529 }
10530 const attr = parseAttribute(context, attributeNames);
10531 if (type === 0 /* Start */) {
10532 props.push(attr);
10533 }
10534 if (/^[^\t\r\n\f />]/.test(context.source)) {
10535 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
10536 }
10537 advanceSpaces(context);
10538 }
10539 return props;
10540}
10541function parseAttribute(context, nameSet) {
10542 // Name.
10543 const start = getCursor(context);
10544 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
10545 const name = match[0];
10546 if (nameSet.has(name)) {
10547 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
10548 }
10549 nameSet.add(name);
10550 if (name[0] === '=') {
10551 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
10552 }
10553 {
10554 const pattern = /["'<]/g;
10555 let m;
10556 while ((m = pattern.exec(name))) {
10557 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
10558 }
10559 }
10560 advanceBy(context, name.length);
10561 // Value
10562 let value = undefined;
10563 if (/^[\t\r\n\f ]*=/.test(context.source)) {
10564 advanceSpaces(context);
10565 advanceBy(context, 1);
10566 advanceSpaces(context);
10567 value = parseAttributeValue(context);
10568 if (!value) {
10569 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
10570 }
10571 }
10572 const loc = getSelection(context, start);
10573 if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {
10574 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
10575 const dirName = match[1] ||
10576 (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');
10577 let arg;
10578 if (match[2]) {
10579 const isSlot = dirName === 'slot';
10580 const startOffset = name.lastIndexOf(match[2]);
10581 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
10582 let content = match[2];
10583 let isStatic = true;
10584 if (content.startsWith('[')) {
10585 isStatic = false;
10586 if (!content.endsWith(']')) {
10587 emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
10588 }
10589 content = content.substr(1, content.length - 2);
10590 }
10591 else if (isSlot) {
10592 // #1241 special case for v-slot: vuetify relies extensively on slot
10593 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
10594 // supports such usage so we are keeping it consistent with 2.x.
10595 content += match[3] || '';
10596 }
10597 arg = {
10598 type: 4 /* SIMPLE_EXPRESSION */,
10599 content,
10600 isStatic,
10601 constType: isStatic
10602 ? 3 /* CAN_STRINGIFY */
10603 : 0 /* NOT_CONSTANT */,
10604 loc
10605 };
10606 }
10607 if (value && value.isQuoted) {
10608 const valueLoc = value.loc;
10609 valueLoc.start.offset++;
10610 valueLoc.start.column++;
10611 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
10612 valueLoc.source = valueLoc.source.slice(1, -1);
10613 }
10614 return {
10615 type: 7 /* DIRECTIVE */,
10616 name: dirName,
10617 exp: value && {
10618 type: 4 /* SIMPLE_EXPRESSION */,
10619 content: value.content,
10620 isStatic: false,
10621 // Treat as non-constant by default. This can be potentially set to
10622 // other values by `transformExpression` to make it eligible for hoisting.
10623 constType: 0 /* NOT_CONSTANT */,
10624 loc: value.loc
10625 },
10626 arg,
10627 modifiers: match[3] ? match[3].substr(1).split('.') : [],
10628 loc
10629 };
10630 }
10631 return {
10632 type: 6 /* ATTRIBUTE */,
10633 name,
10634 value: value && {
10635 type: 2 /* TEXT */,
10636 content: value.content,
10637 loc: value.loc
10638 },
10639 loc
10640 };
10641}
10642function parseAttributeValue(context) {
10643 const start = getCursor(context);
10644 let content;
10645 const quote = context.source[0];
10646 const isQuoted = quote === `"` || quote === `'`;
10647 if (isQuoted) {
10648 // Quoted value.
10649 advanceBy(context, 1);
10650 const endIndex = context.source.indexOf(quote);
10651 if (endIndex === -1) {
10652 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
10653 }
10654 else {
10655 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
10656 advanceBy(context, 1);
10657 }
10658 }
10659 else {
10660 // Unquoted
10661 const match = /^[^\t\r\n\f >]+/.exec(context.source);
10662 if (!match) {
10663 return undefined;
10664 }
10665 const unexpectedChars = /["'<=`]/g;
10666 let m;
10667 while ((m = unexpectedChars.exec(match[0]))) {
10668 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
10669 }
10670 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
10671 }
10672 return { content, isQuoted, loc: getSelection(context, start) };
10673}
10674function parseInterpolation(context, mode) {
10675 const [open, close] = context.options.delimiters;
10676 const closeIndex = context.source.indexOf(close, open.length);
10677 if (closeIndex === -1) {
10678 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
10679 return undefined;
10680 }
10681 const start = getCursor(context);
10682 advanceBy(context, open.length);
10683 const innerStart = getCursor(context);
10684 const innerEnd = getCursor(context);
10685 const rawContentLength = closeIndex - open.length;
10686 const rawContent = context.source.slice(0, rawContentLength);
10687 const preTrimContent = parseTextData(context, rawContentLength, mode);
10688 const content = preTrimContent.trim();
10689 const startOffset = preTrimContent.indexOf(content);
10690 if (startOffset > 0) {
10691 advancePositionWithMutation(innerStart, rawContent, startOffset);
10692 }
10693 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
10694 advancePositionWithMutation(innerEnd, rawContent, endOffset);
10695 advanceBy(context, close.length);
10696 return {
10697 type: 5 /* INTERPOLATION */,
10698 content: {
10699 type: 4 /* SIMPLE_EXPRESSION */,
10700 isStatic: false,
10701 // Set `isConstant` to false by default and will decide in transformExpression
10702 constType: 0 /* NOT_CONSTANT */,
10703 content,
10704 loc: getSelection(context, innerStart, innerEnd)
10705 },
10706 loc: getSelection(context, start)
10707 };
10708}
10709function parseText(context, mode) {
10710 const endTokens = ['<', context.options.delimiters[0]];
10711 if (mode === 3 /* CDATA */) {
10712 endTokens.push(']]>');
10713 }
10714 let endIndex = context.source.length;
10715 for (let i = 0; i < endTokens.length; i++) {
10716 const index = context.source.indexOf(endTokens[i], 1);
10717 if (index !== -1 && endIndex > index) {
10718 endIndex = index;
10719 }
10720 }
10721 const start = getCursor(context);
10722 const content = parseTextData(context, endIndex, mode);
10723 return {
10724 type: 2 /* TEXT */,
10725 content,
10726 loc: getSelection(context, start)
10727 };
10728}
10729/**
10730 * Get text data with a given length from the current location.
10731 * This translates HTML entities in the text data.
10732 */
10733function parseTextData(context, length, mode) {
10734 const rawText = context.source.slice(0, length);
10735 advanceBy(context, length);
10736 if (mode === 2 /* RAWTEXT */ ||
10737 mode === 3 /* CDATA */ ||
10738 rawText.indexOf('&') === -1) {
10739 return rawText;
10740 }
10741 else {
10742 // DATA or RCDATA containing "&"". Entity decoding required.
10743 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
10744 }
10745}
10746function getCursor(context) {
10747 const { column, line, offset } = context;
10748 return { column, line, offset };
10749}
10750function getSelection(context, start, end) {
10751 end = end || getCursor(context);
10752 return {
10753 start,
10754 end,
10755 source: context.originalSource.slice(start.offset, end.offset)
10756 };
10757}
10758function last(xs) {
10759 return xs[xs.length - 1];
10760}
10761function startsWith(source, searchString) {
10762 return source.startsWith(searchString);
10763}
10764function advanceBy(context, numberOfCharacters) {
10765 const { source } = context;
10766 advancePositionWithMutation(context, source, numberOfCharacters);
10767 context.source = source.slice(numberOfCharacters);
10768}
10769function advanceSpaces(context) {
10770 const match = /^[\t\r\n\f ]+/.exec(context.source);
10771 if (match) {
10772 advanceBy(context, match[0].length);
10773 }
10774}
10775function getNewPosition(context, start, numberOfCharacters) {
10776 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
10777}
10778function emitError(context, code, offset, loc = getCursor(context)) {
10779 if (offset) {
10780 loc.offset += offset;
10781 loc.column += offset;
10782 }
10783 context.options.onError(createCompilerError(code, {
10784 start: loc,
10785 end: loc,
10786 source: ''
10787 }));
10788}
10789function isEnd(context, mode, ancestors) {
10790 const s = context.source;
10791 switch (mode) {
10792 case 0 /* DATA */:
10793 if (startsWith(s, '</')) {
10794 // TODO: probably bad performance
10795 for (let i = ancestors.length - 1; i >= 0; --i) {
10796 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
10797 return true;
10798 }
10799 }
10800 }
10801 break;
10802 case 1 /* RCDATA */:
10803 case 2 /* RAWTEXT */: {
10804 const parent = last(ancestors);
10805 if (parent && startsWithEndTagOpen(s, parent.tag)) {
10806 return true;
10807 }
10808 break;
10809 }
10810 case 3 /* CDATA */:
10811 if (startsWith(s, ']]>')) {
10812 return true;
10813 }
10814 break;
10815 }
10816 return !s;
10817}
10818function startsWithEndTagOpen(source, tag) {
10819 return (startsWith(source, '</') &&
10820 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
10821 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
10822}
10823
10824function hoistStatic(root, context) {
10825 walk(root, context,
10826 // Root node is unfortunately non-hoistable due to potential parent
10827 // fallthrough attributes.
10828 isSingleElementRoot(root, root.children[0]));
10829}
10830function isSingleElementRoot(root, child) {
10831 const { children } = root;
10832 return (children.length === 1 &&
10833 child.type === 1 /* ELEMENT */ &&
10834 !isSlotOutlet(child));
10835}
10836function walk(node, context, doNotHoistNode = false) {
10837 let hasHoistedNode = false;
10838 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
10839 // static bindings with expressions. These expressions are guaranteed to be
10840 // constant so they are still eligible for hoisting, but they are only
10841 // available at runtime and therefore cannot be evaluated ahead of time.
10842 // This is only a concern for pre-stringification (via transformHoist by
10843 // @vue/compiler-dom), but doing it here allows us to perform only one full
10844 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
10845 // stringficiation threshold is met.
10846 let canStringify = true;
10847 const { children } = node;
10848 for (let i = 0; i < children.length; i++) {
10849 const child = children[i];
10850 // only plain elements & text calls are eligible for hoisting.
10851 if (child.type === 1 /* ELEMENT */ &&
10852 child.tagType === 0 /* ELEMENT */) {
10853 const constantType = doNotHoistNode
10854 ? 0 /* NOT_CONSTANT */
10855 : getConstantType(child, context);
10856 if (constantType > 0 /* NOT_CONSTANT */) {
10857 if (constantType < 3 /* CAN_STRINGIFY */) {
10858 canStringify = false;
10859 }
10860 if (constantType >= 2 /* CAN_HOIST */) {
10861 child.codegenNode.patchFlag =
10862 -1 /* HOISTED */ + (` /* HOISTED */` );
10863 child.codegenNode = context.hoist(child.codegenNode);
10864 hasHoistedNode = true;
10865 continue;
10866 }
10867 }
10868 else {
10869 // node may contain dynamic children, but its props may be eligible for
10870 // hoisting.
10871 const codegenNode = child.codegenNode;
10872 if (codegenNode.type === 13 /* VNODE_CALL */) {
10873 const flag = getPatchFlag(codegenNode);
10874 if ((!flag ||
10875 flag === 512 /* NEED_PATCH */ ||
10876 flag === 1 /* TEXT */) &&
10877 getGeneratedPropsConstantType(child, context) >=
10878 2 /* CAN_HOIST */) {
10879 const props = getNodeProps(child);
10880 if (props) {
10881 codegenNode.props = context.hoist(props);
10882 }
10883 }
10884 }
10885 }
10886 }
10887 else if (child.type === 12 /* TEXT_CALL */) {
10888 const contentType = getConstantType(child.content, context);
10889 if (contentType > 0) {
10890 if (contentType < 3 /* CAN_STRINGIFY */) {
10891 canStringify = false;
10892 }
10893 if (contentType >= 2 /* CAN_HOIST */) {
10894 child.codegenNode = context.hoist(child.codegenNode);
10895 hasHoistedNode = true;
10896 }
10897 }
10898 }
10899 // walk further
10900 if (child.type === 1 /* ELEMENT */) {
10901 const isComponent = child.tagType === 1 /* COMPONENT */;
10902 if (isComponent) {
10903 context.scopes.vSlot++;
10904 }
10905 walk(child, context);
10906 if (isComponent) {
10907 context.scopes.vSlot--;
10908 }
10909 }
10910 else if (child.type === 11 /* FOR */) {
10911 // Do not hoist v-for single child because it has to be a block
10912 walk(child, context, child.children.length === 1);
10913 }
10914 else if (child.type === 9 /* IF */) {
10915 for (let i = 0; i < child.branches.length; i++) {
10916 // Do not hoist v-if single child because it has to be a block
10917 walk(child.branches[i], context, child.branches[i].children.length === 1);
10918 }
10919 }
10920 }
10921 if (canStringify && hasHoistedNode && context.transformHoist) {
10922 context.transformHoist(children, context, node);
10923 }
10924}
10925function getConstantType(node, context) {
10926 const { constantCache } = context;
10927 switch (node.type) {
10928 case 1 /* ELEMENT */:
10929 if (node.tagType !== 0 /* ELEMENT */) {
10930 return 0 /* NOT_CONSTANT */;
10931 }
10932 const cached = constantCache.get(node);
10933 if (cached !== undefined) {
10934 return cached;
10935 }
10936 const codegenNode = node.codegenNode;
10937 if (codegenNode.type !== 13 /* VNODE_CALL */) {
10938 return 0 /* NOT_CONSTANT */;
10939 }
10940 const flag = getPatchFlag(codegenNode);
10941 if (!flag) {
10942 let returnType = 3 /* CAN_STRINGIFY */;
10943 // Element itself has no patch flag. However we still need to check:
10944 // 1. Even for a node with no patch flag, it is possible for it to contain
10945 // non-hoistable expressions that refers to scope variables, e.g. compiler
10946 // injected keys or cached event handlers. Therefore we need to always
10947 // check the codegenNode's props to be sure.
10948 const generatedPropsType = getGeneratedPropsConstantType(node, context);
10949 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
10950 constantCache.set(node, 0 /* NOT_CONSTANT */);
10951 return 0 /* NOT_CONSTANT */;
10952 }
10953 if (generatedPropsType < returnType) {
10954 returnType = generatedPropsType;
10955 }
10956 // 2. its children.
10957 for (let i = 0; i < node.children.length; i++) {
10958 const childType = getConstantType(node.children[i], context);
10959 if (childType === 0 /* NOT_CONSTANT */) {
10960 constantCache.set(node, 0 /* NOT_CONSTANT */);
10961 return 0 /* NOT_CONSTANT */;
10962 }
10963 if (childType < returnType) {
10964 returnType = childType;
10965 }
10966 }
10967 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
10968 // type, check if any of the props can cause the type to be lowered
10969 // we can skip can_patch because it's guaranteed by the absence of a
10970 // patchFlag.
10971 if (returnType > 1 /* CAN_SKIP_PATCH */) {
10972 for (let i = 0; i < node.props.length; i++) {
10973 const p = node.props[i];
10974 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
10975 const expType = getConstantType(p.exp, context);
10976 if (expType === 0 /* NOT_CONSTANT */) {
10977 constantCache.set(node, 0 /* NOT_CONSTANT */);
10978 return 0 /* NOT_CONSTANT */;
10979 }
10980 if (expType < returnType) {
10981 returnType = expType;
10982 }
10983 }
10984 }
10985 }
10986 // only svg/foreignObject could be block here, however if they are
10987 // static then they don't need to be blocks since there will be no
10988 // nested updates.
10989 if (codegenNode.isBlock) {
10990 context.removeHelper(OPEN_BLOCK);
10991 context.removeHelper(CREATE_BLOCK);
10992 codegenNode.isBlock = false;
10993 context.helper(CREATE_VNODE);
10994 }
10995 constantCache.set(node, returnType);
10996 return returnType;
10997 }
10998 else {
10999 constantCache.set(node, 0 /* NOT_CONSTANT */);
11000 return 0 /* NOT_CONSTANT */;
11001 }
11002 case 2 /* TEXT */:
11003 case 3 /* COMMENT */:
11004 return 3 /* CAN_STRINGIFY */;
11005 case 9 /* IF */:
11006 case 11 /* FOR */:
11007 case 10 /* IF_BRANCH */:
11008 return 0 /* NOT_CONSTANT */;
11009 case 5 /* INTERPOLATION */:
11010 case 12 /* TEXT_CALL */:
11011 return getConstantType(node.content, context);
11012 case 4 /* SIMPLE_EXPRESSION */:
11013 return node.constType;
11014 case 8 /* COMPOUND_EXPRESSION */:
11015 let returnType = 3 /* CAN_STRINGIFY */;
11016 for (let i = 0; i < node.children.length; i++) {
11017 const child = node.children[i];
11018 if (isString(child) || isSymbol(child)) {
11019 continue;
11020 }
11021 const childType = getConstantType(child, context);
11022 if (childType === 0 /* NOT_CONSTANT */) {
11023 return 0 /* NOT_CONSTANT */;
11024 }
11025 else if (childType < returnType) {
11026 returnType = childType;
11027 }
11028 }
11029 return returnType;
11030 default:
11031 return 0 /* NOT_CONSTANT */;
11032 }
11033}
11034function getGeneratedPropsConstantType(node, context) {
11035 let returnType = 3 /* CAN_STRINGIFY */;
11036 const props = getNodeProps(node);
11037 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
11038 const { properties } = props;
11039 for (let i = 0; i < properties.length; i++) {
11040 const { key, value } = properties[i];
11041 const keyType = getConstantType(key, context);
11042 if (keyType === 0 /* NOT_CONSTANT */) {
11043 return keyType;
11044 }
11045 if (keyType < returnType) {
11046 returnType = keyType;
11047 }
11048 if (value.type !== 4 /* SIMPLE_EXPRESSION */) {
11049 return 0 /* NOT_CONSTANT */;
11050 }
11051 const valueType = getConstantType(value, context);
11052 if (valueType === 0 /* NOT_CONSTANT */) {
11053 return valueType;
11054 }
11055 if (valueType < returnType) {
11056 returnType = valueType;
11057 }
11058 }
11059 }
11060 return returnType;
11061}
11062function getNodeProps(node) {
11063 const codegenNode = node.codegenNode;
11064 if (codegenNode.type === 13 /* VNODE_CALL */) {
11065 return codegenNode.props;
11066 }
11067}
11068function getPatchFlag(node) {
11069 const flag = node.patchFlag;
11070 return flag ? parseInt(flag, 10) : undefined;
11071}
11072
11073function 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 }) {
11074 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
11075 const context = {
11076 // options
11077 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
11078 prefixIdentifiers,
11079 hoistStatic,
11080 cacheHandlers,
11081 nodeTransforms,
11082 directiveTransforms,
11083 transformHoist,
11084 isBuiltInComponent,
11085 isCustomElement,
11086 expressionPlugins,
11087 scopeId,
11088 slotted,
11089 ssr,
11090 ssrCssVars,
11091 bindingMetadata,
11092 inline,
11093 isTS,
11094 onError,
11095 // state
11096 root,
11097 helpers: new Map(),
11098 components: new Set(),
11099 directives: new Set(),
11100 hoists: [],
11101 imports: [],
11102 constantCache: new Map(),
11103 temps: 0,
11104 cached: 0,
11105 identifiers: Object.create(null),
11106 scopes: {
11107 vFor: 0,
11108 vSlot: 0,
11109 vPre: 0,
11110 vOnce: 0
11111 },
11112 parent: null,
11113 currentNode: root,
11114 childIndex: 0,
11115 // methods
11116 helper(name) {
11117 const count = context.helpers.get(name) || 0;
11118 context.helpers.set(name, count + 1);
11119 return name;
11120 },
11121 removeHelper(name) {
11122 const count = context.helpers.get(name);
11123 if (count) {
11124 const currentCount = count - 1;
11125 if (!currentCount) {
11126 context.helpers.delete(name);
11127 }
11128 else {
11129 context.helpers.set(name, currentCount);
11130 }
11131 }
11132 },
11133 helperString(name) {
11134 return `_${helperNameMap[context.helper(name)]}`;
11135 },
11136 replaceNode(node) {
11137 /* istanbul ignore if */
11138 {
11139 if (!context.currentNode) {
11140 throw new Error(`Node being replaced is already removed.`);
11141 }
11142 if (!context.parent) {
11143 throw new Error(`Cannot replace root node.`);
11144 }
11145 }
11146 context.parent.children[context.childIndex] = context.currentNode = node;
11147 },
11148 removeNode(node) {
11149 if (!context.parent) {
11150 throw new Error(`Cannot remove root node.`);
11151 }
11152 const list = context.parent.children;
11153 const removalIndex = node
11154 ? list.indexOf(node)
11155 : context.currentNode
11156 ? context.childIndex
11157 : -1;
11158 /* istanbul ignore if */
11159 if (removalIndex < 0) {
11160 throw new Error(`node being removed is not a child of current parent`);
11161 }
11162 if (!node || node === context.currentNode) {
11163 // current node removed
11164 context.currentNode = null;
11165 context.onNodeRemoved();
11166 }
11167 else {
11168 // sibling node removed
11169 if (context.childIndex > removalIndex) {
11170 context.childIndex--;
11171 context.onNodeRemoved();
11172 }
11173 }
11174 context.parent.children.splice(removalIndex, 1);
11175 },
11176 onNodeRemoved: () => { },
11177 addIdentifiers(exp) {
11178 },
11179 removeIdentifiers(exp) {
11180 },
11181 hoist(exp) {
11182 context.hoists.push(exp);
11183 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
11184 identifier.hoisted = exp;
11185 return identifier;
11186 },
11187 cache(exp, isVNode = false) {
11188 return createCacheExpression(++context.cached, exp, isVNode);
11189 }
11190 };
11191 return context;
11192}
11193function transform(root, options) {
11194 const context = createTransformContext(root, options);
11195 traverseNode(root, context);
11196 if (options.hoistStatic) {
11197 hoistStatic(root, context);
11198 }
11199 if (!options.ssr) {
11200 createRootCodegen(root, context);
11201 }
11202 // finalize meta information
11203 root.helpers = [...context.helpers.keys()];
11204 root.components = [...context.components];
11205 root.directives = [...context.directives];
11206 root.imports = context.imports;
11207 root.hoists = context.hoists;
11208 root.temps = context.temps;
11209 root.cached = context.cached;
11210}
11211function createRootCodegen(root, context) {
11212 const { helper, removeHelper } = context;
11213 const { children } = root;
11214 if (children.length === 1) {
11215 const child = children[0];
11216 // if the single child is an element, turn it into a block.
11217 if (isSingleElementRoot(root, child) && child.codegenNode) {
11218 // single element root is never hoisted so codegenNode will never be
11219 // SimpleExpressionNode
11220 const codegenNode = child.codegenNode;
11221 if (codegenNode.type === 13 /* VNODE_CALL */) {
11222 if (!codegenNode.isBlock) {
11223 removeHelper(CREATE_VNODE);
11224 codegenNode.isBlock = true;
11225 helper(OPEN_BLOCK);
11226 helper(CREATE_BLOCK);
11227 }
11228 }
11229 root.codegenNode = codegenNode;
11230 }
11231 else {
11232 // - single <slot/>, IfNode, ForNode: already blocks.
11233 // - single text node: always patched.
11234 // root codegen falls through via genNode()
11235 root.codegenNode = child;
11236 }
11237 }
11238 else if (children.length > 1) {
11239 // root has multiple nodes - return a fragment block.
11240 let patchFlag = 64 /* STABLE_FRAGMENT */;
11241 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
11242 // check if the fragment actually contains a single valid child with
11243 // the rest being comments
11244 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
11245 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
11246 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
11247 }
11248 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true);
11249 }
11250 else ;
11251}
11252function traverseChildren(parent, context) {
11253 let i = 0;
11254 const nodeRemoved = () => {
11255 i--;
11256 };
11257 for (; i < parent.children.length; i++) {
11258 const child = parent.children[i];
11259 if (isString(child))
11260 continue;
11261 context.parent = parent;
11262 context.childIndex = i;
11263 context.onNodeRemoved = nodeRemoved;
11264 traverseNode(child, context);
11265 }
11266}
11267function traverseNode(node, context) {
11268 context.currentNode = node;
11269 // apply transform plugins
11270 const { nodeTransforms } = context;
11271 const exitFns = [];
11272 for (let i = 0; i < nodeTransforms.length; i++) {
11273 const onExit = nodeTransforms[i](node, context);
11274 if (onExit) {
11275 if (isArray(onExit)) {
11276 exitFns.push(...onExit);
11277 }
11278 else {
11279 exitFns.push(onExit);
11280 }
11281 }
11282 if (!context.currentNode) {
11283 // node was removed
11284 return;
11285 }
11286 else {
11287 // node may have been replaced
11288 node = context.currentNode;
11289 }
11290 }
11291 switch (node.type) {
11292 case 3 /* COMMENT */:
11293 if (!context.ssr) {
11294 // inject import for the Comment symbol, which is needed for creating
11295 // comment nodes with `createVNode`
11296 context.helper(CREATE_COMMENT);
11297 }
11298 break;
11299 case 5 /* INTERPOLATION */:
11300 // no need to traverse, but we need to inject toString helper
11301 if (!context.ssr) {
11302 context.helper(TO_DISPLAY_STRING);
11303 }
11304 break;
11305 // for container types, further traverse downwards
11306 case 9 /* IF */:
11307 for (let i = 0; i < node.branches.length; i++) {
11308 traverseNode(node.branches[i], context);
11309 }
11310 break;
11311 case 10 /* IF_BRANCH */:
11312 case 11 /* FOR */:
11313 case 1 /* ELEMENT */:
11314 case 0 /* ROOT */:
11315 traverseChildren(node, context);
11316 break;
11317 }
11318 // exit transforms
11319 context.currentNode = node;
11320 let i = exitFns.length;
11321 while (i--) {
11322 exitFns[i]();
11323 }
11324}
11325function createStructuralDirectiveTransform(name, fn) {
11326 const matches = isString(name)
11327 ? (n) => n === name
11328 : (n) => name.test(n);
11329 return (node, context) => {
11330 if (node.type === 1 /* ELEMENT */) {
11331 const { props } = node;
11332 // structural directive transforms are not concerned with slots
11333 // as they are handled separately in vSlot.ts
11334 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
11335 return;
11336 }
11337 const exitFns = [];
11338 for (let i = 0; i < props.length; i++) {
11339 const prop = props[i];
11340 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
11341 // structural directives are removed to avoid infinite recursion
11342 // also we remove them *before* applying so that it can further
11343 // traverse itself in case it moves the node around
11344 props.splice(i, 1);
11345 i--;
11346 const onExit = fn(node, prop, context);
11347 if (onExit)
11348 exitFns.push(onExit);
11349 }
11350 }
11351 return exitFns;
11352 }
11353 };
11354}
11355
11356const PURE_ANNOTATION = `/*#__PURE__*/`;
11357function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
11358 const context = {
11359 mode,
11360 prefixIdentifiers,
11361 sourceMap,
11362 filename,
11363 scopeId,
11364 optimizeImports,
11365 runtimeGlobalName,
11366 runtimeModuleName,
11367 ssr,
11368 source: ast.loc.source,
11369 code: ``,
11370 column: 1,
11371 line: 1,
11372 offset: 0,
11373 indentLevel: 0,
11374 pure: false,
11375 map: undefined,
11376 helper(key) {
11377 return `_${helperNameMap[key]}`;
11378 },
11379 push(code, node) {
11380 context.code += code;
11381 },
11382 indent() {
11383 newline(++context.indentLevel);
11384 },
11385 deindent(withoutNewLine = false) {
11386 if (withoutNewLine) {
11387 --context.indentLevel;
11388 }
11389 else {
11390 newline(--context.indentLevel);
11391 }
11392 },
11393 newline() {
11394 newline(context.indentLevel);
11395 }
11396 };
11397 function newline(n) {
11398 context.push('\n' + ` `.repeat(n));
11399 }
11400 return context;
11401}
11402function generate(ast, options = {}) {
11403 const context = createCodegenContext(ast, options);
11404 if (options.onContextCreated)
11405 options.onContextCreated(context);
11406 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
11407 const hasHelpers = ast.helpers.length > 0;
11408 const useWithBlock = !prefixIdentifiers && mode !== 'module';
11409 // preambles
11410 // in setup() inline mode, the preamble is generated in a sub context
11411 // and returned separately.
11412 const preambleContext = context;
11413 {
11414 genFunctionPreamble(ast, preambleContext);
11415 }
11416 // enter render function
11417 const functionName = ssr ? `ssrRender` : `render`;
11418 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
11419 const signature = args.join(', ');
11420 {
11421 push(`function ${functionName}(${signature}) {`);
11422 }
11423 indent();
11424 if (useWithBlock) {
11425 push(`with (_ctx) {`);
11426 indent();
11427 // function mode const declarations should be inside with block
11428 // also they should be renamed to avoid collision with user properties
11429 if (hasHelpers) {
11430 push(`const { ${ast.helpers
11431 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
11432 .join(', ')} } = _Vue`);
11433 push(`\n`);
11434 newline();
11435 }
11436 }
11437 // generate asset resolution statements
11438 if (ast.components.length) {
11439 genAssets(ast.components, 'component', context);
11440 if (ast.directives.length || ast.temps > 0) {
11441 newline();
11442 }
11443 }
11444 if (ast.directives.length) {
11445 genAssets(ast.directives, 'directive', context);
11446 if (ast.temps > 0) {
11447 newline();
11448 }
11449 }
11450 if (ast.temps > 0) {
11451 push(`let `);
11452 for (let i = 0; i < ast.temps; i++) {
11453 push(`${i > 0 ? `, ` : ``}_temp${i}`);
11454 }
11455 }
11456 if (ast.components.length || ast.directives.length || ast.temps) {
11457 push(`\n`);
11458 newline();
11459 }
11460 // generate the VNode tree expression
11461 if (!ssr) {
11462 push(`return `);
11463 }
11464 if (ast.codegenNode) {
11465 genNode(ast.codegenNode, context);
11466 }
11467 else {
11468 push(`null`);
11469 }
11470 if (useWithBlock) {
11471 deindent();
11472 push(`}`);
11473 }
11474 deindent();
11475 push(`}`);
11476 return {
11477 ast,
11478 code: context.code,
11479 preamble: ``,
11480 // SourceMapGenerator does have toJSON() method but it's not in the types
11481 map: context.map ? context.map.toJSON() : undefined
11482 };
11483}
11484function genFunctionPreamble(ast, context) {
11485 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;
11486 const VueBinding = runtimeGlobalName;
11487 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
11488 // Generate const declaration for helpers
11489 // In prefix mode, we place the const declaration at top so it's done
11490 // only once; But if we not prefixing, we place the declaration inside the
11491 // with block so it doesn't incur the `in` check cost for every helper access.
11492 if (ast.helpers.length > 0) {
11493 {
11494 // "with" mode.
11495 // save Vue in a separate variable to avoid collision
11496 push(`const _Vue = ${VueBinding}\n`);
11497 // in "with" mode, helpers are declared inside the with block to avoid
11498 // has check cost, but hoists are lifted out of the function - we need
11499 // to provide the helper here.
11500 if (ast.hoists.length) {
11501 const staticHelpers = [
11502 CREATE_VNODE,
11503 CREATE_COMMENT,
11504 CREATE_TEXT,
11505 CREATE_STATIC
11506 ]
11507 .filter(helper => ast.helpers.includes(helper))
11508 .map(aliasHelper)
11509 .join(', ');
11510 push(`const { ${staticHelpers} } = _Vue\n`);
11511 }
11512 }
11513 }
11514 genHoists(ast.hoists, context);
11515 newline();
11516 push(`return `);
11517}
11518function genAssets(assets, type, { helper, push, newline }) {
11519 const resolver = helper(type === 'component' ? RESOLVE_COMPONENT : RESOLVE_DIRECTIVE);
11520 for (let i = 0; i < assets.length; i++) {
11521 let id = assets[i];
11522 // potential component implicit self-reference inferred from SFC filename
11523 const maybeSelfReference = id.endsWith('__self');
11524 if (maybeSelfReference) {
11525 id = id.slice(0, -6);
11526 }
11527 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})`);
11528 if (i < assets.length - 1) {
11529 newline();
11530 }
11531 }
11532}
11533function genHoists(hoists, context) {
11534 if (!hoists.length) {
11535 return;
11536 }
11537 context.pure = true;
11538 const { push, newline, helper, scopeId, mode } = context;
11539 newline();
11540 hoists.forEach((exp, i) => {
11541 if (exp) {
11542 push(`const _hoisted_${i + 1} = `);
11543 genNode(exp, context);
11544 newline();
11545 }
11546 });
11547 context.pure = false;
11548}
11549function isText$1(n) {
11550 return (isString(n) ||
11551 n.type === 4 /* SIMPLE_EXPRESSION */ ||
11552 n.type === 2 /* TEXT */ ||
11553 n.type === 5 /* INTERPOLATION */ ||
11554 n.type === 8 /* COMPOUND_EXPRESSION */);
11555}
11556function genNodeListAsArray(nodes, context) {
11557 const multilines = nodes.length > 3 ||
11558 (nodes.some(n => isArray(n) || !isText$1(n)));
11559 context.push(`[`);
11560 multilines && context.indent();
11561 genNodeList(nodes, context, multilines);
11562 multilines && context.deindent();
11563 context.push(`]`);
11564}
11565function genNodeList(nodes, context, multilines = false, comma = true) {
11566 const { push, newline } = context;
11567 for (let i = 0; i < nodes.length; i++) {
11568 const node = nodes[i];
11569 if (isString(node)) {
11570 push(node);
11571 }
11572 else if (isArray(node)) {
11573 genNodeListAsArray(node, context);
11574 }
11575 else {
11576 genNode(node, context);
11577 }
11578 if (i < nodes.length - 1) {
11579 if (multilines) {
11580 comma && push(',');
11581 newline();
11582 }
11583 else {
11584 comma && push(', ');
11585 }
11586 }
11587 }
11588}
11589function genNode(node, context) {
11590 if (isString(node)) {
11591 context.push(node);
11592 return;
11593 }
11594 if (isSymbol(node)) {
11595 context.push(context.helper(node));
11596 return;
11597 }
11598 switch (node.type) {
11599 case 1 /* ELEMENT */:
11600 case 9 /* IF */:
11601 case 11 /* FOR */:
11602 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
11603 `Apply appropriate transforms first.`);
11604 genNode(node.codegenNode, context);
11605 break;
11606 case 2 /* TEXT */:
11607 genText(node, context);
11608 break;
11609 case 4 /* SIMPLE_EXPRESSION */:
11610 genExpression(node, context);
11611 break;
11612 case 5 /* INTERPOLATION */:
11613 genInterpolation(node, context);
11614 break;
11615 case 12 /* TEXT_CALL */:
11616 genNode(node.codegenNode, context);
11617 break;
11618 case 8 /* COMPOUND_EXPRESSION */:
11619 genCompoundExpression(node, context);
11620 break;
11621 case 3 /* COMMENT */:
11622 genComment(node, context);
11623 break;
11624 case 13 /* VNODE_CALL */:
11625 genVNodeCall(node, context);
11626 break;
11627 case 14 /* JS_CALL_EXPRESSION */:
11628 genCallExpression(node, context);
11629 break;
11630 case 15 /* JS_OBJECT_EXPRESSION */:
11631 genObjectExpression(node, context);
11632 break;
11633 case 17 /* JS_ARRAY_EXPRESSION */:
11634 genArrayExpression(node, context);
11635 break;
11636 case 18 /* JS_FUNCTION_EXPRESSION */:
11637 genFunctionExpression(node, context);
11638 break;
11639 case 19 /* JS_CONDITIONAL_EXPRESSION */:
11640 genConditionalExpression(node, context);
11641 break;
11642 case 20 /* JS_CACHE_EXPRESSION */:
11643 genCacheExpression(node, context);
11644 break;
11645 // SSR only types
11646 case 21 /* JS_BLOCK_STATEMENT */:
11647 break;
11648 case 22 /* JS_TEMPLATE_LITERAL */:
11649 break;
11650 case 23 /* JS_IF_STATEMENT */:
11651 break;
11652 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
11653 break;
11654 case 25 /* JS_SEQUENCE_EXPRESSION */:
11655 break;
11656 case 26 /* JS_RETURN_STATEMENT */:
11657 break;
11658 /* istanbul ignore next */
11659 case 10 /* IF_BRANCH */:
11660 // noop
11661 break;
11662 default:
11663 {
11664 assert(false, `unhandled codegen node type: ${node.type}`);
11665 // make sure we exhaust all possible types
11666 const exhaustiveCheck = node;
11667 return exhaustiveCheck;
11668 }
11669 }
11670}
11671function genText(node, context) {
11672 context.push(JSON.stringify(node.content), node);
11673}
11674function genExpression(node, context) {
11675 const { content, isStatic } = node;
11676 context.push(isStatic ? JSON.stringify(content) : content, node);
11677}
11678function genInterpolation(node, context) {
11679 const { push, helper, pure } = context;
11680 if (pure)
11681 push(PURE_ANNOTATION);
11682 push(`${helper(TO_DISPLAY_STRING)}(`);
11683 genNode(node.content, context);
11684 push(`)`);
11685}
11686function genCompoundExpression(node, context) {
11687 for (let i = 0; i < node.children.length; i++) {
11688 const child = node.children[i];
11689 if (isString(child)) {
11690 context.push(child);
11691 }
11692 else {
11693 genNode(child, context);
11694 }
11695 }
11696}
11697function genExpressionAsPropertyKey(node, context) {
11698 const { push } = context;
11699 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
11700 push(`[`);
11701 genCompoundExpression(node, context);
11702 push(`]`);
11703 }
11704 else if (node.isStatic) {
11705 // only quote keys if necessary
11706 const text = isSimpleIdentifier(node.content)
11707 ? node.content
11708 : JSON.stringify(node.content);
11709 push(text, node);
11710 }
11711 else {
11712 push(`[${node.content}]`, node);
11713 }
11714}
11715function genComment(node, context) {
11716 {
11717 const { push, helper, pure } = context;
11718 if (pure) {
11719 push(PURE_ANNOTATION);
11720 }
11721 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
11722 }
11723}
11724function genVNodeCall(node, context) {
11725 const { push, helper, pure } = context;
11726 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;
11727 if (directives) {
11728 push(helper(WITH_DIRECTIVES) + `(`);
11729 }
11730 if (isBlock) {
11731 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
11732 }
11733 if (pure) {
11734 push(PURE_ANNOTATION);
11735 }
11736 push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);
11737 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
11738 push(`)`);
11739 if (isBlock) {
11740 push(`)`);
11741 }
11742 if (directives) {
11743 push(`, `);
11744 genNode(directives, context);
11745 push(`)`);
11746 }
11747}
11748function genNullableArgs(args) {
11749 let i = args.length;
11750 while (i--) {
11751 if (args[i] != null)
11752 break;
11753 }
11754 return args.slice(0, i + 1).map(arg => arg || `null`);
11755}
11756// JavaScript
11757function genCallExpression(node, context) {
11758 const { push, helper, pure } = context;
11759 const callee = isString(node.callee) ? node.callee : helper(node.callee);
11760 if (pure) {
11761 push(PURE_ANNOTATION);
11762 }
11763 push(callee + `(`, node);
11764 genNodeList(node.arguments, context);
11765 push(`)`);
11766}
11767function genObjectExpression(node, context) {
11768 const { push, indent, deindent, newline } = context;
11769 const { properties } = node;
11770 if (!properties.length) {
11771 push(`{}`, node);
11772 return;
11773 }
11774 const multilines = properties.length > 1 ||
11775 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
11776 push(multilines ? `{` : `{ `);
11777 multilines && indent();
11778 for (let i = 0; i < properties.length; i++) {
11779 const { key, value } = properties[i];
11780 // key
11781 genExpressionAsPropertyKey(key, context);
11782 push(`: `);
11783 // value
11784 genNode(value, context);
11785 if (i < properties.length - 1) {
11786 // will only reach this if it's multilines
11787 push(`,`);
11788 newline();
11789 }
11790 }
11791 multilines && deindent();
11792 push(multilines ? `}` : ` }`);
11793}
11794function genArrayExpression(node, context) {
11795 genNodeListAsArray(node.elements, context);
11796}
11797function genFunctionExpression(node, context) {
11798 const { push, indent, deindent, scopeId, mode } = context;
11799 const { params, returns, body, newline, isSlot } = node;
11800 if (isSlot) {
11801 // wrap slot functions with owner context
11802 push(`_${helperNameMap[WITH_CTX]}(`);
11803 }
11804 push(`(`, node);
11805 if (isArray(params)) {
11806 genNodeList(params, context);
11807 }
11808 else if (params) {
11809 genNode(params, context);
11810 }
11811 push(`) => `);
11812 if (newline || body) {
11813 push(`{`);
11814 indent();
11815 }
11816 if (returns) {
11817 if (newline) {
11818 push(`return `);
11819 }
11820 if (isArray(returns)) {
11821 genNodeListAsArray(returns, context);
11822 }
11823 else {
11824 genNode(returns, context);
11825 }
11826 }
11827 else if (body) {
11828 genNode(body, context);
11829 }
11830 if (newline || body) {
11831 deindent();
11832 push(`}`);
11833 }
11834 if (isSlot) {
11835 push(`)`);
11836 }
11837}
11838function genConditionalExpression(node, context) {
11839 const { test, consequent, alternate, newline: needNewline } = node;
11840 const { push, indent, deindent, newline } = context;
11841 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
11842 const needsParens = !isSimpleIdentifier(test.content);
11843 needsParens && push(`(`);
11844 genExpression(test, context);
11845 needsParens && push(`)`);
11846 }
11847 else {
11848 push(`(`);
11849 genNode(test, context);
11850 push(`)`);
11851 }
11852 needNewline && indent();
11853 context.indentLevel++;
11854 needNewline || push(` `);
11855 push(`? `);
11856 genNode(consequent, context);
11857 context.indentLevel--;
11858 needNewline && newline();
11859 needNewline || push(` `);
11860 push(`: `);
11861 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
11862 if (!isNested) {
11863 context.indentLevel++;
11864 }
11865 genNode(alternate, context);
11866 if (!isNested) {
11867 context.indentLevel--;
11868 }
11869 needNewline && deindent(true /* without newline */);
11870}
11871function genCacheExpression(node, context) {
11872 const { push, helper, indent, deindent, newline } = context;
11873 push(`_cache[${node.index}] || (`);
11874 if (node.isVNode) {
11875 indent();
11876 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
11877 newline();
11878 }
11879 push(`_cache[${node.index}] = `);
11880 genNode(node.value, context);
11881 if (node.isVNode) {
11882 push(`,`);
11883 newline();
11884 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
11885 newline();
11886 push(`_cache[${node.index}]`);
11887 deindent();
11888 }
11889 push(`)`);
11890}
11891
11892// these keywords should not appear inside expressions, but operators like
11893// typeof, instanceof and in are allowed
11894const prohibitedKeywordRE = new RegExp('\\b' +
11895 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
11896 'super,throw,while,yield,delete,export,import,return,switch,default,' +
11897 'extends,finally,continue,debugger,function,arguments,typeof,void')
11898 .split(',')
11899 .join('\\b|\\b') +
11900 '\\b');
11901// strip strings in expressions
11902const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
11903/**
11904 * Validate a non-prefixed expression.
11905 * This is only called when using the in-browser runtime compiler since it
11906 * doesn't prefix expressions.
11907 */
11908function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
11909 const exp = node.content;
11910 // empty expressions are validated per-directive since some directives
11911 // do allow empty expressions.
11912 if (!exp.trim()) {
11913 return;
11914 }
11915 try {
11916 new Function(asRawStatements
11917 ? ` ${exp} `
11918 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
11919 }
11920 catch (e) {
11921 let message = e.message;
11922 const keywordMatch = exp
11923 .replace(stripStringRE, '')
11924 .match(prohibitedKeywordRE);
11925 if (keywordMatch) {
11926 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
11927 }
11928 context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
11929 }
11930}
11931
11932const transformExpression = (node, context) => {
11933 if (node.type === 5 /* INTERPOLATION */) {
11934 node.content = processExpression(node.content, context);
11935 }
11936 else if (node.type === 1 /* ELEMENT */) {
11937 // handle directives on element
11938 for (let i = 0; i < node.props.length; i++) {
11939 const dir = node.props[i];
11940 // do not process for v-on & v-for since they are special handled
11941 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
11942 const exp = dir.exp;
11943 const arg = dir.arg;
11944 // do not process exp if this is v-on:arg - we need special handling
11945 // for wrapping inline statements.
11946 if (exp &&
11947 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
11948 !(dir.name === 'on' && arg)) {
11949 dir.exp = processExpression(exp, context,
11950 // slot args must be processed as function params
11951 dir.name === 'slot');
11952 }
11953 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
11954 dir.arg = processExpression(arg, context);
11955 }
11956 }
11957 }
11958 }
11959};
11960// Important: since this function uses Node.js only dependencies, it should
11961// always be used with a leading !true check so that it can be
11962// tree-shaken from the browser build.
11963function processExpression(node, context,
11964// some expressions like v-slot props & v-for aliases should be parsed as
11965// function params
11966asParams = false,
11967// v-on handler values may contain multiple statements
11968asRawStatements = false) {
11969 {
11970 {
11971 // simple in-browser validation (same logic in 2.x)
11972 validateBrowserExpression(node, context, asParams, asRawStatements);
11973 }
11974 return node;
11975 }
11976}
11977
11978const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
11979 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
11980 // #1587: We need to dynamically increment the key based on the current
11981 // node's sibling nodes, since chained v-if/else branches are
11982 // rendered at the same depth
11983 const siblings = context.parent.children;
11984 let i = siblings.indexOf(ifNode);
11985 let key = 0;
11986 while (i-- >= 0) {
11987 const sibling = siblings[i];
11988 if (sibling && sibling.type === 9 /* IF */) {
11989 key += sibling.branches.length;
11990 }
11991 }
11992 // Exit callback. Complete the codegenNode when all children have been
11993 // transformed.
11994 return () => {
11995 if (isRoot) {
11996 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
11997 }
11998 else {
11999 // attach this branch's codegen node to the v-if root.
12000 const parentCondition = getParentCondition(ifNode.codegenNode);
12001 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
12002 }
12003 };
12004 });
12005});
12006// target-agnostic transform used for both Client and SSR
12007function processIf(node, dir, context, processCodegen) {
12008 if (dir.name !== 'else' &&
12009 (!dir.exp || !dir.exp.content.trim())) {
12010 const loc = dir.exp ? dir.exp.loc : node.loc;
12011 context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));
12012 dir.exp = createSimpleExpression(`true`, false, loc);
12013 }
12014 if (dir.exp) {
12015 validateBrowserExpression(dir.exp, context);
12016 }
12017 if (dir.name === 'if') {
12018 const branch = createIfBranch(node, dir);
12019 const ifNode = {
12020 type: 9 /* IF */,
12021 loc: node.loc,
12022 branches: [branch]
12023 };
12024 context.replaceNode(ifNode);
12025 if (processCodegen) {
12026 return processCodegen(ifNode, branch, true);
12027 }
12028 }
12029 else {
12030 // locate the adjacent v-if
12031 const siblings = context.parent.children;
12032 const comments = [];
12033 let i = siblings.indexOf(node);
12034 while (i-- >= -1) {
12035 const sibling = siblings[i];
12036 if (sibling && sibling.type === 3 /* COMMENT */) {
12037 context.removeNode(sibling);
12038 comments.unshift(sibling);
12039 continue;
12040 }
12041 if (sibling &&
12042 sibling.type === 2 /* TEXT */ &&
12043 !sibling.content.trim().length) {
12044 context.removeNode(sibling);
12045 continue;
12046 }
12047 if (sibling && sibling.type === 9 /* IF */) {
12048 // move the node to the if node's branches
12049 context.removeNode();
12050 const branch = createIfBranch(node, dir);
12051 if (comments.length) {
12052 branch.children = [...comments, ...branch.children];
12053 }
12054 // check if user is forcing same key on different branches
12055 {
12056 const key = branch.userKey;
12057 if (key) {
12058 sibling.branches.forEach(({ userKey }) => {
12059 if (isSameKey(userKey, key)) {
12060 context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
12061 }
12062 });
12063 }
12064 }
12065 sibling.branches.push(branch);
12066 const onExit = processCodegen && processCodegen(sibling, branch, false);
12067 // since the branch was removed, it will not be traversed.
12068 // make sure to traverse here.
12069 traverseNode(branch, context);
12070 // call on exit
12071 if (onExit)
12072 onExit();
12073 // make sure to reset currentNode after traversal to indicate this
12074 // node has been removed.
12075 context.currentNode = null;
12076 }
12077 else {
12078 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
12079 }
12080 break;
12081 }
12082 }
12083}
12084function createIfBranch(node, dir) {
12085 return {
12086 type: 10 /* IF_BRANCH */,
12087 loc: node.loc,
12088 condition: dir.name === 'else' ? undefined : dir.exp,
12089 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
12090 ? node.children
12091 : [node],
12092 userKey: findProp(node, `key`)
12093 };
12094}
12095function createCodegenNodeForBranch(branch, keyIndex, context) {
12096 if (branch.condition) {
12097 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
12098 // make sure to pass in asBlock: true so that the comment node call
12099 // closes the current block.
12100 createCallExpression(context.helper(CREATE_COMMENT), [
12101 '"v-if"' ,
12102 'true'
12103 ]));
12104 }
12105 else {
12106 return createChildrenCodegenNode(branch, keyIndex, context);
12107 }
12108}
12109function createChildrenCodegenNode(branch, keyIndex, context) {
12110 const { helper, removeHelper } = context;
12111 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
12112 const { children } = branch;
12113 const firstChild = children[0];
12114 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
12115 if (needFragmentWrapper) {
12116 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
12117 // optimize away nested fragments when child is a ForNode
12118 const vnodeCall = firstChild.codegenNode;
12119 injectProp(vnodeCall, keyProperty, context);
12120 return vnodeCall;
12121 }
12122 else {
12123 let patchFlag = 64 /* STABLE_FRAGMENT */;
12124 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
12125 // check if the fragment actually contains a single valid child with
12126 // the rest being comments
12127 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
12128 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
12129 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
12130 }
12131 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, branch.loc);
12132 }
12133 }
12134 else {
12135 const vnodeCall = firstChild
12136 .codegenNode;
12137 // Change createVNode to createBlock.
12138 if (vnodeCall.type === 13 /* VNODE_CALL */ && !vnodeCall.isBlock) {
12139 removeHelper(CREATE_VNODE);
12140 vnodeCall.isBlock = true;
12141 helper(OPEN_BLOCK);
12142 helper(CREATE_BLOCK);
12143 }
12144 // inject branch key
12145 injectProp(vnodeCall, keyProperty, context);
12146 return vnodeCall;
12147 }
12148}
12149function isSameKey(a, b) {
12150 if (!a || a.type !== b.type) {
12151 return false;
12152 }
12153 if (a.type === 6 /* ATTRIBUTE */) {
12154 if (a.value.content !== b.value.content) {
12155 return false;
12156 }
12157 }
12158 else {
12159 // directive
12160 const exp = a.exp;
12161 const branchExp = b.exp;
12162 if (exp.type !== branchExp.type) {
12163 return false;
12164 }
12165 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
12166 (exp.isStatic !== branchExp.isStatic ||
12167 exp.content !== branchExp.content)) {
12168 return false;
12169 }
12170 }
12171 return true;
12172}
12173function getParentCondition(node) {
12174 while (true) {
12175 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12176 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12177 node = node.alternate;
12178 }
12179 else {
12180 return node;
12181 }
12182 }
12183 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
12184 node = node.value;
12185 }
12186 }
12187}
12188
12189const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
12190 const { helper, removeHelper } = context;
12191 return processFor(node, dir, context, forNode => {
12192 // create the loop render function expression now, and add the
12193 // iterator on exit after all children have been traversed
12194 const renderExp = createCallExpression(helper(RENDER_LIST), [
12195 forNode.source
12196 ]);
12197 const keyProp = findProp(node, `key`);
12198 const keyProperty = keyProp
12199 ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */
12200 ? createSimpleExpression(keyProp.value.content, true)
12201 : keyProp.exp)
12202 : null;
12203 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
12204 forNode.source.constType > 0 /* NOT_CONSTANT */;
12205 const fragmentFlag = isStableFragment
12206 ? 64 /* STABLE_FRAGMENT */
12207 : keyProp
12208 ? 128 /* KEYED_FRAGMENT */
12209 : 256 /* UNKEYED_FRAGMENT */;
12210 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
12211 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);
12212 return () => {
12213 // finish the codegen now that all children have been traversed
12214 let childBlock;
12215 const isTemplate = isTemplateNode(node);
12216 const { children } = forNode;
12217 // check <template v-for> key placement
12218 if (isTemplate) {
12219 node.children.some(c => {
12220 if (c.type === 1 /* ELEMENT */) {
12221 const key = findProp(c, 'key');
12222 if (key) {
12223 context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
12224 return true;
12225 }
12226 }
12227 });
12228 }
12229 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
12230 const slotOutlet = isSlotOutlet(node)
12231 ? node
12232 : isTemplate &&
12233 node.children.length === 1 &&
12234 isSlotOutlet(node.children[0])
12235 ? node.children[0] // api-extractor somehow fails to infer this
12236 : null;
12237 if (slotOutlet) {
12238 // <slot v-for="..."> or <template v-for="..."><slot/></template>
12239 childBlock = slotOutlet.codegenNode;
12240 if (isTemplate && keyProperty) {
12241 // <template v-for="..." :key="..."><slot/></template>
12242 // we need to inject the key to the renderSlot() call.
12243 // the props for renderSlot is passed as the 3rd argument.
12244 injectProp(childBlock, keyProperty, context);
12245 }
12246 }
12247 else if (needFragmentWrapper) {
12248 // <template v-for="..."> with text or multi-elements
12249 // should generate a fragment block for each loop
12250 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
12251 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
12252 ), undefined, undefined, true);
12253 }
12254 else {
12255 // Normal element v-for. Directly use the child's codegenNode
12256 // but mark it as a block.
12257 childBlock = children[0]
12258 .codegenNode;
12259 if (isTemplate && keyProperty) {
12260 injectProp(childBlock, keyProperty, context);
12261 }
12262 if (childBlock.isBlock !== !isStableFragment) {
12263 if (childBlock.isBlock) {
12264 // switch from block to vnode
12265 removeHelper(OPEN_BLOCK);
12266 removeHelper(CREATE_BLOCK);
12267 }
12268 else {
12269 // switch from vnode to block
12270 removeHelper(CREATE_VNODE);
12271 }
12272 }
12273 childBlock.isBlock = !isStableFragment;
12274 if (childBlock.isBlock) {
12275 helper(OPEN_BLOCK);
12276 helper(CREATE_BLOCK);
12277 }
12278 else {
12279 helper(CREATE_VNODE);
12280 }
12281 }
12282 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
12283 };
12284 });
12285});
12286// target-agnostic transform used for both Client and SSR
12287function processFor(node, dir, context, processCodegen) {
12288 if (!dir.exp) {
12289 context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
12290 return;
12291 }
12292 const parseResult = parseForExpression(
12293 // can only be simple expression because vFor transform is applied
12294 // before expression transform.
12295 dir.exp, context);
12296 if (!parseResult) {
12297 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
12298 return;
12299 }
12300 const { addIdentifiers, removeIdentifiers, scopes } = context;
12301 const { source, value, key, index } = parseResult;
12302 const forNode = {
12303 type: 11 /* FOR */,
12304 loc: dir.loc,
12305 source,
12306 valueAlias: value,
12307 keyAlias: key,
12308 objectIndexAlias: index,
12309 parseResult,
12310 children: isTemplateNode(node) ? node.children : [node]
12311 };
12312 context.replaceNode(forNode);
12313 // bookkeeping
12314 scopes.vFor++;
12315 const onExit = processCodegen && processCodegen(forNode);
12316 return () => {
12317 scopes.vFor--;
12318 if (onExit)
12319 onExit();
12320 };
12321}
12322const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
12323// This regex doesn't cover the case if key or index aliases have destructuring,
12324// but those do not make sense in the first place, so this works in practice.
12325const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
12326const stripParensRE = /^\(|\)$/g;
12327function parseForExpression(input, context) {
12328 const loc = input.loc;
12329 const exp = input.content;
12330 const inMatch = exp.match(forAliasRE);
12331 if (!inMatch)
12332 return;
12333 const [, LHS, RHS] = inMatch;
12334 const result = {
12335 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
12336 value: undefined,
12337 key: undefined,
12338 index: undefined
12339 };
12340 {
12341 validateBrowserExpression(result.source, context);
12342 }
12343 let valueContent = LHS.trim()
12344 .replace(stripParensRE, '')
12345 .trim();
12346 const trimmedOffset = LHS.indexOf(valueContent);
12347 const iteratorMatch = valueContent.match(forIteratorRE);
12348 if (iteratorMatch) {
12349 valueContent = valueContent.replace(forIteratorRE, '').trim();
12350 const keyContent = iteratorMatch[1].trim();
12351 let keyOffset;
12352 if (keyContent) {
12353 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
12354 result.key = createAliasExpression(loc, keyContent, keyOffset);
12355 {
12356 validateBrowserExpression(result.key, context, true);
12357 }
12358 }
12359 if (iteratorMatch[2]) {
12360 const indexContent = iteratorMatch[2].trim();
12361 if (indexContent) {
12362 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
12363 ? keyOffset + keyContent.length
12364 : trimmedOffset + valueContent.length));
12365 {
12366 validateBrowserExpression(result.index, context, true);
12367 }
12368 }
12369 }
12370 }
12371 if (valueContent) {
12372 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
12373 {
12374 validateBrowserExpression(result.value, context, true);
12375 }
12376 }
12377 return result;
12378}
12379function createAliasExpression(range, content, offset) {
12380 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
12381}
12382function createForLoopParams({ value, key, index }) {
12383 const params = [];
12384 if (value) {
12385 params.push(value);
12386 }
12387 if (key) {
12388 if (!value) {
12389 params.push(createSimpleExpression(`_`, false));
12390 }
12391 params.push(key);
12392 }
12393 if (index) {
12394 if (!key) {
12395 if (!value) {
12396 params.push(createSimpleExpression(`_`, false));
12397 }
12398 params.push(createSimpleExpression(`__`, false));
12399 }
12400 params.push(index);
12401 }
12402 return params;
12403}
12404
12405const defaultFallback = createSimpleExpression(`undefined`, false);
12406// A NodeTransform that:
12407// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
12408// by transformExpression. This is only applied in non-browser builds with
12409// { prefixIdentifiers: true }.
12410// 2. Track v-slot depths so that we know a slot is inside another slot.
12411// Note the exit callback is executed before buildSlots() on the same node,
12412// so only nested slots see positive numbers.
12413const trackSlotScopes = (node, context) => {
12414 if (node.type === 1 /* ELEMENT */ &&
12415 (node.tagType === 1 /* COMPONENT */ ||
12416 node.tagType === 3 /* TEMPLATE */)) {
12417 // We are only checking non-empty v-slot here
12418 // since we only care about slots that introduce scope variables.
12419 const vSlot = findDir(node, 'slot');
12420 if (vSlot) {
12421 vSlot.exp;
12422 context.scopes.vSlot++;
12423 return () => {
12424 context.scopes.vSlot--;
12425 };
12426 }
12427 }
12428};
12429const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
12430// Instead of being a DirectiveTransform, v-slot processing is called during
12431// transformElement to build the slots object for a component.
12432function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
12433 context.helper(WITH_CTX);
12434 const { children, loc } = node;
12435 const slotsProperties = [];
12436 const dynamicSlots = [];
12437 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));
12438 // If the slot is inside a v-for or another v-slot, force it to be dynamic
12439 // since it likely uses a scope variable.
12440 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
12441 // 1. Check for slot with slotProps on component itself.
12442 // <Comp v-slot="{ prop }"/>
12443 const onComponentSlot = findDir(node, 'slot', true);
12444 if (onComponentSlot) {
12445 const { arg, exp } = onComponentSlot;
12446 if (arg && !isStaticExp(arg)) {
12447 hasDynamicSlots = true;
12448 }
12449 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
12450 }
12451 // 2. Iterate through children and check for template slots
12452 // <template v-slot:foo="{ prop }">
12453 let hasTemplateSlots = false;
12454 let hasNamedDefaultSlot = false;
12455 const implicitDefaultChildren = [];
12456 const seenSlotNames = new Set();
12457 for (let i = 0; i < children.length; i++) {
12458 const slotElement = children[i];
12459 let slotDir;
12460 if (!isTemplateNode(slotElement) ||
12461 !(slotDir = findDir(slotElement, 'slot', true))) {
12462 // not a <template v-slot>, skip.
12463 if (slotElement.type !== 3 /* COMMENT */) {
12464 implicitDefaultChildren.push(slotElement);
12465 }
12466 continue;
12467 }
12468 if (onComponentSlot) {
12469 // already has on-component slot - this is incorrect usage.
12470 context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
12471 break;
12472 }
12473 hasTemplateSlots = true;
12474 const { children: slotChildren, loc: slotLoc } = slotElement;
12475 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
12476 // check if name is dynamic.
12477 let staticSlotName;
12478 if (isStaticExp(slotName)) {
12479 staticSlotName = slotName ? slotName.content : `default`;
12480 }
12481 else {
12482 hasDynamicSlots = true;
12483 }
12484 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
12485 // check if this slot is conditional (v-if/v-for)
12486 let vIf;
12487 let vElse;
12488 let vFor;
12489 if ((vIf = findDir(slotElement, 'if'))) {
12490 hasDynamicSlots = true;
12491 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
12492 }
12493 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
12494 // find adjacent v-if
12495 let j = i;
12496 let prev;
12497 while (j--) {
12498 prev = children[j];
12499 if (prev.type !== 3 /* COMMENT */) {
12500 break;
12501 }
12502 }
12503 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
12504 // remove node
12505 children.splice(i, 1);
12506 i--;
12507 // attach this slot to previous conditional
12508 let conditional = dynamicSlots[dynamicSlots.length - 1];
12509 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12510 conditional = conditional.alternate;
12511 }
12512 conditional.alternate = vElse.exp
12513 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
12514 : buildDynamicSlot(slotName, slotFunction);
12515 }
12516 else {
12517 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
12518 }
12519 }
12520 else if ((vFor = findDir(slotElement, 'for'))) {
12521 hasDynamicSlots = true;
12522 const parseResult = vFor.parseResult ||
12523 parseForExpression(vFor.exp, context);
12524 if (parseResult) {
12525 // Render the dynamic slots as an array and add it to the createSlot()
12526 // args. The runtime knows how to handle it appropriately.
12527 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
12528 parseResult.source,
12529 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
12530 ]));
12531 }
12532 else {
12533 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
12534 }
12535 }
12536 else {
12537 // check duplicate static names
12538 if (staticSlotName) {
12539 if (seenSlotNames.has(staticSlotName)) {
12540 context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
12541 continue;
12542 }
12543 seenSlotNames.add(staticSlotName);
12544 if (staticSlotName === 'default') {
12545 hasNamedDefaultSlot = true;
12546 }
12547 }
12548 slotsProperties.push(createObjectProperty(slotName, slotFunction));
12549 }
12550 }
12551 if (!onComponentSlot) {
12552 if (!hasTemplateSlots) {
12553 // implicit default slot (on component)
12554 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
12555 }
12556 else if (implicitDefaultChildren.length) {
12557 // implicit default slot (mixed with named slots)
12558 if (hasNamedDefaultSlot) {
12559 context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
12560 }
12561 else {
12562 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
12563 }
12564 }
12565 }
12566 const slotFlag = hasDynamicSlots
12567 ? 2 /* DYNAMIC */
12568 : hasForwardedSlots(node.children)
12569 ? 3 /* FORWARDED */
12570 : 1 /* STABLE */;
12571 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
12572 // 2 = compiled but dynamic = can skip normalization, but must run diff
12573 // 1 = compiled and static = can skip normalization AND diff as optimized
12574 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
12575 if (dynamicSlots.length) {
12576 slots = createCallExpression(context.helper(CREATE_SLOTS), [
12577 slots,
12578 createArrayExpression(dynamicSlots)
12579 ]);
12580 }
12581 return {
12582 slots,
12583 hasDynamicSlots
12584 };
12585}
12586function buildDynamicSlot(name, fn) {
12587 return createObjectExpression([
12588 createObjectProperty(`name`, name),
12589 createObjectProperty(`fn`, fn)
12590 ]);
12591}
12592function hasForwardedSlots(children) {
12593 for (let i = 0; i < children.length; i++) {
12594 const child = children[i];
12595 switch (child.type) {
12596 case 1 /* ELEMENT */:
12597 if (child.tagType === 2 /* SLOT */ ||
12598 (child.tagType === 0 /* ELEMENT */ &&
12599 hasForwardedSlots(child.children))) {
12600 return true;
12601 }
12602 break;
12603 case 9 /* IF */:
12604 if (hasForwardedSlots(child.branches))
12605 return true;
12606 break;
12607 case 10 /* IF_BRANCH */:
12608 case 11 /* FOR */:
12609 if (hasForwardedSlots(child.children))
12610 return true;
12611 break;
12612 }
12613 }
12614 return false;
12615}
12616
12617// some directive transforms (e.g. v-model) may return a symbol for runtime
12618// import, which should be used instead of a resolveDirective call.
12619const directiveImportMap = new WeakMap();
12620// generate a JavaScript AST for this element's codegen
12621const transformElement = (node, context) => {
12622 // perform the work on exit, after all child expressions have been
12623 // processed and merged.
12624 return function postTransformElement() {
12625 node = context.currentNode;
12626 if (!(node.type === 1 /* ELEMENT */ &&
12627 (node.tagType === 0 /* ELEMENT */ ||
12628 node.tagType === 1 /* COMPONENT */))) {
12629 return;
12630 }
12631 const { tag, props } = node;
12632 const isComponent = node.tagType === 1 /* COMPONENT */;
12633 // The goal of the transform is to create a codegenNode implementing the
12634 // VNodeCall interface.
12635 const vnodeTag = isComponent
12636 ? resolveComponentType(node, context)
12637 : `"${tag}"`;
12638 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
12639 let vnodeProps;
12640 let vnodeChildren;
12641 let vnodePatchFlag;
12642 let patchFlag = 0;
12643 let vnodeDynamicProps;
12644 let dynamicPropNames;
12645 let vnodeDirectives;
12646 let shouldUseBlock =
12647 // dynamic component may resolve to plain elements
12648 isDynamicComponent ||
12649 vnodeTag === TELEPORT ||
12650 vnodeTag === SUSPENSE ||
12651 (!isComponent &&
12652 // <svg> and <foreignObject> must be forced into blocks so that block
12653 // updates inside get proper isSVG flag at runtime. (#639, #643)
12654 // This is technically web-specific, but splitting the logic out of core
12655 // leads to too much unnecessary complexity.
12656 (tag === 'svg' ||
12657 tag === 'foreignObject' ||
12658 // #938: elements with dynamic keys should be forced into blocks
12659 findProp(node, 'key', true)));
12660 // props
12661 if (props.length > 0) {
12662 const propsBuildResult = buildProps(node, context);
12663 vnodeProps = propsBuildResult.props;
12664 patchFlag = propsBuildResult.patchFlag;
12665 dynamicPropNames = propsBuildResult.dynamicPropNames;
12666 const directives = propsBuildResult.directives;
12667 vnodeDirectives =
12668 directives && directives.length
12669 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
12670 : undefined;
12671 }
12672 // children
12673 if (node.children.length > 0) {
12674 if (vnodeTag === KEEP_ALIVE) {
12675 // Although a built-in component, we compile KeepAlive with raw children
12676 // instead of slot functions so that it can be used inside Transition
12677 // or other Transition-wrapping HOCs.
12678 // To ensure correct updates with block optimizations, we need to:
12679 // 1. Force keep-alive into a block. This avoids its children being
12680 // collected by a parent block.
12681 shouldUseBlock = true;
12682 // 2. Force keep-alive to always be updated, since it uses raw children.
12683 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
12684 if (node.children.length > 1) {
12685 context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
12686 start: node.children[0].loc.start,
12687 end: node.children[node.children.length - 1].loc.end,
12688 source: ''
12689 }));
12690 }
12691 }
12692 const shouldBuildAsSlots = isComponent &&
12693 // Teleport is not a real component and has dedicated runtime handling
12694 vnodeTag !== TELEPORT &&
12695 // explained above.
12696 vnodeTag !== KEEP_ALIVE;
12697 if (shouldBuildAsSlots) {
12698 const { slots, hasDynamicSlots } = buildSlots(node, context);
12699 vnodeChildren = slots;
12700 if (hasDynamicSlots) {
12701 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
12702 }
12703 }
12704 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
12705 const child = node.children[0];
12706 const type = child.type;
12707 // check for dynamic text children
12708 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
12709 type === 8 /* COMPOUND_EXPRESSION */;
12710 if (hasDynamicTextChild &&
12711 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
12712 patchFlag |= 1 /* TEXT */;
12713 }
12714 // pass directly if the only child is a text node
12715 // (plain / interpolation / expression)
12716 if (hasDynamicTextChild || type === 2 /* TEXT */) {
12717 vnodeChildren = child;
12718 }
12719 else {
12720 vnodeChildren = node.children;
12721 }
12722 }
12723 else {
12724 vnodeChildren = node.children;
12725 }
12726 }
12727 // patchFlag & dynamicPropNames
12728 if (patchFlag !== 0) {
12729 {
12730 if (patchFlag < 0) {
12731 // special flags (negative and mutually exclusive)
12732 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
12733 }
12734 else {
12735 // bitwise flags
12736 const flagNames = Object.keys(PatchFlagNames)
12737 .map(Number)
12738 .filter(n => n > 0 && patchFlag & n)
12739 .map(n => PatchFlagNames[n])
12740 .join(`, `);
12741 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
12742 }
12743 }
12744 if (dynamicPropNames && dynamicPropNames.length) {
12745 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
12746 }
12747 }
12748 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);
12749 };
12750};
12751function resolveComponentType(node, context, ssr = false) {
12752 const { tag } = node;
12753 // 1. dynamic component
12754 const isProp = isComponentTag(tag)
12755 ? findProp(node, 'is')
12756 : findDir(node, 'is');
12757 if (isProp) {
12758 const exp = isProp.type === 6 /* ATTRIBUTE */
12759 ? isProp.value && createSimpleExpression(isProp.value.content, true)
12760 : isProp.exp;
12761 if (exp) {
12762 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
12763 exp
12764 ]);
12765 }
12766 }
12767 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
12768 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
12769 if (builtIn) {
12770 // built-ins are simply fallthroughs / have special handling during ssr
12771 // so we don't need to import their runtime equivalents
12772 if (!ssr)
12773 context.helper(builtIn);
12774 return builtIn;
12775 }
12776 // 5. user component (resolve)
12777 context.helper(RESOLVE_COMPONENT);
12778 context.components.add(tag);
12779 return toValidAssetId(tag, `component`);
12780}
12781function buildProps(node, context, props = node.props, ssr = false) {
12782 const { tag, loc: elementLoc } = node;
12783 const isComponent = node.tagType === 1 /* COMPONENT */;
12784 let properties = [];
12785 const mergeArgs = [];
12786 const runtimeDirectives = [];
12787 // patchFlag analysis
12788 let patchFlag = 0;
12789 let hasRef = false;
12790 let hasClassBinding = false;
12791 let hasStyleBinding = false;
12792 let hasHydrationEventBinding = false;
12793 let hasDynamicKeys = false;
12794 let hasVnodeHook = false;
12795 const dynamicPropNames = [];
12796 const analyzePatchFlag = ({ key, value }) => {
12797 if (isStaticExp(key)) {
12798 const name = key.content;
12799 const isEventHandler = isOn(name);
12800 if (!isComponent &&
12801 isEventHandler &&
12802 // omit the flag for click handlers because hydration gives click
12803 // dedicated fast path.
12804 name.toLowerCase() !== 'onclick' &&
12805 // omit v-model handlers
12806 name !== 'onUpdate:modelValue' &&
12807 // omit onVnodeXXX hooks
12808 !isReservedProp(name)) {
12809 hasHydrationEventBinding = true;
12810 }
12811 if (isEventHandler && isReservedProp(name)) {
12812 hasVnodeHook = true;
12813 }
12814 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
12815 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
12816 value.type === 8 /* COMPOUND_EXPRESSION */) &&
12817 getConstantType(value, context) > 0)) {
12818 // skip if the prop is a cached handler or has constant value
12819 return;
12820 }
12821 if (name === 'ref') {
12822 hasRef = true;
12823 }
12824 else if (name === 'class' && !isComponent) {
12825 hasClassBinding = true;
12826 }
12827 else if (name === 'style' && !isComponent) {
12828 hasStyleBinding = true;
12829 }
12830 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
12831 dynamicPropNames.push(name);
12832 }
12833 }
12834 else {
12835 hasDynamicKeys = true;
12836 }
12837 };
12838 for (let i = 0; i < props.length; i++) {
12839 // static attribute
12840 const prop = props[i];
12841 if (prop.type === 6 /* ATTRIBUTE */) {
12842 const { loc, name, value } = prop;
12843 let isStatic = true;
12844 if (name === 'ref') {
12845 hasRef = true;
12846 }
12847 // skip :is on <component>
12848 if (name === 'is' && isComponentTag(tag)) {
12849 continue;
12850 }
12851 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
12852 }
12853 else {
12854 // directives
12855 const { name, arg, exp, loc } = prop;
12856 const isBind = name === 'bind';
12857 const isOn = name === 'on';
12858 // skip v-slot - it is handled by its dedicated transform.
12859 if (name === 'slot') {
12860 if (!isComponent) {
12861 context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));
12862 }
12863 continue;
12864 }
12865 // skip v-once - it is handled by its dedicated transform.
12866 if (name === 'once') {
12867 continue;
12868 }
12869 // skip v-is and :is on <component>
12870 if (name === 'is' ||
12871 (isBind && isComponentTag(tag) && isBindKey(arg, 'is'))) {
12872 continue;
12873 }
12874 // skip v-on in SSR compilation
12875 if (isOn && ssr) {
12876 continue;
12877 }
12878 // special case for v-bind and v-on with no argument
12879 if (!arg && (isBind || isOn)) {
12880 hasDynamicKeys = true;
12881 if (exp) {
12882 if (properties.length) {
12883 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
12884 properties = [];
12885 }
12886 if (isBind) {
12887 mergeArgs.push(exp);
12888 }
12889 else {
12890 // v-on="obj" -> toHandlers(obj)
12891 mergeArgs.push({
12892 type: 14 /* JS_CALL_EXPRESSION */,
12893 loc,
12894 callee: context.helper(TO_HANDLERS),
12895 arguments: [exp]
12896 });
12897 }
12898 }
12899 else {
12900 context.onError(createCompilerError(isBind
12901 ? 33 /* X_V_BIND_NO_EXPRESSION */
12902 : 34 /* X_V_ON_NO_EXPRESSION */, loc));
12903 }
12904 continue;
12905 }
12906 const directiveTransform = context.directiveTransforms[name];
12907 if (directiveTransform) {
12908 // has built-in directive transform.
12909 const { props, needRuntime } = directiveTransform(prop, node, context);
12910 !ssr && props.forEach(analyzePatchFlag);
12911 properties.push(...props);
12912 if (needRuntime) {
12913 runtimeDirectives.push(prop);
12914 if (isSymbol(needRuntime)) {
12915 directiveImportMap.set(prop, needRuntime);
12916 }
12917 }
12918 }
12919 else {
12920 // no built-in transform, this is a user custom directive.
12921 runtimeDirectives.push(prop);
12922 }
12923 }
12924 }
12925 let propsExpression = undefined;
12926 // has v-bind="object" or v-on="object", wrap with mergeProps
12927 if (mergeArgs.length) {
12928 if (properties.length) {
12929 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
12930 }
12931 if (mergeArgs.length > 1) {
12932 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
12933 }
12934 else {
12935 // single v-bind with nothing else - no need for a mergeProps call
12936 propsExpression = mergeArgs[0];
12937 }
12938 }
12939 else if (properties.length) {
12940 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
12941 }
12942 // patchFlag analysis
12943 if (hasDynamicKeys) {
12944 patchFlag |= 16 /* FULL_PROPS */;
12945 }
12946 else {
12947 if (hasClassBinding) {
12948 patchFlag |= 2 /* CLASS */;
12949 }
12950 if (hasStyleBinding) {
12951 patchFlag |= 4 /* STYLE */;
12952 }
12953 if (dynamicPropNames.length) {
12954 patchFlag |= 8 /* PROPS */;
12955 }
12956 if (hasHydrationEventBinding) {
12957 patchFlag |= 32 /* HYDRATE_EVENTS */;
12958 }
12959 }
12960 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
12961 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
12962 patchFlag |= 512 /* NEED_PATCH */;
12963 }
12964 return {
12965 props: propsExpression,
12966 directives: runtimeDirectives,
12967 patchFlag,
12968 dynamicPropNames
12969 };
12970}
12971// Dedupe props in an object literal.
12972// Literal duplicated attributes would have been warned during the parse phase,
12973// however, it's possible to encounter duplicated `onXXX` handlers with different
12974// modifiers. We also need to merge static and dynamic class / style attributes.
12975// - onXXX handlers / style: merge into array
12976// - class: merge into single expression with concatenation
12977function dedupeProperties(properties) {
12978 const knownProps = new Map();
12979 const deduped = [];
12980 for (let i = 0; i < properties.length; i++) {
12981 const prop = properties[i];
12982 // dynamic keys are always allowed
12983 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
12984 deduped.push(prop);
12985 continue;
12986 }
12987 const name = prop.key.content;
12988 const existing = knownProps.get(name);
12989 if (existing) {
12990 if (name === 'style' || name === 'class' || name.startsWith('on')) {
12991 mergeAsArray(existing, prop);
12992 }
12993 // unexpected duplicate, should have emitted error during parse
12994 }
12995 else {
12996 knownProps.set(name, prop);
12997 deduped.push(prop);
12998 }
12999 }
13000 return deduped;
13001}
13002function mergeAsArray(existing, incoming) {
13003 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
13004 existing.value.elements.push(incoming.value);
13005 }
13006 else {
13007 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
13008 }
13009}
13010function buildDirectiveArgs(dir, context) {
13011 const dirArgs = [];
13012 const runtime = directiveImportMap.get(dir);
13013 if (runtime) {
13014 // built-in directive with runtime
13015 dirArgs.push(context.helperString(runtime));
13016 }
13017 else {
13018 {
13019 // inject statement for resolving directive
13020 context.helper(RESOLVE_DIRECTIVE);
13021 context.directives.add(dir.name);
13022 dirArgs.push(toValidAssetId(dir.name, `directive`));
13023 }
13024 }
13025 const { loc } = dir;
13026 if (dir.exp)
13027 dirArgs.push(dir.exp);
13028 if (dir.arg) {
13029 if (!dir.exp) {
13030 dirArgs.push(`void 0`);
13031 }
13032 dirArgs.push(dir.arg);
13033 }
13034 if (Object.keys(dir.modifiers).length) {
13035 if (!dir.arg) {
13036 if (!dir.exp) {
13037 dirArgs.push(`void 0`);
13038 }
13039 dirArgs.push(`void 0`);
13040 }
13041 const trueExpression = createSimpleExpression(`true`, false, loc);
13042 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
13043 }
13044 return createArrayExpression(dirArgs, dir.loc);
13045}
13046function stringifyDynamicPropNames(props) {
13047 let propsNamesString = `[`;
13048 for (let i = 0, l = props.length; i < l; i++) {
13049 propsNamesString += JSON.stringify(props[i]);
13050 if (i < l - 1)
13051 propsNamesString += ', ';
13052 }
13053 return propsNamesString + `]`;
13054}
13055function isComponentTag(tag) {
13056 return tag[0].toLowerCase() + tag.slice(1) === 'component';
13057}
13058
13059const transformSlotOutlet = (node, context) => {
13060 if (isSlotOutlet(node)) {
13061 const { children, loc } = node;
13062 const { slotName, slotProps } = processSlotOutlet(node, context);
13063 const slotArgs = [
13064 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
13065 slotName
13066 ];
13067 if (slotProps) {
13068 slotArgs.push(slotProps);
13069 }
13070 if (children.length) {
13071 if (!slotProps) {
13072 slotArgs.push(`{}`);
13073 }
13074 slotArgs.push(createFunctionExpression([], children, false, false, loc));
13075 }
13076 if (context.scopeId && !context.slotted) {
13077 if (!slotProps) {
13078 slotArgs.push(`{}`);
13079 }
13080 if (!children.length) {
13081 slotArgs.push(`undefined`);
13082 }
13083 slotArgs.push(`true`);
13084 }
13085 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
13086 }
13087};
13088function processSlotOutlet(node, context) {
13089 let slotName = `"default"`;
13090 let slotProps = undefined;
13091 const nonNameProps = [];
13092 for (let i = 0; i < node.props.length; i++) {
13093 const p = node.props[i];
13094 if (p.type === 6 /* ATTRIBUTE */) {
13095 if (p.value) {
13096 if (p.name === 'name') {
13097 slotName = JSON.stringify(p.value.content);
13098 }
13099 else {
13100 p.name = camelize(p.name);
13101 nonNameProps.push(p);
13102 }
13103 }
13104 }
13105 else {
13106 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
13107 if (p.exp)
13108 slotName = p.exp;
13109 }
13110 else {
13111 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
13112 p.arg.content = camelize(p.arg.content);
13113 }
13114 nonNameProps.push(p);
13115 }
13116 }
13117 }
13118 if (nonNameProps.length > 0) {
13119 const { props, directives } = buildProps(node, context, nonNameProps);
13120 slotProps = props;
13121 if (directives.length) {
13122 context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
13123 }
13124 }
13125 return {
13126 slotName,
13127 slotProps
13128 };
13129}
13130
13131const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;
13132const transformOn = (dir, node, context, augmentor) => {
13133 const { loc, modifiers, arg } = dir;
13134 if (!dir.exp && !modifiers.length) {
13135 context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));
13136 }
13137 let eventName;
13138 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13139 if (arg.isStatic) {
13140 const rawName = arg.content;
13141 // for all event listeners, auto convert it to camelCase. See issue #2249
13142 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
13143 }
13144 else {
13145 // #2388
13146 eventName = createCompoundExpression([
13147 `${context.helperString(TO_HANDLER_KEY)}(`,
13148 arg,
13149 `)`
13150 ]);
13151 }
13152 }
13153 else {
13154 // already a compound expression.
13155 eventName = arg;
13156 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
13157 eventName.children.push(`)`);
13158 }
13159 // handler processing
13160 let exp = dir.exp;
13161 if (exp && !exp.content.trim()) {
13162 exp = undefined;
13163 }
13164 let shouldCache = context.cacheHandlers && !exp;
13165 if (exp) {
13166 const isMemberExp = isMemberExpression(exp.content);
13167 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
13168 const hasMultipleStatements = exp.content.includes(`;`);
13169 {
13170 validateBrowserExpression(exp, context, false, hasMultipleStatements);
13171 }
13172 if (isInlineStatement || (shouldCache && isMemberExp)) {
13173 // wrap inline statement in a function expression
13174 exp = createCompoundExpression([
13175 `${isInlineStatement
13176 ? `$event`
13177 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
13178 exp,
13179 hasMultipleStatements ? `}` : `)`
13180 ]);
13181 }
13182 }
13183 let ret = {
13184 props: [
13185 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
13186 ]
13187 };
13188 // apply extended compiler augmentor
13189 if (augmentor) {
13190 ret = augmentor(ret);
13191 }
13192 if (shouldCache) {
13193 // cache handlers so that it's always the same handler being passed down.
13194 // this avoids unnecessary re-renders when users use inline handlers on
13195 // components.
13196 ret.props[0].value = context.cache(ret.props[0].value);
13197 }
13198 return ret;
13199};
13200
13201// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
13202// codegen for the entire props object. This transform here is only for v-bind
13203// *with* args.
13204const transformBind = (dir, node, context) => {
13205 const { exp, modifiers, loc } = dir;
13206 const arg = dir.arg;
13207 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
13208 arg.children.unshift(`(`);
13209 arg.children.push(`) || ""`);
13210 }
13211 else if (!arg.isStatic) {
13212 arg.content = `${arg.content} || ""`;
13213 }
13214 // .prop is no longer necessary due to new patch behavior
13215 // .sync is replaced by v-model:arg
13216 if (modifiers.includes('camel')) {
13217 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13218 if (arg.isStatic) {
13219 arg.content = camelize(arg.content);
13220 }
13221 else {
13222 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
13223 }
13224 }
13225 else {
13226 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
13227 arg.children.push(`)`);
13228 }
13229 }
13230 if (!exp ||
13231 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
13232 context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));
13233 return {
13234 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
13235 };
13236 }
13237 return {
13238 props: [createObjectProperty(arg, exp)]
13239 };
13240};
13241
13242// Merge adjacent text nodes and expressions into a single expression
13243// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
13244const transformText = (node, context) => {
13245 if (node.type === 0 /* ROOT */ ||
13246 node.type === 1 /* ELEMENT */ ||
13247 node.type === 11 /* FOR */ ||
13248 node.type === 10 /* IF_BRANCH */) {
13249 // perform the transform on node exit so that all expressions have already
13250 // been processed.
13251 return () => {
13252 const children = node.children;
13253 let currentContainer = undefined;
13254 let hasText = false;
13255 for (let i = 0; i < children.length; i++) {
13256 const child = children[i];
13257 if (isText(child)) {
13258 hasText = true;
13259 for (let j = i + 1; j < children.length; j++) {
13260 const next = children[j];
13261 if (isText(next)) {
13262 if (!currentContainer) {
13263 currentContainer = children[i] = {
13264 type: 8 /* COMPOUND_EXPRESSION */,
13265 loc: child.loc,
13266 children: [child]
13267 };
13268 }
13269 // merge adjacent text node into current
13270 currentContainer.children.push(` + `, next);
13271 children.splice(j, 1);
13272 j--;
13273 }
13274 else {
13275 currentContainer = undefined;
13276 break;
13277 }
13278 }
13279 }
13280 }
13281 if (!hasText ||
13282 // if this is a plain element with a single text child, leave it
13283 // as-is since the runtime has dedicated fast path for this by directly
13284 // setting textContent of the element.
13285 // for component root it's always normalized anyway.
13286 (children.length === 1 &&
13287 (node.type === 0 /* ROOT */ ||
13288 (node.type === 1 /* ELEMENT */ &&
13289 node.tagType === 0 /* ELEMENT */)))) {
13290 return;
13291 }
13292 // pre-convert text nodes into createTextVNode(text) calls to avoid
13293 // runtime normalization.
13294 for (let i = 0; i < children.length; i++) {
13295 const child = children[i];
13296 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
13297 const callArgs = [];
13298 // createTextVNode defaults to single whitespace, so if it is a
13299 // single space the code could be an empty call to save bytes.
13300 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
13301 callArgs.push(child);
13302 }
13303 // mark dynamic text with flag so it gets patched inside a block
13304 if (!context.ssr &&
13305 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
13306 callArgs.push(1 /* TEXT */ +
13307 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
13308 }
13309 children[i] = {
13310 type: 12 /* TEXT_CALL */,
13311 content: child,
13312 loc: child.loc,
13313 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
13314 };
13315 }
13316 }
13317 };
13318 }
13319};
13320
13321const seen = new WeakSet();
13322const transformOnce = (node, context) => {
13323 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
13324 if (seen.has(node)) {
13325 return;
13326 }
13327 seen.add(node);
13328 context.helper(SET_BLOCK_TRACKING);
13329 return () => {
13330 const cur = context.currentNode;
13331 if (cur.codegenNode) {
13332 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
13333 }
13334 };
13335 }
13336};
13337
13338const transformModel = (dir, node, context) => {
13339 const { exp, arg } = dir;
13340 if (!exp) {
13341 context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
13342 return createTransformProps();
13343 }
13344 const rawExp = exp.loc.source;
13345 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
13346 // im SFC <script setup> inline mode, the exp may have been transformed into
13347 // _unref(exp)
13348 context.bindingMetadata[rawExp];
13349 const maybeRef = !true /* SETUP_CONST */;
13350 if (!isMemberExpression(expString) && !maybeRef) {
13351 context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
13352 return createTransformProps();
13353 }
13354 const propName = arg ? arg : createSimpleExpression('modelValue', true);
13355 const eventName = arg
13356 ? isStaticExp(arg)
13357 ? `onUpdate:${arg.content}`
13358 : createCompoundExpression(['"onUpdate:" + ', arg])
13359 : `onUpdate:modelValue`;
13360 let assignmentExp;
13361 const eventArg = context.isTS ? `($event: any)` : `$event`;
13362 {
13363 assignmentExp = createCompoundExpression([
13364 `${eventArg} => (`,
13365 exp,
13366 ` = $event)`
13367 ]);
13368 }
13369 const props = [
13370 // modelValue: foo
13371 createObjectProperty(propName, dir.exp),
13372 // "onUpdate:modelValue": $event => (foo = $event)
13373 createObjectProperty(eventName, assignmentExp)
13374 ];
13375 // modelModifiers: { foo: true, "bar-baz": true }
13376 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
13377 const modifiers = dir.modifiers
13378 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
13379 .join(`, `);
13380 const modifiersKey = arg
13381 ? isStaticExp(arg)
13382 ? `${arg.content}Modifiers`
13383 : createCompoundExpression([arg, ' + "Modifiers"'])
13384 : `modelModifiers`;
13385 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
13386 }
13387 return createTransformProps(props);
13388};
13389function createTransformProps(props = []) {
13390 return { props };
13391}
13392
13393function getBaseTransformPreset(prefixIdentifiers) {
13394 return [
13395 [
13396 transformOnce,
13397 transformIf,
13398 transformFor,
13399 ...([transformExpression]
13400 ),
13401 transformSlotOutlet,
13402 transformElement,
13403 trackSlotScopes,
13404 transformText
13405 ],
13406 {
13407 on: transformOn,
13408 bind: transformBind,
13409 model: transformModel
13410 }
13411 ];
13412}
13413// we name it `baseCompile` so that higher order compilers like
13414// @vue/compiler-dom can export `compile` while re-exporting everything else.
13415function baseCompile(template, options = {}) {
13416 const onError = options.onError || defaultOnError;
13417 const isModuleMode = options.mode === 'module';
13418 /* istanbul ignore if */
13419 {
13420 if (options.prefixIdentifiers === true) {
13421 onError(createCompilerError(45 /* X_PREFIX_ID_NOT_SUPPORTED */));
13422 }
13423 else if (isModuleMode) {
13424 onError(createCompilerError(46 /* X_MODULE_MODE_NOT_SUPPORTED */));
13425 }
13426 }
13427 const prefixIdentifiers = !true ;
13428 if (options.cacheHandlers) {
13429 onError(createCompilerError(47 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
13430 }
13431 if (options.scopeId && !isModuleMode) {
13432 onError(createCompilerError(48 /* X_SCOPE_ID_NOT_SUPPORTED */));
13433 }
13434 const ast = isString(template) ? baseParse(template, options) : template;
13435 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
13436 transform(ast, extend({}, options, {
13437 prefixIdentifiers,
13438 nodeTransforms: [
13439 ...nodeTransforms,
13440 ...(options.nodeTransforms || []) // user transforms
13441 ],
13442 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
13443 )
13444 }));
13445 return generate(ast, extend({}, options, {
13446 prefixIdentifiers
13447 }));
13448}
13449
13450const noopDirectiveTransform = () => ({ props: [] });
13451
13452const V_MODEL_RADIO = Symbol(`vModelRadio` );
13453const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
13454const V_MODEL_TEXT = Symbol(`vModelText` );
13455const V_MODEL_SELECT = Symbol(`vModelSelect` );
13456const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
13457const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
13458const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
13459const V_SHOW = Symbol(`vShow` );
13460const TRANSITION$1 = Symbol(`Transition` );
13461const TRANSITION_GROUP = Symbol(`TransitionGroup` );
13462registerRuntimeHelpers({
13463 [V_MODEL_RADIO]: `vModelRadio`,
13464 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
13465 [V_MODEL_TEXT]: `vModelText`,
13466 [V_MODEL_SELECT]: `vModelSelect`,
13467 [V_MODEL_DYNAMIC]: `vModelDynamic`,
13468 [V_ON_WITH_MODIFIERS]: `withModifiers`,
13469 [V_ON_WITH_KEYS]: `withKeys`,
13470 [V_SHOW]: `vShow`,
13471 [TRANSITION$1]: `Transition`,
13472 [TRANSITION_GROUP]: `TransitionGroup`
13473});
13474
13475/* eslint-disable no-restricted-globals */
13476let decoder;
13477function decodeHtmlBrowser(raw) {
13478 (decoder || (decoder = document.createElement('div'))).innerHTML = raw;
13479 return decoder.textContent;
13480}
13481
13482const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
13483const parserOptions = {
13484 isVoidTag,
13485 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
13486 isPreTag: tag => tag === 'pre',
13487 decodeEntities: decodeHtmlBrowser ,
13488 isBuiltInComponent: (tag) => {
13489 if (isBuiltInType(tag, `Transition`)) {
13490 return TRANSITION$1;
13491 }
13492 else if (isBuiltInType(tag, `TransitionGroup`)) {
13493 return TRANSITION_GROUP;
13494 }
13495 },
13496 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
13497 getNamespace(tag, parent) {
13498 let ns = parent ? parent.ns : 0 /* HTML */;
13499 if (parent && ns === 2 /* MATH_ML */) {
13500 if (parent.tag === 'annotation-xml') {
13501 if (tag === 'svg') {
13502 return 1 /* SVG */;
13503 }
13504 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
13505 a.name === 'encoding' &&
13506 a.value != null &&
13507 (a.value.content === 'text/html' ||
13508 a.value.content === 'application/xhtml+xml'))) {
13509 ns = 0 /* HTML */;
13510 }
13511 }
13512 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
13513 tag !== 'mglyph' &&
13514 tag !== 'malignmark') {
13515 ns = 0 /* HTML */;
13516 }
13517 }
13518 else if (parent && ns === 1 /* SVG */) {
13519 if (parent.tag === 'foreignObject' ||
13520 parent.tag === 'desc' ||
13521 parent.tag === 'title') {
13522 ns = 0 /* HTML */;
13523 }
13524 }
13525 if (ns === 0 /* HTML */) {
13526 if (tag === 'svg') {
13527 return 1 /* SVG */;
13528 }
13529 if (tag === 'math') {
13530 return 2 /* MATH_ML */;
13531 }
13532 }
13533 return ns;
13534 },
13535 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
13536 getTextMode({ tag, ns }) {
13537 if (ns === 0 /* HTML */) {
13538 if (tag === 'textarea' || tag === 'title') {
13539 return 1 /* RCDATA */;
13540 }
13541 if (isRawTextContainer(tag)) {
13542 return 2 /* RAWTEXT */;
13543 }
13544 }
13545 return 0 /* DATA */;
13546 }
13547};
13548
13549// Parse inline CSS strings for static style attributes into an object.
13550// This is a NodeTransform since it works on the static `style` attribute and
13551// converts it into a dynamic equivalent:
13552// style="color: red" -> :style='{ "color": "red" }'
13553// It is then processed by `transformElement` and included in the generated
13554// props.
13555const transformStyle = node => {
13556 if (node.type === 1 /* ELEMENT */) {
13557 node.props.forEach((p, i) => {
13558 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
13559 // replace p with an expression node
13560 node.props[i] = {
13561 type: 7 /* DIRECTIVE */,
13562 name: `bind`,
13563 arg: createSimpleExpression(`style`, true, p.loc),
13564 exp: parseInlineCSS(p.value.content, p.loc),
13565 modifiers: [],
13566 loc: p.loc
13567 };
13568 }
13569 });
13570 }
13571};
13572const parseInlineCSS = (cssText, loc) => {
13573 const normalized = parseStringStyle(cssText);
13574 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
13575};
13576
13577function createDOMCompilerError(code, loc) {
13578 return createCompilerError(code, loc, DOMErrorMessages );
13579}
13580const DOMErrorMessages = {
13581 [49 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
13582 [50 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
13583 [51 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
13584 [52 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
13585 [53 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
13586 [54 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
13587 [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.`,
13588 [56 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
13589 [57 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
13590 [58 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
13591 [59 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
13592};
13593
13594const transformVHtml = (dir, node, context) => {
13595 const { exp, loc } = dir;
13596 if (!exp) {
13597 context.onError(createDOMCompilerError(49 /* X_V_HTML_NO_EXPRESSION */, loc));
13598 }
13599 if (node.children.length) {
13600 context.onError(createDOMCompilerError(50 /* X_V_HTML_WITH_CHILDREN */, loc));
13601 node.children.length = 0;
13602 }
13603 return {
13604 props: [
13605 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
13606 ]
13607 };
13608};
13609
13610const transformVText = (dir, node, context) => {
13611 const { exp, loc } = dir;
13612 if (!exp) {
13613 context.onError(createDOMCompilerError(51 /* X_V_TEXT_NO_EXPRESSION */, loc));
13614 }
13615 if (node.children.length) {
13616 context.onError(createDOMCompilerError(52 /* X_V_TEXT_WITH_CHILDREN */, loc));
13617 node.children.length = 0;
13618 }
13619 return {
13620 props: [
13621 createObjectProperty(createSimpleExpression(`textContent`, true), exp
13622 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
13623 : createSimpleExpression('', true))
13624 ]
13625 };
13626};
13627
13628const transformModel$1 = (dir, node, context) => {
13629 const baseResult = transformModel(dir, node, context);
13630 // base transform has errors OR component v-model (only need props)
13631 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
13632 return baseResult;
13633 }
13634 if (dir.arg) {
13635 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
13636 }
13637 function checkDuplicatedValue() {
13638 const value = findProp(node, 'value');
13639 if (value) {
13640 context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
13641 }
13642 }
13643 const { tag } = node;
13644 const isCustomElement = context.isCustomElement(tag);
13645 if (tag === 'input' ||
13646 tag === 'textarea' ||
13647 tag === 'select' ||
13648 isCustomElement) {
13649 let directiveToUse = V_MODEL_TEXT;
13650 let isInvalidType = false;
13651 if (tag === 'input' || isCustomElement) {
13652 const type = findProp(node, `type`);
13653 if (type) {
13654 if (type.type === 7 /* DIRECTIVE */) {
13655 // :type="foo"
13656 directiveToUse = V_MODEL_DYNAMIC;
13657 }
13658 else if (type.value) {
13659 switch (type.value.content) {
13660 case 'radio':
13661 directiveToUse = V_MODEL_RADIO;
13662 break;
13663 case 'checkbox':
13664 directiveToUse = V_MODEL_CHECKBOX;
13665 break;
13666 case 'file':
13667 isInvalidType = true;
13668 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
13669 break;
13670 default:
13671 // text type
13672 checkDuplicatedValue();
13673 break;
13674 }
13675 }
13676 }
13677 else if (hasDynamicKeyVBind(node)) {
13678 // element has bindings with dynamic keys, which can possibly contain
13679 // "type".
13680 directiveToUse = V_MODEL_DYNAMIC;
13681 }
13682 else {
13683 // text type
13684 checkDuplicatedValue();
13685 }
13686 }
13687 else if (tag === 'select') {
13688 directiveToUse = V_MODEL_SELECT;
13689 }
13690 else {
13691 // textarea
13692 checkDuplicatedValue();
13693 }
13694 // inject runtime directive
13695 // by returning the helper symbol via needRuntime
13696 // the import will replaced a resolveDirective call.
13697 if (!isInvalidType) {
13698 baseResult.needRuntime = context.helper(directiveToUse);
13699 }
13700 }
13701 else {
13702 context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
13703 }
13704 // native vmodel doesn't need the `modelValue` props since they are also
13705 // passed to the runtime as `binding.value`. removing it reduces code size.
13706 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
13707 p.key.content === 'modelValue'));
13708 return baseResult;
13709};
13710
13711const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
13712const isNonKeyModifier = /*#__PURE__*/ makeMap(
13713// event propagation management
13714`stop,prevent,self,` +
13715 // system modifiers + exact
13716 `ctrl,shift,alt,meta,exact,` +
13717 // mouse
13718 `middle`);
13719// left & right could be mouse or key modifiers based on event type
13720const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
13721const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
13722const resolveModifiers = (key, modifiers) => {
13723 const keyModifiers = [];
13724 const nonKeyModifiers = [];
13725 const eventOptionModifiers = [];
13726 for (let i = 0; i < modifiers.length; i++) {
13727 const modifier = modifiers[i];
13728 if (isEventOptionModifier(modifier)) {
13729 // eventOptionModifiers: modifiers for addEventListener() options,
13730 // e.g. .passive & .capture
13731 eventOptionModifiers.push(modifier);
13732 }
13733 else {
13734 // runtimeModifiers: modifiers that needs runtime guards
13735 if (maybeKeyModifier(modifier)) {
13736 if (isStaticExp(key)) {
13737 if (isKeyboardEvent(key.content)) {
13738 keyModifiers.push(modifier);
13739 }
13740 else {
13741 nonKeyModifiers.push(modifier);
13742 }
13743 }
13744 else {
13745 keyModifiers.push(modifier);
13746 nonKeyModifiers.push(modifier);
13747 }
13748 }
13749 else {
13750 if (isNonKeyModifier(modifier)) {
13751 nonKeyModifiers.push(modifier);
13752 }
13753 else {
13754 keyModifiers.push(modifier);
13755 }
13756 }
13757 }
13758 }
13759 return {
13760 keyModifiers,
13761 nonKeyModifiers,
13762 eventOptionModifiers
13763 };
13764};
13765const transformClick = (key, event) => {
13766 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
13767 return isStaticClick
13768 ? createSimpleExpression(event, true)
13769 : key.type !== 4 /* SIMPLE_EXPRESSION */
13770 ? createCompoundExpression([
13771 `(`,
13772 key,
13773 `) === "onClick" ? "${event}" : (`,
13774 key,
13775 `)`
13776 ])
13777 : key;
13778};
13779const transformOn$1 = (dir, node, context) => {
13780 return transformOn(dir, node, context, baseResult => {
13781 const { modifiers } = dir;
13782 if (!modifiers.length)
13783 return baseResult;
13784 let { key, value: handlerExp } = baseResult.props[0];
13785 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers);
13786 // normalize click.right and click.middle since they don't actually fire
13787 if (nonKeyModifiers.includes('right')) {
13788 key = transformClick(key, `onContextmenu`);
13789 }
13790 if (nonKeyModifiers.includes('middle')) {
13791 key = transformClick(key, `onMouseup`);
13792 }
13793 if (nonKeyModifiers.length) {
13794 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
13795 handlerExp,
13796 JSON.stringify(nonKeyModifiers)
13797 ]);
13798 }
13799 if (keyModifiers.length &&
13800 // if event name is dynamic, always wrap with keys guard
13801 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
13802 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
13803 handlerExp,
13804 JSON.stringify(keyModifiers)
13805 ]);
13806 }
13807 if (eventOptionModifiers.length) {
13808 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
13809 key = isStaticExp(key)
13810 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
13811 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
13812 }
13813 return {
13814 props: [createObjectProperty(key, handlerExp)]
13815 };
13816 });
13817};
13818
13819const transformShow = (dir, node, context) => {
13820 const { exp, loc } = dir;
13821 if (!exp) {
13822 context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */, loc));
13823 }
13824 return {
13825 props: [],
13826 needRuntime: context.helper(V_SHOW)
13827 };
13828};
13829
13830const warnTransitionChildren = (node, context) => {
13831 if (node.type === 1 /* ELEMENT */ &&
13832 node.tagType === 1 /* COMPONENT */) {
13833 const component = context.isBuiltInComponent(node.tag);
13834 if (component === TRANSITION$1) {
13835 return () => {
13836 if (node.children.length && hasMultipleChildren(node)) {
13837 context.onError(createDOMCompilerError(58 /* X_TRANSITION_INVALID_CHILDREN */, {
13838 start: node.children[0].loc.start,
13839 end: node.children[node.children.length - 1].loc.end,
13840 source: ''
13841 }));
13842 }
13843 };
13844 }
13845 }
13846};
13847function hasMultipleChildren(node) {
13848 // #1352 filter out potential comment nodes.
13849 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */));
13850 const child = children[0];
13851 return (children.length !== 1 ||
13852 child.type === 11 /* FOR */ ||
13853 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
13854}
13855
13856const ignoreSideEffectTags = (node, context) => {
13857 if (node.type === 1 /* ELEMENT */ &&
13858 node.tagType === 0 /* ELEMENT */ &&
13859 (node.tag === 'script' || node.tag === 'style')) {
13860 context.onError(createDOMCompilerError(59 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
13861 context.removeNode();
13862 }
13863};
13864
13865const DOMNodeTransforms = [
13866 transformStyle,
13867 ...([warnTransitionChildren] )
13868];
13869const DOMDirectiveTransforms = {
13870 cloak: noopDirectiveTransform,
13871 html: transformVHtml,
13872 text: transformVText,
13873 model: transformModel$1,
13874 on: transformOn$1,
13875 show: transformShow
13876};
13877function compile$1(template, options = {}) {
13878 return baseCompile(template, extend({}, parserOptions, options, {
13879 nodeTransforms: [
13880 // ignore <script> and <tag>
13881 // this is not put inside DOMNodeTransforms because that list is used
13882 // by compiler-ssr to generate vnode fallback branches
13883 ignoreSideEffectTags,
13884 ...DOMNodeTransforms,
13885 ...(options.nodeTransforms || [])
13886 ],
13887 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
13888 transformHoist: null
13889 }));
13890}
13891
13892// This entry is the "full-build" that includes both the runtime
13893{
13894 initDev();
13895}
13896const compileCache = Object.create(null);
13897function compileToFunction(template, options) {
13898 if (!isString(template)) {
13899 if (template.nodeType) {
13900 template = template.innerHTML;
13901 }
13902 else {
13903 warn(`invalid template option: `, template);
13904 return NOOP;
13905 }
13906 }
13907 const key = template;
13908 const cached = compileCache[key];
13909 if (cached) {
13910 return cached;
13911 }
13912 if (template[0] === '#') {
13913 const el = document.querySelector(template);
13914 if (!el) {
13915 warn(`Template element not found or is empty: ${template}`);
13916 }
13917 // __UNSAFE__
13918 // Reason: potential execution of JS expressions in in-DOM template.
13919 // The user must make sure the in-DOM template is trusted. If it's rendered
13920 // by the server, the template should not contain any user data.
13921 template = el ? el.innerHTML : ``;
13922 }
13923 const { code } = compile$1(template, extend({
13924 hoistStatic: true,
13925 onError(err) {
13926 {
13927 const message = `Template compilation error: ${err.message}`;
13928 const codeFrame = err.loc &&
13929 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
13930 warn(codeFrame ? `${message}\n${codeFrame}` : message);
13931 }
13932 }
13933 }, options));
13934 // The wildcard import results in a huge object with every export
13935 // with keys that cannot be mangled, and can be quite heavy size-wise.
13936 // In the global build we know `Vue` is available globally so we can avoid
13937 // the wildcard object.
13938 const render = (new Function('Vue', code)(runtimeDom));
13939 render._rc = true;
13940 return (compileCache[key] = render);
13941}
13942registerRuntimeCompiler(compileToFunction);
13943
13944export { BaseTransition, Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, Transition, TransitionGroup, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, 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, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, 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 };