UNPKG

520 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 === (isReadonly ? readonlyMap : reactiveMap).get(target)) {
603 return target;
604 }
605 const targetIsArray = isArray(target);
606 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
607 return Reflect.get(arrayInstrumentations, key, receiver);
608 }
609 const res = Reflect.get(target, key, receiver);
610 if (isSymbol(key)
611 ? builtInSymbols.has(key)
612 : isNonTrackableKeys(key)) {
613 return res;
614 }
615 if (!isReadonly) {
616 track(target, "get" /* GET */, key);
617 }
618 if (shallow) {
619 return res;
620 }
621 if (isRef(res)) {
622 // ref unwrapping - does not apply for Array + integer key.
623 const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
624 return shouldUnwrap ? res.value : res;
625 }
626 if (isObject(res)) {
627 // Convert returned value into a proxy as well. we do the isObject check
628 // here to avoid invalid value warning. Also need to lazy access readonly
629 // and reactive here to avoid circular dependency.
630 return isReadonly ? readonly(res) : reactive(res);
631 }
632 return res;
633 };
634}
635const set = /*#__PURE__*/ createSetter();
636const shallowSet = /*#__PURE__*/ createSetter(true);
637function createSetter(shallow = false) {
638 return function set(target, key, value, receiver) {
639 const oldValue = target[key];
640 if (!shallow) {
641 value = toRaw(value);
642 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
643 oldValue.value = value;
644 return true;
645 }
646 }
647 const hadKey = isArray(target) && isIntegerKey(key)
648 ? Number(key) < target.length
649 : hasOwn(target, key);
650 const result = Reflect.set(target, key, value, receiver);
651 // don't trigger if target is something up in the prototype chain of original
652 if (target === toRaw(receiver)) {
653 if (!hadKey) {
654 trigger(target, "add" /* ADD */, key, value);
655 }
656 else if (hasChanged(value, oldValue)) {
657 trigger(target, "set" /* SET */, key, value, oldValue);
658 }
659 }
660 return result;
661 };
662}
663function deleteProperty(target, key) {
664 const hadKey = hasOwn(target, key);
665 const oldValue = target[key];
666 const result = Reflect.deleteProperty(target, key);
667 if (result && hadKey) {
668 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
669 }
670 return result;
671}
672function has(target, key) {
673 const result = Reflect.has(target, key);
674 if (!isSymbol(key) || !builtInSymbols.has(key)) {
675 track(target, "has" /* HAS */, key);
676 }
677 return result;
678}
679function ownKeys(target) {
680 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
681 return Reflect.ownKeys(target);
682}
683const mutableHandlers = {
684 get,
685 set,
686 deleteProperty,
687 has,
688 ownKeys
689};
690const readonlyHandlers = {
691 get: readonlyGet,
692 set(target, key) {
693 {
694 console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
695 }
696 return true;
697 },
698 deleteProperty(target, key) {
699 {
700 console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
701 }
702 return true;
703 }
704};
705const shallowReactiveHandlers = extend({}, mutableHandlers, {
706 get: shallowGet,
707 set: shallowSet
708});
709// Props handlers are special in the sense that it should not unwrap top-level
710// refs (in order to allow refs to be explicitly passed down), but should
711// retain the reactivity of the normal readonly object.
712const shallowReadonlyHandlers = extend({}, readonlyHandlers, {
713 get: shallowReadonlyGet
714});
715
716const toReactive = (value) => isObject(value) ? reactive(value) : value;
717const toReadonly = (value) => isObject(value) ? readonly(value) : value;
718const toShallow = (value) => value;
719const getProto = (v) => Reflect.getPrototypeOf(v);
720function get$1(target, key, isReadonly = false, isShallow = false) {
721 // #1772: readonly(reactive(Map)) should return readonly + reactive version
722 // of the value
723 target = target["__v_raw" /* RAW */];
724 const rawTarget = toRaw(target);
725 const rawKey = toRaw(key);
726 if (key !== rawKey) {
727 !isReadonly && track(rawTarget, "get" /* GET */, key);
728 }
729 !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
730 const { has } = getProto(rawTarget);
731 const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive;
732 if (has.call(rawTarget, key)) {
733 return wrap(target.get(key));
734 }
735 else if (has.call(rawTarget, rawKey)) {
736 return wrap(target.get(rawKey));
737 }
738}
739function has$1(key, isReadonly = false) {
740 const target = this["__v_raw" /* RAW */];
741 const rawTarget = toRaw(target);
742 const rawKey = toRaw(key);
743 if (key !== rawKey) {
744 !isReadonly && track(rawTarget, "has" /* HAS */, key);
745 }
746 !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
747 return key === rawKey
748 ? target.has(key)
749 : target.has(key) || target.has(rawKey);
750}
751function size(target, isReadonly = false) {
752 target = target["__v_raw" /* RAW */];
753 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
754 return Reflect.get(target, 'size', target);
755}
756function add(value) {
757 value = toRaw(value);
758 const target = toRaw(this);
759 const proto = getProto(target);
760 const hadKey = proto.has.call(target, value);
761 if (!hadKey) {
762 target.add(value);
763 trigger(target, "add" /* ADD */, value, value);
764 }
765 return this;
766}
767function set$1(key, value) {
768 value = toRaw(value);
769 const target = toRaw(this);
770 const { has, get } = getProto(target);
771 let hadKey = has.call(target, key);
772 if (!hadKey) {
773 key = toRaw(key);
774 hadKey = has.call(target, key);
775 }
776 else {
777 checkIdentityKeys(target, has, key);
778 }
779 const oldValue = get.call(target, key);
780 target.set(key, value);
781 if (!hadKey) {
782 trigger(target, "add" /* ADD */, key, value);
783 }
784 else if (hasChanged(value, oldValue)) {
785 trigger(target, "set" /* SET */, key, value, oldValue);
786 }
787 return this;
788}
789function deleteEntry(key) {
790 const target = toRaw(this);
791 const { has, get } = getProto(target);
792 let hadKey = has.call(target, key);
793 if (!hadKey) {
794 key = toRaw(key);
795 hadKey = has.call(target, key);
796 }
797 else {
798 checkIdentityKeys(target, has, key);
799 }
800 const oldValue = get ? get.call(target, key) : undefined;
801 // forward the operation before queueing reactions
802 const result = target.delete(key);
803 if (hadKey) {
804 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
805 }
806 return result;
807}
808function clear() {
809 const target = toRaw(this);
810 const hadItems = target.size !== 0;
811 const oldTarget = isMap(target)
812 ? new Map(target)
813 : new Set(target)
814 ;
815 // forward the operation before queueing reactions
816 const result = target.clear();
817 if (hadItems) {
818 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
819 }
820 return result;
821}
822function createForEach(isReadonly, isShallow) {
823 return function forEach(callback, thisArg) {
824 const observed = this;
825 const target = observed["__v_raw" /* RAW */];
826 const rawTarget = toRaw(target);
827 const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive;
828 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
829 return target.forEach((value, key) => {
830 // important: make sure the callback is
831 // 1. invoked with the reactive map as `this` and 3rd arg
832 // 2. the value received should be a corresponding reactive/readonly.
833 return callback.call(thisArg, wrap(value), wrap(key), observed);
834 });
835 };
836}
837function createIterableMethod(method, isReadonly, isShallow) {
838 return function (...args) {
839 const target = this["__v_raw" /* RAW */];
840 const rawTarget = toRaw(target);
841 const targetIsMap = isMap(rawTarget);
842 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
843 const isKeyOnly = method === 'keys' && targetIsMap;
844 const innerIterator = target[method](...args);
845 const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive;
846 !isReadonly &&
847 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
848 // return a wrapped iterator which returns observed versions of the
849 // values emitted from the real iterator
850 return {
851 // iterator protocol
852 next() {
853 const { value, done } = innerIterator.next();
854 return done
855 ? { value, done }
856 : {
857 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
858 done
859 };
860 },
861 // iterable protocol
862 [Symbol.iterator]() {
863 return this;
864 }
865 };
866 };
867}
868function createReadonlyMethod(type) {
869 return function (...args) {
870 {
871 const key = args[0] ? `on key "${args[0]}" ` : ``;
872 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
873 }
874 return type === "delete" /* DELETE */ ? false : this;
875 };
876}
877const mutableInstrumentations = {
878 get(key) {
879 return get$1(this, key);
880 },
881 get size() {
882 return size(this);
883 },
884 has: has$1,
885 add,
886 set: set$1,
887 delete: deleteEntry,
888 clear,
889 forEach: createForEach(false, false)
890};
891const shallowInstrumentations = {
892 get(key) {
893 return get$1(this, key, false, true);
894 },
895 get size() {
896 return size(this);
897 },
898 has: has$1,
899 add,
900 set: set$1,
901 delete: deleteEntry,
902 clear,
903 forEach: createForEach(false, true)
904};
905const readonlyInstrumentations = {
906 get(key) {
907 return get$1(this, key, true);
908 },
909 get size() {
910 return size(this, true);
911 },
912 has(key) {
913 return has$1.call(this, key, true);
914 },
915 add: createReadonlyMethod("add" /* ADD */),
916 set: createReadonlyMethod("set" /* SET */),
917 delete: createReadonlyMethod("delete" /* DELETE */),
918 clear: createReadonlyMethod("clear" /* CLEAR */),
919 forEach: createForEach(true, false)
920};
921const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
922iteratorMethods.forEach(method => {
923 mutableInstrumentations[method] = createIterableMethod(method, false, false);
924 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
925 shallowInstrumentations[method] = createIterableMethod(method, false, true);
926});
927function createInstrumentationGetter(isReadonly, shallow) {
928 const instrumentations = shallow
929 ? shallowInstrumentations
930 : isReadonly
931 ? readonlyInstrumentations
932 : mutableInstrumentations;
933 return (target, key, receiver) => {
934 if (key === "__v_isReactive" /* IS_REACTIVE */) {
935 return !isReadonly;
936 }
937 else if (key === "__v_isReadonly" /* IS_READONLY */) {
938 return isReadonly;
939 }
940 else if (key === "__v_raw" /* RAW */) {
941 return target;
942 }
943 return Reflect.get(hasOwn(instrumentations, key) && key in target
944 ? instrumentations
945 : target, key, receiver);
946 };
947}
948const mutableCollectionHandlers = {
949 get: createInstrumentationGetter(false, false)
950};
951const shallowCollectionHandlers = {
952 get: createInstrumentationGetter(false, true)
953};
954const readonlyCollectionHandlers = {
955 get: createInstrumentationGetter(true, false)
956};
957function checkIdentityKeys(target, has, key) {
958 const rawKey = toRaw(key);
959 if (rawKey !== key && has.call(target, rawKey)) {
960 const type = toRawType(target);
961 console.warn(`Reactive ${type} contains both the raw and reactive ` +
962 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
963 `which can lead to inconsistencies. ` +
964 `Avoid differentiating between the raw and reactive versions ` +
965 `of an object and only use the reactive version if possible.`);
966 }
967}
968
969const reactiveMap = new WeakMap();
970const readonlyMap = new WeakMap();
971function targetTypeMap(rawType) {
972 switch (rawType) {
973 case 'Object':
974 case 'Array':
975 return 1 /* COMMON */;
976 case 'Map':
977 case 'Set':
978 case 'WeakMap':
979 case 'WeakSet':
980 return 2 /* COLLECTION */;
981 default:
982 return 0 /* INVALID */;
983 }
984}
985function getTargetType(value) {
986 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
987 ? 0 /* INVALID */
988 : targetTypeMap(toRawType(value));
989}
990function reactive(target) {
991 // if trying to observe a readonly proxy, return the readonly version.
992 if (target && target["__v_isReadonly" /* IS_READONLY */]) {
993 return target;
994 }
995 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers);
996}
997/**
998 * Return a shallowly-reactive copy of the original object, where only the root
999 * level properties are reactive. It also does not auto-unwrap refs (even at the
1000 * root level).
1001 */
1002function shallowReactive(target) {
1003 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers);
1004}
1005/**
1006 * Creates a readonly copy of the original object. Note the returned copy is not
1007 * made reactive, but `readonly` can be called on an already reactive object.
1008 */
1009function readonly(target) {
1010 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers);
1011}
1012/**
1013 * Returns a reactive-copy of the original object, where only the root level
1014 * properties are readonly, and does NOT unwrap refs nor recursively convert
1015 * returned properties.
1016 * This is used for creating the props proxy object for stateful components.
1017 */
1018function shallowReadonly(target) {
1019 return createReactiveObject(target, true, shallowReadonlyHandlers, readonlyCollectionHandlers);
1020}
1021function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers) {
1022 if (!isObject(target)) {
1023 {
1024 console.warn(`value cannot be made reactive: ${String(target)}`);
1025 }
1026 return target;
1027 }
1028 // target is already a Proxy, return it.
1029 // exception: calling readonly() on a reactive object
1030 if (target["__v_raw" /* RAW */] &&
1031 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1032 return target;
1033 }
1034 // target already has corresponding Proxy
1035 const proxyMap = isReadonly ? readonlyMap : reactiveMap;
1036 const existingProxy = proxyMap.get(target);
1037 if (existingProxy) {
1038 return existingProxy;
1039 }
1040 // only a whitelist of value types can be observed.
1041 const targetType = getTargetType(target);
1042 if (targetType === 0 /* INVALID */) {
1043 return target;
1044 }
1045 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1046 proxyMap.set(target, proxy);
1047 return proxy;
1048}
1049function isReactive(value) {
1050 if (isReadonly(value)) {
1051 return isReactive(value["__v_raw" /* RAW */]);
1052 }
1053 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1054}
1055function isReadonly(value) {
1056 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1057}
1058function isProxy(value) {
1059 return isReactive(value) || isReadonly(value);
1060}
1061function toRaw(observed) {
1062 return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed);
1063}
1064function markRaw(value) {
1065 def(value, "__v_skip" /* SKIP */, true);
1066 return value;
1067}
1068
1069const convert = (val) => isObject(val) ? reactive(val) : val;
1070function isRef(r) {
1071 return Boolean(r && r.__v_isRef === true);
1072}
1073function ref(value) {
1074 return createRef(value);
1075}
1076function shallowRef(value) {
1077 return createRef(value, true);
1078}
1079class RefImpl {
1080 constructor(_rawValue, _shallow = false) {
1081 this._rawValue = _rawValue;
1082 this._shallow = _shallow;
1083 this.__v_isRef = true;
1084 this._value = _shallow ? _rawValue : convert(_rawValue);
1085 }
1086 get value() {
1087 track(toRaw(this), "get" /* GET */, 'value');
1088 return this._value;
1089 }
1090 set value(newVal) {
1091 if (hasChanged(toRaw(newVal), this._rawValue)) {
1092 this._rawValue = newVal;
1093 this._value = this._shallow ? newVal : convert(newVal);
1094 trigger(toRaw(this), "set" /* SET */, 'value', newVal);
1095 }
1096 }
1097}
1098function createRef(rawValue, shallow = false) {
1099 if (isRef(rawValue)) {
1100 return rawValue;
1101 }
1102 return new RefImpl(rawValue, shallow);
1103}
1104function triggerRef(ref) {
1105 trigger(toRaw(ref), "set" /* SET */, 'value', ref.value );
1106}
1107function unref(ref) {
1108 return isRef(ref) ? ref.value : ref;
1109}
1110const shallowUnwrapHandlers = {
1111 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1112 set: (target, key, value, receiver) => {
1113 const oldValue = target[key];
1114 if (isRef(oldValue) && !isRef(value)) {
1115 oldValue.value = value;
1116 return true;
1117 }
1118 else {
1119 return Reflect.set(target, key, value, receiver);
1120 }
1121 }
1122};
1123function proxyRefs(objectWithRefs) {
1124 return isReactive(objectWithRefs)
1125 ? objectWithRefs
1126 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1127}
1128class CustomRefImpl {
1129 constructor(factory) {
1130 this.__v_isRef = true;
1131 const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value'));
1132 this._get = get;
1133 this._set = set;
1134 }
1135 get value() {
1136 return this._get();
1137 }
1138 set value(newVal) {
1139 this._set(newVal);
1140 }
1141}
1142function customRef(factory) {
1143 return new CustomRefImpl(factory);
1144}
1145function toRefs(object) {
1146 if (!isProxy(object)) {
1147 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1148 }
1149 const ret = isArray(object) ? new Array(object.length) : {};
1150 for (const key in object) {
1151 ret[key] = toRef(object, key);
1152 }
1153 return ret;
1154}
1155class ObjectRefImpl {
1156 constructor(_object, _key) {
1157 this._object = _object;
1158 this._key = _key;
1159 this.__v_isRef = true;
1160 }
1161 get value() {
1162 return this._object[this._key];
1163 }
1164 set value(newVal) {
1165 this._object[this._key] = newVal;
1166 }
1167}
1168function toRef(object, key) {
1169 return isRef(object[key])
1170 ? object[key]
1171 : new ObjectRefImpl(object, key);
1172}
1173
1174class ComputedRefImpl {
1175 constructor(getter, _setter, isReadonly) {
1176 this._setter = _setter;
1177 this._dirty = true;
1178 this.__v_isRef = true;
1179 this.effect = effect(getter, {
1180 lazy: true,
1181 scheduler: () => {
1182 if (!this._dirty) {
1183 this._dirty = true;
1184 trigger(toRaw(this), "set" /* SET */, 'value');
1185 }
1186 }
1187 });
1188 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1189 }
1190 get value() {
1191 if (this._dirty) {
1192 this._value = this.effect();
1193 this._dirty = false;
1194 }
1195 track(toRaw(this), "get" /* GET */, 'value');
1196 return this._value;
1197 }
1198 set value(newValue) {
1199 this._setter(newValue);
1200 }
1201}
1202function computed(getterOrOptions) {
1203 let getter;
1204 let setter;
1205 if (isFunction(getterOrOptions)) {
1206 getter = getterOrOptions;
1207 setter = () => {
1208 console.warn('Write operation failed: computed value is readonly');
1209 }
1210 ;
1211 }
1212 else {
1213 getter = getterOrOptions.get;
1214 setter = getterOrOptions.set;
1215 }
1216 return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);
1217}
1218
1219const stack = [];
1220function pushWarningContext(vnode) {
1221 stack.push(vnode);
1222}
1223function popWarningContext() {
1224 stack.pop();
1225}
1226function warn(msg, ...args) {
1227 // avoid props formatting or warn handler tracking deps that might be mutated
1228 // during patch, leading to infinite recursion.
1229 pauseTracking();
1230 const instance = stack.length ? stack[stack.length - 1].component : null;
1231 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1232 const trace = getComponentTrace();
1233 if (appWarnHandler) {
1234 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
1235 msg + args.join(''),
1236 instance && instance.proxy,
1237 trace
1238 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1239 .join('\n'),
1240 trace
1241 ]);
1242 }
1243 else {
1244 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1245 /* istanbul ignore if */
1246 if (trace.length &&
1247 // avoid spamming console during tests
1248 !false) {
1249 warnArgs.push(`\n`, ...formatTrace(trace));
1250 }
1251 console.warn(...warnArgs);
1252 }
1253 resetTracking();
1254}
1255function getComponentTrace() {
1256 let currentVNode = stack[stack.length - 1];
1257 if (!currentVNode) {
1258 return [];
1259 }
1260 // we can't just use the stack because it will be incomplete during updates
1261 // that did not start from the root. Re-construct the parent chain using
1262 // instance parent pointers.
1263 const normalizedStack = [];
1264 while (currentVNode) {
1265 const last = normalizedStack[0];
1266 if (last && last.vnode === currentVNode) {
1267 last.recurseCount++;
1268 }
1269 else {
1270 normalizedStack.push({
1271 vnode: currentVNode,
1272 recurseCount: 0
1273 });
1274 }
1275 const parentInstance = currentVNode.component && currentVNode.component.parent;
1276 currentVNode = parentInstance && parentInstance.vnode;
1277 }
1278 return normalizedStack;
1279}
1280/* istanbul ignore next */
1281function formatTrace(trace) {
1282 const logs = [];
1283 trace.forEach((entry, i) => {
1284 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1285 });
1286 return logs;
1287}
1288function formatTraceEntry({ vnode, recurseCount }) {
1289 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1290 const isRoot = vnode.component ? vnode.component.parent == null : false;
1291 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1292 const close = `>` + postfix;
1293 return vnode.props
1294 ? [open, ...formatProps(vnode.props), close]
1295 : [open + close];
1296}
1297/* istanbul ignore next */
1298function formatProps(props) {
1299 const res = [];
1300 const keys = Object.keys(props);
1301 keys.slice(0, 3).forEach(key => {
1302 res.push(...formatProp(key, props[key]));
1303 });
1304 if (keys.length > 3) {
1305 res.push(` ...`);
1306 }
1307 return res;
1308}
1309/* istanbul ignore next */
1310function formatProp(key, value, raw) {
1311 if (isString(value)) {
1312 value = JSON.stringify(value);
1313 return raw ? value : [`${key}=${value}`];
1314 }
1315 else if (typeof value === 'number' ||
1316 typeof value === 'boolean' ||
1317 value == null) {
1318 return raw ? value : [`${key}=${value}`];
1319 }
1320 else if (isRef(value)) {
1321 value = formatProp(key, toRaw(value.value), true);
1322 return raw ? value : [`${key}=Ref<`, value, `>`];
1323 }
1324 else if (isFunction(value)) {
1325 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1326 }
1327 else {
1328 value = toRaw(value);
1329 return raw ? value : [`${key}=`, value];
1330 }
1331}
1332
1333const ErrorTypeStrings = {
1334 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
1335 ["c" /* CREATED */]: 'created hook',
1336 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
1337 ["m" /* MOUNTED */]: 'mounted hook',
1338 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
1339 ["u" /* UPDATED */]: 'updated',
1340 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1341 ["um" /* UNMOUNTED */]: 'unmounted hook',
1342 ["a" /* ACTIVATED */]: 'activated hook',
1343 ["da" /* DEACTIVATED */]: 'deactivated hook',
1344 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
1345 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
1346 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
1347 [0 /* SETUP_FUNCTION */]: 'setup function',
1348 [1 /* RENDER_FUNCTION */]: 'render function',
1349 [2 /* WATCH_GETTER */]: 'watcher getter',
1350 [3 /* WATCH_CALLBACK */]: 'watcher callback',
1351 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
1352 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
1353 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
1354 [7 /* VNODE_HOOK */]: 'vnode hook',
1355 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
1356 [9 /* TRANSITION_HOOK */]: 'transition hook',
1357 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
1358 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
1359 [12 /* FUNCTION_REF */]: 'ref function',
1360 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1361 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1362 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
1363};
1364function callWithErrorHandling(fn, instance, type, args) {
1365 let res;
1366 try {
1367 res = args ? fn(...args) : fn();
1368 }
1369 catch (err) {
1370 handleError(err, instance, type);
1371 }
1372 return res;
1373}
1374function callWithAsyncErrorHandling(fn, instance, type, args) {
1375 if (isFunction(fn)) {
1376 const res = callWithErrorHandling(fn, instance, type, args);
1377 if (res && isPromise(res)) {
1378 res.catch(err => {
1379 handleError(err, instance, type);
1380 });
1381 }
1382 return res;
1383 }
1384 const values = [];
1385 for (let i = 0; i < fn.length; i++) {
1386 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1387 }
1388 return values;
1389}
1390function handleError(err, instance, type, throwInDev = true) {
1391 const contextVNode = instance ? instance.vnode : null;
1392 if (instance) {
1393 let cur = instance.parent;
1394 // the exposed instance is the render proxy to keep it consistent with 2.x
1395 const exposedInstance = instance.proxy;
1396 // in production the hook receives only the error code
1397 const errorInfo = ErrorTypeStrings[type] ;
1398 while (cur) {
1399 const errorCapturedHooks = cur.ec;
1400 if (errorCapturedHooks) {
1401 for (let i = 0; i < errorCapturedHooks.length; i++) {
1402 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1403 return;
1404 }
1405 }
1406 }
1407 cur = cur.parent;
1408 }
1409 // app-level handling
1410 const appErrorHandler = instance.appContext.config.errorHandler;
1411 if (appErrorHandler) {
1412 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1413 return;
1414 }
1415 }
1416 logError(err, type, contextVNode, throwInDev);
1417}
1418function logError(err, type, contextVNode, throwInDev = true) {
1419 {
1420 const info = ErrorTypeStrings[type];
1421 if (contextVNode) {
1422 pushWarningContext(contextVNode);
1423 }
1424 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1425 if (contextVNode) {
1426 popWarningContext();
1427 }
1428 // crash in dev by default so it's more noticeable
1429 if (throwInDev) {
1430 throw err;
1431 }
1432 else {
1433 console.error(err);
1434 }
1435 }
1436}
1437
1438let isFlushing = false;
1439let isFlushPending = false;
1440const queue = [];
1441let flushIndex = 0;
1442const pendingPreFlushCbs = [];
1443let activePreFlushCbs = null;
1444let preFlushIndex = 0;
1445const pendingPostFlushCbs = [];
1446let activePostFlushCbs = null;
1447let postFlushIndex = 0;
1448const resolvedPromise = Promise.resolve();
1449let currentFlushPromise = null;
1450let currentPreFlushParentJob = null;
1451const RECURSION_LIMIT = 100;
1452function nextTick(fn) {
1453 const p = currentFlushPromise || resolvedPromise;
1454 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1455}
1456// #2768
1457// Use binary-search to find a suitable position in the queue,
1458// so that the queue maintains the increasing order of job's id,
1459// which can prevent the job from being skipped and also can avoid repeated patching.
1460function findInsertionIndex(job) {
1461 // the start index should be `flushIndex + 1`
1462 let start = flushIndex + 1;
1463 let end = queue.length;
1464 const jobId = getId(job);
1465 while (start < end) {
1466 const middle = (start + end) >>> 1;
1467 const middleJobId = getId(queue[middle]);
1468 middleJobId < jobId ? (start = middle + 1) : (end = middle);
1469 }
1470 return start;
1471}
1472function queueJob(job) {
1473 // the dedupe search uses the startIndex argument of Array.includes()
1474 // by default the search index includes the current job that is being run
1475 // so it cannot recursively trigger itself again.
1476 // if the job is a watch() callback, the search will start with a +1 index to
1477 // allow it recursively trigger itself - it is the user's responsibility to
1478 // ensure it doesn't end up in an infinite loop.
1479 if ((!queue.length ||
1480 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
1481 job !== currentPreFlushParentJob) {
1482 const pos = findInsertionIndex(job);
1483 if (pos > -1) {
1484 queue.splice(pos, 0, job);
1485 }
1486 else {
1487 queue.push(job);
1488 }
1489 queueFlush();
1490 }
1491}
1492function queueFlush() {
1493 if (!isFlushing && !isFlushPending) {
1494 isFlushPending = true;
1495 currentFlushPromise = resolvedPromise.then(flushJobs);
1496 }
1497}
1498function invalidateJob(job) {
1499 const i = queue.indexOf(job);
1500 if (i > -1) {
1501 queue.splice(i, 1);
1502 }
1503}
1504function queueCb(cb, activeQueue, pendingQueue, index) {
1505 if (!isArray(cb)) {
1506 if (!activeQueue ||
1507 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
1508 pendingQueue.push(cb);
1509 }
1510 }
1511 else {
1512 // if cb is an array, it is a component lifecycle hook which can only be
1513 // triggered by a job, which is already deduped in the main queue, so
1514 // we can skip duplicate check here to improve perf
1515 pendingQueue.push(...cb);
1516 }
1517 queueFlush();
1518}
1519function queuePreFlushCb(cb) {
1520 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
1521}
1522function queuePostFlushCb(cb) {
1523 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
1524}
1525function flushPreFlushCbs(seen, parentJob = null) {
1526 if (pendingPreFlushCbs.length) {
1527 currentPreFlushParentJob = parentJob;
1528 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
1529 pendingPreFlushCbs.length = 0;
1530 {
1531 seen = seen || new Map();
1532 }
1533 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
1534 {
1535 checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex]);
1536 }
1537 activePreFlushCbs[preFlushIndex]();
1538 }
1539 activePreFlushCbs = null;
1540 preFlushIndex = 0;
1541 currentPreFlushParentJob = null;
1542 // recursively flush until it drains
1543 flushPreFlushCbs(seen, parentJob);
1544 }
1545}
1546function flushPostFlushCbs(seen) {
1547 if (pendingPostFlushCbs.length) {
1548 const deduped = [...new Set(pendingPostFlushCbs)];
1549 pendingPostFlushCbs.length = 0;
1550 // #1947 already has active queue, nested flushPostFlushCbs call
1551 if (activePostFlushCbs) {
1552 activePostFlushCbs.push(...deduped);
1553 return;
1554 }
1555 activePostFlushCbs = deduped;
1556 {
1557 seen = seen || new Map();
1558 }
1559 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1560 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1561 {
1562 checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex]);
1563 }
1564 activePostFlushCbs[postFlushIndex]();
1565 }
1566 activePostFlushCbs = null;
1567 postFlushIndex = 0;
1568 }
1569}
1570const getId = (job) => job.id == null ? Infinity : job.id;
1571function flushJobs(seen) {
1572 isFlushPending = false;
1573 isFlushing = true;
1574 {
1575 seen = seen || new Map();
1576 }
1577 flushPreFlushCbs(seen);
1578 // Sort queue before flush.
1579 // This ensures that:
1580 // 1. Components are updated from parent to child. (because parent is always
1581 // created before the child so its render effect will have smaller
1582 // priority number)
1583 // 2. If a component is unmounted during a parent component's update,
1584 // its update can be skipped.
1585 queue.sort((a, b) => getId(a) - getId(b));
1586 try {
1587 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
1588 const job = queue[flushIndex];
1589 if (job) {
1590 if (true) {
1591 checkRecursiveUpdates(seen, job);
1592 }
1593 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
1594 }
1595 }
1596 }
1597 finally {
1598 flushIndex = 0;
1599 queue.length = 0;
1600 flushPostFlushCbs(seen);
1601 isFlushing = false;
1602 currentFlushPromise = null;
1603 // some postFlushCb queued jobs!
1604 // keep flushing until it drains.
1605 if (queue.length || pendingPostFlushCbs.length) {
1606 flushJobs(seen);
1607 }
1608 }
1609}
1610function checkRecursiveUpdates(seen, fn) {
1611 if (!seen.has(fn)) {
1612 seen.set(fn, 1);
1613 }
1614 else {
1615 const count = seen.get(fn);
1616 if (count > RECURSION_LIMIT) {
1617 throw new Error(`Maximum recursive updates exceeded. ` +
1618 `This means you have a reactive effect that is mutating its own ` +
1619 `dependencies and thus recursively triggering itself. Possible sources ` +
1620 `include component template, render function, updated hook or ` +
1621 `watcher source function.`);
1622 }
1623 else {
1624 seen.set(fn, count + 1);
1625 }
1626 }
1627}
1628
1629/* eslint-disable no-restricted-globals */
1630let isHmrUpdating = false;
1631const hmrDirtyComponents = new Set();
1632// Expose the HMR runtime on the global object
1633// This makes it entirely tree-shakable without polluting the exports and makes
1634// it easier to be used in toolings like vue-loader
1635// Note: for a component to be eligible for HMR it also needs the __hmrId option
1636// to be set so that its instances can be registered / removed.
1637{
1638 const globalObject = typeof global !== 'undefined'
1639 ? global
1640 : typeof self !== 'undefined'
1641 ? self
1642 : typeof window !== 'undefined'
1643 ? window
1644 : {};
1645 globalObject.__VUE_HMR_RUNTIME__ = {
1646 createRecord: tryWrap(createRecord),
1647 rerender: tryWrap(rerender),
1648 reload: tryWrap(reload)
1649 };
1650}
1651const map = new Map();
1652function registerHMR(instance) {
1653 const id = instance.type.__hmrId;
1654 let record = map.get(id);
1655 if (!record) {
1656 createRecord(id, instance.type);
1657 record = map.get(id);
1658 }
1659 record.instances.add(instance);
1660}
1661function unregisterHMR(instance) {
1662 map.get(instance.type.__hmrId).instances.delete(instance);
1663}
1664function createRecord(id, component) {
1665 if (!component) {
1666 warn(`HMR API usage is out of date.\n` +
1667 `Please upgrade vue-loader/vite/rollup-plugin-vue or other relevant ` +
1668 `dependency that handles Vue SFC compilation.`);
1669 component = {};
1670 }
1671 if (map.has(id)) {
1672 return false;
1673 }
1674 map.set(id, {
1675 component: isClassComponent(component) ? component.__vccOpts : component,
1676 instances: new Set()
1677 });
1678 return true;
1679}
1680function rerender(id, newRender) {
1681 const record = map.get(id);
1682 if (!record)
1683 return;
1684 if (newRender)
1685 record.component.render = newRender;
1686 // Array.from creates a snapshot which avoids the set being mutated during
1687 // updates
1688 Array.from(record.instances).forEach(instance => {
1689 if (newRender) {
1690 instance.render = newRender;
1691 }
1692 instance.renderCache = [];
1693 // this flag forces child components with slot content to update
1694 isHmrUpdating = true;
1695 instance.update();
1696 isHmrUpdating = false;
1697 });
1698}
1699function reload(id, newComp) {
1700 const record = map.get(id);
1701 if (!record)
1702 return;
1703 // Array.from creates a snapshot which avoids the set being mutated during
1704 // updates
1705 const { component, instances } = record;
1706 if (!hmrDirtyComponents.has(component)) {
1707 // 1. Update existing comp definition to match new one
1708 newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp;
1709 extend(component, newComp);
1710 for (const key in component) {
1711 if (!(key in newComp)) {
1712 delete component[key];
1713 }
1714 }
1715 // 2. Mark component dirty. This forces the renderer to replace the component
1716 // on patch.
1717 hmrDirtyComponents.add(component);
1718 // 3. Make sure to unmark the component after the reload.
1719 queuePostFlushCb(() => {
1720 hmrDirtyComponents.delete(component);
1721 });
1722 }
1723 Array.from(instances).forEach(instance => {
1724 if (instance.parent) {
1725 // 4. Force the parent instance to re-render. This will cause all updated
1726 // components to be unmounted and re-mounted. Queue the update so that we
1727 // don't end up forcing the same parent to re-render multiple times.
1728 queueJob(instance.parent.update);
1729 }
1730 else if (instance.appContext.reload) {
1731 // root instance mounted via createApp() has a reload method
1732 instance.appContext.reload();
1733 }
1734 else if (typeof window !== 'undefined') {
1735 // root instance inside tree created via raw render(). Force reload.
1736 window.location.reload();
1737 }
1738 else {
1739 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
1740 }
1741 });
1742}
1743function tryWrap(fn) {
1744 return (id, arg) => {
1745 try {
1746 return fn(id, arg);
1747 }
1748 catch (e) {
1749 console.error(e);
1750 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
1751 `Full reload required.`);
1752 }
1753 };
1754}
1755
1756let devtools;
1757function setDevtoolsHook(hook) {
1758 devtools = hook;
1759}
1760function devtoolsInitApp(app, version) {
1761 // TODO queue if devtools is undefined
1762 if (!devtools)
1763 return;
1764 devtools.emit("app:init" /* APP_INIT */, app, version, {
1765 Fragment,
1766 Text,
1767 Comment,
1768 Static
1769 });
1770}
1771function devtoolsUnmountApp(app) {
1772 if (!devtools)
1773 return;
1774 devtools.emit("app:unmount" /* APP_UNMOUNT */, app);
1775}
1776const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
1777const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
1778const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
1779function createDevtoolsComponentHook(hook) {
1780 return (component) => {
1781 if (!devtools)
1782 return;
1783 devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
1784 };
1785}
1786function devtoolsComponentEmit(component, event, params) {
1787 if (!devtools)
1788 return;
1789 devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
1790}
1791
1792function emit(instance, event, ...rawArgs) {
1793 const props = instance.vnode.props || EMPTY_OBJ;
1794 {
1795 const { emitsOptions, propsOptions: [propsOptions] } = instance;
1796 if (emitsOptions) {
1797 if (!(event in emitsOptions)) {
1798 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
1799 warn(`Component emitted event "${event}" but it is neither declared in ` +
1800 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
1801 }
1802 }
1803 else {
1804 const validator = emitsOptions[event];
1805 if (isFunction(validator)) {
1806 const isValid = validator(...rawArgs);
1807 if (!isValid) {
1808 warn(`Invalid event arguments: event validation failed for event "${event}".`);
1809 }
1810 }
1811 }
1812 }
1813 }
1814 let args = rawArgs;
1815 const isModelListener = event.startsWith('update:');
1816 // for v-model update:xxx events, apply modifiers on args
1817 const modelArg = isModelListener && event.slice(7);
1818 if (modelArg && modelArg in props) {
1819 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
1820 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
1821 if (trim) {
1822 args = rawArgs.map(a => a.trim());
1823 }
1824 else if (number) {
1825 args = rawArgs.map(toNumber);
1826 }
1827 }
1828 {
1829 devtoolsComponentEmit(instance, event, args);
1830 }
1831 {
1832 const lowerCaseEvent = event.toLowerCase();
1833 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
1834 warn(`Event "${lowerCaseEvent}" is emitted in component ` +
1835 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
1836 `Note that HTML attributes are case-insensitive and you cannot use ` +
1837 `v-on to listen to camelCase events when using in-DOM templates. ` +
1838 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
1839 }
1840 }
1841 // convert handler name to camelCase. See issue #2249
1842 let handlerName = toHandlerKey(camelize(event));
1843 let handler = props[handlerName];
1844 // for v-model update:xxx events, also trigger kebab-case equivalent
1845 // for props passed via kebab-case
1846 if (!handler && isModelListener) {
1847 handlerName = toHandlerKey(hyphenate(event));
1848 handler = props[handlerName];
1849 }
1850 if (handler) {
1851 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1852 }
1853 const onceHandler = props[handlerName + `Once`];
1854 if (onceHandler) {
1855 if (!instance.emitted) {
1856 (instance.emitted = {})[handlerName] = true;
1857 }
1858 else if (instance.emitted[handlerName]) {
1859 return;
1860 }
1861 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1862 }
1863}
1864function normalizeEmitsOptions(comp, appContext, asMixin = false) {
1865 if (!appContext.deopt && comp.__emits !== undefined) {
1866 return comp.__emits;
1867 }
1868 const raw = comp.emits;
1869 let normalized = {};
1870 // apply mixin/extends props
1871 let hasExtends = false;
1872 if (!isFunction(comp)) {
1873 const extendEmits = (raw) => {
1874 hasExtends = true;
1875 extend(normalized, normalizeEmitsOptions(raw, appContext, true));
1876 };
1877 if (!asMixin && appContext.mixins.length) {
1878 appContext.mixins.forEach(extendEmits);
1879 }
1880 if (comp.extends) {
1881 extendEmits(comp.extends);
1882 }
1883 if (comp.mixins) {
1884 comp.mixins.forEach(extendEmits);
1885 }
1886 }
1887 if (!raw && !hasExtends) {
1888 return (comp.__emits = null);
1889 }
1890 if (isArray(raw)) {
1891 raw.forEach(key => (normalized[key] = null));
1892 }
1893 else {
1894 extend(normalized, raw);
1895 }
1896 return (comp.__emits = normalized);
1897}
1898// Check if an incoming prop key is a declared emit event listener.
1899// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
1900// both considered matched listeners.
1901function isEmitListener(options, key) {
1902 if (!options || !isOn(key)) {
1903 return false;
1904 }
1905 key = key.slice(2).replace(/Once$/, '');
1906 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
1907 hasOwn(options, hyphenate(key)) ||
1908 hasOwn(options, key));
1909}
1910
1911/**
1912 * mark the current rendering instance for asset resolution (e.g.
1913 * resolveComponent, resolveDirective) during render
1914 */
1915let currentRenderingInstance = null;
1916function setCurrentRenderingInstance(instance) {
1917 currentRenderingInstance = instance;
1918}
1919/**
1920 * dev only flag to track whether $attrs was used during render.
1921 * If $attrs was used during render then the warning for failed attrs
1922 * fallthrough can be suppressed.
1923 */
1924let accessedAttrs = false;
1925function markAttrsAccessed() {
1926 accessedAttrs = true;
1927}
1928function renderComponentRoot(instance) {
1929 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance;
1930 let result;
1931 currentRenderingInstance = instance;
1932 {
1933 accessedAttrs = false;
1934 }
1935 try {
1936 let fallthroughAttrs;
1937 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
1938 // withProxy is a proxy with a different `has` trap only for
1939 // runtime-compiled render functions using `with` block.
1940 const proxyToUse = withProxy || proxy;
1941 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
1942 fallthroughAttrs = attrs;
1943 }
1944 else {
1945 // functional
1946 const render = Component;
1947 // in dev, mark attrs accessed if optional props (attrs === props)
1948 if (true && attrs === props) {
1949 markAttrsAccessed();
1950 }
1951 result = normalizeVNode(render.length > 1
1952 ? render(props, true
1953 ? {
1954 get attrs() {
1955 markAttrsAccessed();
1956 return attrs;
1957 },
1958 slots,
1959 emit
1960 }
1961 : { attrs, slots, emit })
1962 : render(props, null /* we know it doesn't need it */));
1963 fallthroughAttrs = Component.props
1964 ? attrs
1965 : getFunctionalFallthrough(attrs);
1966 }
1967 // attr merging
1968 // in dev mode, comments are preserved, and it's possible for a template
1969 // to have comments along side the root element which makes it a fragment
1970 let root = result;
1971 let setRoot = undefined;
1972 if (true &&
1973 result.patchFlag > 0 &&
1974 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
1975 ;
1976 [root, setRoot] = getChildRoot(result);
1977 }
1978 if (Component.inheritAttrs !== false && fallthroughAttrs) {
1979 const keys = Object.keys(fallthroughAttrs);
1980 const { shapeFlag } = root;
1981 if (keys.length) {
1982 if (shapeFlag & 1 /* ELEMENT */ ||
1983 shapeFlag & 6 /* COMPONENT */) {
1984 if (propsOptions && keys.some(isModelListener)) {
1985 // If a v-model listener (onUpdate:xxx) has a corresponding declared
1986 // prop, it indicates this component expects to handle v-model and
1987 // it should not fallthrough.
1988 // related: #1543, #1643, #1989
1989 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
1990 }
1991 root = cloneVNode(root, fallthroughAttrs);
1992 }
1993 else if (true && !accessedAttrs && root.type !== Comment) {
1994 const allAttrs = Object.keys(attrs);
1995 const eventAttrs = [];
1996 const extraAttrs = [];
1997 for (let i = 0, l = allAttrs.length; i < l; i++) {
1998 const key = allAttrs[i];
1999 if (isOn(key)) {
2000 // ignore v-model handlers when they fail to fallthrough
2001 if (!isModelListener(key)) {
2002 // remove `on`, lowercase first letter to reflect event casing
2003 // accurately
2004 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2005 }
2006 }
2007 else {
2008 extraAttrs.push(key);
2009 }
2010 }
2011 if (extraAttrs.length) {
2012 warn(`Extraneous non-props attributes (` +
2013 `${extraAttrs.join(', ')}) ` +
2014 `were passed to component but could not be automatically inherited ` +
2015 `because component renders fragment or text root nodes.`);
2016 }
2017 if (eventAttrs.length) {
2018 warn(`Extraneous non-emits event listeners (` +
2019 `${eventAttrs.join(', ')}) ` +
2020 `were passed to component but could not be automatically inherited ` +
2021 `because component renders fragment or text root nodes. ` +
2022 `If the listener is intended to be a component custom event listener only, ` +
2023 `declare it using the "emits" option.`);
2024 }
2025 }
2026 }
2027 }
2028 // inherit directives
2029 if (vnode.dirs) {
2030 if (true && !isElementRoot(root)) {
2031 warn(`Runtime directive used on component with non-element root node. ` +
2032 `The directives will not function as intended.`);
2033 }
2034 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2035 }
2036 // inherit transition data
2037 if (vnode.transition) {
2038 if (true && !isElementRoot(root)) {
2039 warn(`Component inside <Transition> renders non-element root node ` +
2040 `that cannot be animated.`);
2041 }
2042 root.transition = vnode.transition;
2043 }
2044 if (true && setRoot) {
2045 setRoot(root);
2046 }
2047 else {
2048 result = root;
2049 }
2050 }
2051 catch (err) {
2052 handleError(err, instance, 1 /* RENDER_FUNCTION */);
2053 result = createVNode(Comment);
2054 }
2055 currentRenderingInstance = null;
2056 return result;
2057}
2058/**
2059 * dev only
2060 * In dev mode, template root level comments are rendered, which turns the
2061 * template into a fragment root, but we need to locate the single element
2062 * root for attrs and scope id processing.
2063 */
2064const getChildRoot = (vnode) => {
2065 const rawChildren = vnode.children;
2066 const dynamicChildren = vnode.dynamicChildren;
2067 const childRoot = filterSingleRoot(rawChildren);
2068 if (!childRoot) {
2069 return [vnode, undefined];
2070 }
2071 const index = rawChildren.indexOf(childRoot);
2072 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2073 const setRoot = (updatedRoot) => {
2074 rawChildren[index] = updatedRoot;
2075 if (dynamicChildren) {
2076 if (dynamicIndex > -1) {
2077 dynamicChildren[dynamicIndex] = updatedRoot;
2078 }
2079 else if (updatedRoot.patchFlag > 0) {
2080 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2081 }
2082 }
2083 };
2084 return [normalizeVNode(childRoot), setRoot];
2085};
2086function filterSingleRoot(children) {
2087 let singleRoot;
2088 for (let i = 0; i < children.length; i++) {
2089 const child = children[i];
2090 if (isVNode(child)) {
2091 // ignore user comment
2092 if (child.type !== Comment || child.children === 'v-if') {
2093 if (singleRoot) {
2094 // has more than 1 non-comment child, return now
2095 return;
2096 }
2097 else {
2098 singleRoot = child;
2099 }
2100 }
2101 }
2102 else {
2103 return;
2104 }
2105 }
2106 return singleRoot;
2107}
2108const getFunctionalFallthrough = (attrs) => {
2109 let res;
2110 for (const key in attrs) {
2111 if (key === 'class' || key === 'style' || isOn(key)) {
2112 (res || (res = {}))[key] = attrs[key];
2113 }
2114 }
2115 return res;
2116};
2117const filterModelListeners = (attrs, props) => {
2118 const res = {};
2119 for (const key in attrs) {
2120 if (!isModelListener(key) || !(key.slice(9) in props)) {
2121 res[key] = attrs[key];
2122 }
2123 }
2124 return res;
2125};
2126const isElementRoot = (vnode) => {
2127 return (vnode.shapeFlag & 6 /* COMPONENT */ ||
2128 vnode.shapeFlag & 1 /* ELEMENT */ ||
2129 vnode.type === Comment // potential v-if branch switch
2130 );
2131};
2132function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2133 const { props: prevProps, children: prevChildren, component } = prevVNode;
2134 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2135 const emits = component.emitsOptions;
2136 // Parent component's render function was hot-updated. Since this may have
2137 // caused the child component's slots content to have changed, we need to
2138 // force the child to update as well.
2139 if ((prevChildren || nextChildren) && isHmrUpdating) {
2140 return true;
2141 }
2142 // force child update for runtime directive or transition on component vnode.
2143 if (nextVNode.dirs || nextVNode.transition) {
2144 return true;
2145 }
2146 if (optimized && patchFlag >= 0) {
2147 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2148 // slot content that references values that might have changed,
2149 // e.g. in a v-for
2150 return true;
2151 }
2152 if (patchFlag & 16 /* FULL_PROPS */) {
2153 if (!prevProps) {
2154 return !!nextProps;
2155 }
2156 // presence of this flag indicates props are always non-null
2157 return hasPropsChanged(prevProps, nextProps, emits);
2158 }
2159 else if (patchFlag & 8 /* PROPS */) {
2160 const dynamicProps = nextVNode.dynamicProps;
2161 for (let i = 0; i < dynamicProps.length; i++) {
2162 const key = dynamicProps[i];
2163 if (nextProps[key] !== prevProps[key] &&
2164 !isEmitListener(emits, key)) {
2165 return true;
2166 }
2167 }
2168 }
2169 }
2170 else {
2171 // this path is only taken by manually written render functions
2172 // so presence of any children leads to a forced update
2173 if (prevChildren || nextChildren) {
2174 if (!nextChildren || !nextChildren.$stable) {
2175 return true;
2176 }
2177 }
2178 if (prevProps === nextProps) {
2179 return false;
2180 }
2181 if (!prevProps) {
2182 return !!nextProps;
2183 }
2184 if (!nextProps) {
2185 return true;
2186 }
2187 return hasPropsChanged(prevProps, nextProps, emits);
2188 }
2189 return false;
2190}
2191function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2192 const nextKeys = Object.keys(nextProps);
2193 if (nextKeys.length !== Object.keys(prevProps).length) {
2194 return true;
2195 }
2196 for (let i = 0; i < nextKeys.length; i++) {
2197 const key = nextKeys[i];
2198 if (nextProps[key] !== prevProps[key] &&
2199 !isEmitListener(emitsOptions, key)) {
2200 return true;
2201 }
2202 }
2203 return false;
2204}
2205function updateHOCHostEl({ vnode, parent }, el // HostNode
2206) {
2207 while (parent && parent.subTree === vnode) {
2208 (vnode = parent.vnode).el = el;
2209 parent = parent.parent;
2210 }
2211}
2212
2213const isSuspense = (type) => type.__isSuspense;
2214// Suspense exposes a component-like API, and is treated like a component
2215// in the compiler, but internally it's a special built-in type that hooks
2216// directly into the renderer.
2217const SuspenseImpl = {
2218 // In order to make Suspense tree-shakable, we need to avoid importing it
2219 // directly in the renderer. The renderer checks for the __isSuspense flag
2220 // on a vnode's type and calls the `process` method, passing in renderer
2221 // internals.
2222 __isSuspense: true,
2223 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized,
2224 // platform-specific impl passed from renderer
2225 rendererInternals) {
2226 if (n1 == null) {
2227 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals);
2228 }
2229 else {
2230 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, rendererInternals);
2231 }
2232 },
2233 hydrate: hydrateSuspense,
2234 create: createSuspenseBoundary
2235};
2236// Force-casted public typing for h and TSX props inference
2237const Suspense = (SuspenseImpl
2238 );
2239function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals) {
2240 const { p: patch, o: { createElement } } = rendererInternals;
2241 const hiddenContainer = createElement('div');
2242 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals));
2243 // start mounting the content subtree in an off-dom container
2244 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG);
2245 // now check if we have encountered any async deps
2246 if (suspense.deps > 0) {
2247 // has async
2248 // mount the fallback tree
2249 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2250 isSVG);
2251 setActiveBranch(suspense, vnode.ssFallback);
2252 }
2253 else {
2254 // Suspense has no async deps. Just resolve.
2255 suspense.resolve();
2256 }
2257}
2258function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, { p: patch, um: unmount, o: { createElement } }) {
2259 const suspense = (n2.suspense = n1.suspense);
2260 suspense.vnode = n2;
2261 n2.el = n1.el;
2262 const newBranch = n2.ssContent;
2263 const newFallback = n2.ssFallback;
2264 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2265 if (pendingBranch) {
2266 suspense.pendingBranch = newBranch;
2267 if (isSameVNodeType(newBranch, pendingBranch)) {
2268 // same root type but content may have changed.
2269 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
2270 if (suspense.deps <= 0) {
2271 suspense.resolve();
2272 }
2273 else if (isInFallback) {
2274 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2275 isSVG);
2276 setActiveBranch(suspense, newFallback);
2277 }
2278 }
2279 else {
2280 // toggled before pending tree is resolved
2281 suspense.pendingId++;
2282 if (isHydrating) {
2283 // if toggled before hydration is finished, the current DOM tree is
2284 // no longer valid. set it as the active branch so it will be unmounted
2285 // when resolved
2286 suspense.isHydrating = false;
2287 suspense.activeBranch = pendingBranch;
2288 }
2289 else {
2290 unmount(pendingBranch, parentComponent, suspense);
2291 }
2292 // increment pending ID. this is used to invalidate async callbacks
2293 // reset suspense state
2294 suspense.deps = 0;
2295 // discard effects from pending branch
2296 suspense.effects.length = 0;
2297 // discard previous container
2298 suspense.hiddenContainer = createElement('div');
2299 if (isInFallback) {
2300 // already in fallback state
2301 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
2302 if (suspense.deps <= 0) {
2303 suspense.resolve();
2304 }
2305 else {
2306 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2307 isSVG);
2308 setActiveBranch(suspense, newFallback);
2309 }
2310 }
2311 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2312 // toggled "back" to current active branch
2313 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG);
2314 // force resolve
2315 suspense.resolve(true);
2316 }
2317 else {
2318 // switched to a 3rd branch
2319 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
2320 if (suspense.deps <= 0) {
2321 suspense.resolve();
2322 }
2323 }
2324 }
2325 }
2326 else {
2327 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2328 // root did not change, just normal patch
2329 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG);
2330 setActiveBranch(suspense, newBranch);
2331 }
2332 else {
2333 // root node toggled
2334 // invoke @pending event
2335 const onPending = n2.props && n2.props.onPending;
2336 if (isFunction(onPending)) {
2337 onPending();
2338 }
2339 // mount pending branch in off-dom container
2340 suspense.pendingBranch = newBranch;
2341 suspense.pendingId++;
2342 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
2343 if (suspense.deps <= 0) {
2344 // incoming branch has no async deps, resolve now.
2345 suspense.resolve();
2346 }
2347 else {
2348 const { timeout, pendingId } = suspense;
2349 if (timeout > 0) {
2350 setTimeout(() => {
2351 if (suspense.pendingId === pendingId) {
2352 suspense.fallback(newFallback);
2353 }
2354 }, timeout);
2355 }
2356 else if (timeout === 0) {
2357 suspense.fallback(newFallback);
2358 }
2359 }
2360 }
2361 }
2362}
2363let hasWarned = false;
2364function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals, isHydrating = false) {
2365 /* istanbul ignore if */
2366 if (!hasWarned) {
2367 hasWarned = true;
2368 // @ts-ignore `console.info` cannot be null error
2369 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2370 }
2371 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2372 const timeout = toNumber(vnode.props && vnode.props.timeout);
2373 const suspense = {
2374 vnode,
2375 parent,
2376 parentComponent,
2377 isSVG,
2378 container,
2379 hiddenContainer,
2380 anchor,
2381 deps: 0,
2382 pendingId: 0,
2383 timeout: typeof timeout === 'number' ? timeout : -1,
2384 activeBranch: null,
2385 pendingBranch: null,
2386 isInFallback: true,
2387 isHydrating,
2388 isUnmounted: false,
2389 effects: [],
2390 resolve(resume = false) {
2391 {
2392 if (!resume && !suspense.pendingBranch) {
2393 throw new Error(`suspense.resolve() is called without a pending branch.`);
2394 }
2395 if (suspense.isUnmounted) {
2396 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2397 }
2398 }
2399 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2400 if (suspense.isHydrating) {
2401 suspense.isHydrating = false;
2402 }
2403 else if (!resume) {
2404 const delayEnter = activeBranch &&
2405 pendingBranch.transition &&
2406 pendingBranch.transition.mode === 'out-in';
2407 if (delayEnter) {
2408 activeBranch.transition.afterLeave = () => {
2409 if (pendingId === suspense.pendingId) {
2410 move(pendingBranch, container, anchor, 0 /* ENTER */);
2411 }
2412 };
2413 }
2414 // this is initial anchor on mount
2415 let { anchor } = suspense;
2416 // unmount current active tree
2417 if (activeBranch) {
2418 // if the fallback tree was mounted, it may have been moved
2419 // as part of a parent suspense. get the latest anchor for insertion
2420 anchor = next(activeBranch);
2421 unmount(activeBranch, parentComponent, suspense, true);
2422 }
2423 if (!delayEnter) {
2424 // move content from off-dom container to actual container
2425 move(pendingBranch, container, anchor, 0 /* ENTER */);
2426 }
2427 }
2428 setActiveBranch(suspense, pendingBranch);
2429 suspense.pendingBranch = null;
2430 suspense.isInFallback = false;
2431 // flush buffered effects
2432 // check if there is a pending parent suspense
2433 let parent = suspense.parent;
2434 let hasUnresolvedAncestor = false;
2435 while (parent) {
2436 if (parent.pendingBranch) {
2437 // found a pending parent suspense, merge buffered post jobs
2438 // into that parent
2439 parent.effects.push(...effects);
2440 hasUnresolvedAncestor = true;
2441 break;
2442 }
2443 parent = parent.parent;
2444 }
2445 // no pending parent suspense, flush all jobs
2446 if (!hasUnresolvedAncestor) {
2447 queuePostFlushCb(effects);
2448 }
2449 suspense.effects = [];
2450 // invoke @resolve event
2451 const onResolve = vnode.props && vnode.props.onResolve;
2452 if (isFunction(onResolve)) {
2453 onResolve();
2454 }
2455 },
2456 fallback(fallbackVNode) {
2457 if (!suspense.pendingBranch) {
2458 return;
2459 }
2460 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2461 // invoke @fallback event
2462 const onFallback = vnode.props && vnode.props.onFallback;
2463 if (isFunction(onFallback)) {
2464 onFallback();
2465 }
2466 const anchor = next(activeBranch);
2467 const mountFallback = () => {
2468 if (!suspense.isInFallback) {
2469 return;
2470 }
2471 // mount the fallback tree
2472 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2473 isSVG);
2474 setActiveBranch(suspense, fallbackVNode);
2475 };
2476 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
2477 if (delayEnter) {
2478 activeBranch.transition.afterLeave = mountFallback;
2479 }
2480 // unmount current active branch
2481 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
2482 true // shouldRemove
2483 );
2484 suspense.isInFallback = true;
2485 if (!delayEnter) {
2486 mountFallback();
2487 }
2488 },
2489 move(container, anchor, type) {
2490 suspense.activeBranch &&
2491 move(suspense.activeBranch, container, anchor, type);
2492 suspense.container = container;
2493 },
2494 next() {
2495 return suspense.activeBranch && next(suspense.activeBranch);
2496 },
2497 registerDep(instance, setupRenderEffect) {
2498 const isInPendingSuspense = !!suspense.pendingBranch;
2499 if (isInPendingSuspense) {
2500 suspense.deps++;
2501 }
2502 const hydratedEl = instance.vnode.el;
2503 instance
2504 .asyncDep.catch(err => {
2505 handleError(err, instance, 0 /* SETUP_FUNCTION */);
2506 })
2507 .then(asyncSetupResult => {
2508 // retry when the setup() promise resolves.
2509 // component may have been unmounted before resolve.
2510 if (instance.isUnmounted ||
2511 suspense.isUnmounted ||
2512 suspense.pendingId !== instance.suspenseId) {
2513 return;
2514 }
2515 // retry from this component
2516 instance.asyncResolved = true;
2517 const { vnode } = instance;
2518 {
2519 pushWarningContext(vnode);
2520 }
2521 handleSetupResult(instance, asyncSetupResult);
2522 if (hydratedEl) {
2523 // vnode may have been replaced if an update happened before the
2524 // async dep is resolved.
2525 vnode.el = hydratedEl;
2526 }
2527 const placeholder = !hydratedEl && instance.subTree.el;
2528 setupRenderEffect(instance, vnode,
2529 // component may have been moved before resolve.
2530 // if this is not a hydration, instance.subTree will be the comment
2531 // placeholder.
2532 parentNode(hydratedEl || instance.subTree.el),
2533 // anchor will not be used if this is hydration, so only need to
2534 // consider the comment placeholder case.
2535 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
2536 if (placeholder) {
2537 remove(placeholder);
2538 }
2539 updateHOCHostEl(instance, vnode.el);
2540 {
2541 popWarningContext();
2542 }
2543 // only decrease deps count if suspense is not already resolved
2544 if (isInPendingSuspense && --suspense.deps === 0) {
2545 suspense.resolve();
2546 }
2547 });
2548 },
2549 unmount(parentSuspense, doRemove) {
2550 suspense.isUnmounted = true;
2551 if (suspense.activeBranch) {
2552 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
2553 }
2554 if (suspense.pendingBranch) {
2555 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
2556 }
2557 }
2558 };
2559 return suspense;
2560}
2561function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, optimized, rendererInternals, hydrateNode) {
2562 /* eslint-disable no-restricted-globals */
2563 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, optimized, rendererInternals, true /* hydrating */));
2564 // there are two possible scenarios for server-rendered suspense:
2565 // - success: ssr content should be fully resolved
2566 // - failure: ssr content should be the fallback branch.
2567 // however, on the client we don't really know if it has failed or not
2568 // attempt to hydrate the DOM assuming it has succeeded, but we still
2569 // need to construct a suspense boundary first
2570 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, optimized);
2571 if (suspense.deps === 0) {
2572 suspense.resolve();
2573 }
2574 return result;
2575 /* eslint-enable no-restricted-globals */
2576}
2577function normalizeSuspenseChildren(vnode) {
2578 const { shapeFlag, children } = vnode;
2579 let content;
2580 let fallback;
2581 if (shapeFlag & 32 /* SLOTS_CHILDREN */) {
2582 content = normalizeSuspenseSlot(children.default);
2583 fallback = normalizeSuspenseSlot(children.fallback);
2584 }
2585 else {
2586 content = normalizeSuspenseSlot(children);
2587 fallback = normalizeVNode(null);
2588 }
2589 return {
2590 content,
2591 fallback
2592 };
2593}
2594function normalizeSuspenseSlot(s) {
2595 if (isFunction(s)) {
2596 s = s();
2597 }
2598 if (isArray(s)) {
2599 const singleChild = filterSingleRoot(s);
2600 if (!singleChild) {
2601 warn(`<Suspense> slots expect a single root node.`);
2602 }
2603 s = singleChild;
2604 }
2605 return normalizeVNode(s);
2606}
2607function queueEffectWithSuspense(fn, suspense) {
2608 if (suspense && suspense.pendingBranch) {
2609 if (isArray(fn)) {
2610 suspense.effects.push(...fn);
2611 }
2612 else {
2613 suspense.effects.push(fn);
2614 }
2615 }
2616 else {
2617 queuePostFlushCb(fn);
2618 }
2619}
2620function setActiveBranch(suspense, branch) {
2621 suspense.activeBranch = branch;
2622 const { vnode, parentComponent } = suspense;
2623 const el = (vnode.el = branch.el);
2624 // in case suspense is the root node of a component,
2625 // recursively update the HOC el
2626 if (parentComponent && parentComponent.subTree === vnode) {
2627 parentComponent.vnode.el = el;
2628 updateHOCHostEl(parentComponent, el);
2629 }
2630}
2631
2632let isRenderingCompiledSlot = 0;
2633const setCompiledSlotRendering = (n) => (isRenderingCompiledSlot += n);
2634/**
2635 * Compiler runtime helper for rendering `<slot/>`
2636 * @private
2637 */
2638function renderSlot(slots, name, props = {},
2639// this is not a user-facing function, so the fallback is always generated by
2640// the compiler and guaranteed to be a function returning an array
2641fallback) {
2642 let slot = slots[name];
2643 if (slot && slot.length > 1) {
2644 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
2645 `function. You need to mark this component with $dynamic-slots in the ` +
2646 `parent template.`);
2647 slot = () => [];
2648 }
2649 // a compiled slot disables block tracking by default to avoid manual
2650 // invocation interfering with template-based block tracking, but in
2651 // `renderSlot` we can be sure that it's template-based so we can force
2652 // enable it.
2653 isRenderingCompiledSlot++;
2654 openBlock();
2655 const validSlotContent = slot && ensureValidVNode(slot(props));
2656 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
2657 ? 64 /* STABLE_FRAGMENT */
2658 : -2 /* BAIL */);
2659 isRenderingCompiledSlot--;
2660 return rendered;
2661}
2662function ensureValidVNode(vnodes) {
2663 return vnodes.some(child => {
2664 if (!isVNode(child))
2665 return true;
2666 if (child.type === Comment)
2667 return false;
2668 if (child.type === Fragment &&
2669 !ensureValidVNode(child.children))
2670 return false;
2671 return true;
2672 })
2673 ? vnodes
2674 : null;
2675}
2676
2677/**
2678 * Wrap a slot function to memoize current rendering instance
2679 * @private
2680 */
2681function withCtx(fn, ctx = currentRenderingInstance) {
2682 if (!ctx)
2683 return fn;
2684 const renderFnWithContext = (...args) => {
2685 // If a user calls a compiled slot inside a template expression (#1745), it
2686 // can mess up block tracking, so by default we need to push a null block to
2687 // avoid that. This isn't necessary if rendering a compiled `<slot>`.
2688 if (!isRenderingCompiledSlot) {
2689 openBlock(true /* null block that disables tracking */);
2690 }
2691 const owner = currentRenderingInstance;
2692 setCurrentRenderingInstance(ctx);
2693 const res = fn(...args);
2694 setCurrentRenderingInstance(owner);
2695 if (!isRenderingCompiledSlot) {
2696 closeBlock();
2697 }
2698 return res;
2699 };
2700 renderFnWithContext._c = true;
2701 return renderFnWithContext;
2702}
2703
2704// SFC scoped style ID management.
2705let currentScopeId = null;
2706const scopeIdStack = [];
2707/**
2708 * @private
2709 */
2710function pushScopeId(id) {
2711 scopeIdStack.push((currentScopeId = id));
2712}
2713/**
2714 * @private
2715 */
2716function popScopeId() {
2717 scopeIdStack.pop();
2718 currentScopeId = scopeIdStack[scopeIdStack.length - 1] || null;
2719}
2720/**
2721 * @private
2722 */
2723function withScopeId(id) {
2724 return ((fn) => withCtx(function () {
2725 pushScopeId(id);
2726 const res = fn.apply(this, arguments);
2727 popScopeId();
2728 return res;
2729 }));
2730}
2731
2732function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
2733isSSR = false) {
2734 const props = {};
2735 const attrs = {};
2736 def(attrs, InternalObjectKey, 1);
2737 setFullProps(instance, rawProps, props, attrs);
2738 // validation
2739 {
2740 validateProps(props, instance);
2741 }
2742 if (isStateful) {
2743 // stateful
2744 instance.props = isSSR ? props : shallowReactive(props);
2745 }
2746 else {
2747 if (!instance.type.props) {
2748 // functional w/ optional props, props === attrs
2749 instance.props = attrs;
2750 }
2751 else {
2752 // functional w/ declared props
2753 instance.props = props;
2754 }
2755 }
2756 instance.attrs = attrs;
2757}
2758function updateProps(instance, rawProps, rawPrevProps, optimized) {
2759 const { props, attrs, vnode: { patchFlag } } = instance;
2760 const rawCurrentProps = toRaw(props);
2761 const [options] = instance.propsOptions;
2762 if (
2763 // always force full diff in dev
2764 // - #1942 if hmr is enabled with sfc component
2765 // - vite#872 non-sfc component used by sfc component
2766 !((instance.type.__hmrId ||
2767 (instance.parent && instance.parent.type.__hmrId))) &&
2768 (optimized || patchFlag > 0) &&
2769 !(patchFlag & 16 /* FULL_PROPS */)) {
2770 if (patchFlag & 8 /* PROPS */) {
2771 // Compiler-generated props & no keys change, just set the updated
2772 // the props.
2773 const propsToUpdate = instance.vnode.dynamicProps;
2774 for (let i = 0; i < propsToUpdate.length; i++) {
2775 const key = propsToUpdate[i];
2776 // PROPS flag guarantees rawProps to be non-null
2777 const value = rawProps[key];
2778 if (options) {
2779 // attr / props separation was done on init and will be consistent
2780 // in this code path, so just check if attrs have it.
2781 if (hasOwn(attrs, key)) {
2782 attrs[key] = value;
2783 }
2784 else {
2785 const camelizedKey = camelize(key);
2786 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
2787 }
2788 }
2789 else {
2790 attrs[key] = value;
2791 }
2792 }
2793 }
2794 }
2795 else {
2796 // full props update.
2797 setFullProps(instance, rawProps, props, attrs);
2798 // in case of dynamic props, check if we need to delete keys from
2799 // the props object
2800 let kebabKey;
2801 for (const key in rawCurrentProps) {
2802 if (!rawProps ||
2803 // for camelCase
2804 (!hasOwn(rawProps, key) &&
2805 // it's possible the original props was passed in as kebab-case
2806 // and converted to camelCase (#955)
2807 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
2808 if (options) {
2809 if (rawPrevProps &&
2810 // for camelCase
2811 (rawPrevProps[key] !== undefined ||
2812 // for kebab-case
2813 rawPrevProps[kebabKey] !== undefined)) {
2814 props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
2815 }
2816 }
2817 else {
2818 delete props[key];
2819 }
2820 }
2821 }
2822 // in the case of functional component w/o props declaration, props and
2823 // attrs point to the same object so it should already have been updated.
2824 if (attrs !== rawCurrentProps) {
2825 for (const key in attrs) {
2826 if (!rawProps || !hasOwn(rawProps, key)) {
2827 delete attrs[key];
2828 }
2829 }
2830 }
2831 }
2832 // trigger updates for $attrs in case it's used in component slots
2833 trigger(instance, "set" /* SET */, '$attrs');
2834 if (rawProps) {
2835 validateProps(props, instance);
2836 }
2837}
2838function setFullProps(instance, rawProps, props, attrs) {
2839 const [options, needCastKeys] = instance.propsOptions;
2840 if (rawProps) {
2841 for (const key in rawProps) {
2842 const value = rawProps[key];
2843 // key, ref are reserved and never passed down
2844 if (isReservedProp(key)) {
2845 continue;
2846 }
2847 // prop option names are camelized during normalization, so to support
2848 // kebab -> camel conversion here we need to camelize the key.
2849 let camelKey;
2850 if (options && hasOwn(options, (camelKey = camelize(key)))) {
2851 props[camelKey] = value;
2852 }
2853 else if (!isEmitListener(instance.emitsOptions, key)) {
2854 // Any non-declared (either as a prop or an emitted event) props are put
2855 // into a separate `attrs` object for spreading. Make sure to preserve
2856 // original key casing
2857 attrs[key] = value;
2858 }
2859 }
2860 }
2861 if (needCastKeys) {
2862 const rawCurrentProps = toRaw(props);
2863 for (let i = 0; i < needCastKeys.length; i++) {
2864 const key = needCastKeys[i];
2865 props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
2866 }
2867 }
2868}
2869function resolvePropValue(options, props, key, value, instance) {
2870 const opt = options[key];
2871 if (opt != null) {
2872 const hasDefault = hasOwn(opt, 'default');
2873 // default values
2874 if (hasDefault && value === undefined) {
2875 const defaultValue = opt.default;
2876 if (opt.type !== Function && isFunction(defaultValue)) {
2877 setCurrentInstance(instance);
2878 value = defaultValue(props);
2879 setCurrentInstance(null);
2880 }
2881 else {
2882 value = defaultValue;
2883 }
2884 }
2885 // boolean casting
2886 if (opt[0 /* shouldCast */]) {
2887 if (!hasOwn(props, key) && !hasDefault) {
2888 value = false;
2889 }
2890 else if (opt[1 /* shouldCastTrue */] &&
2891 (value === '' || value === hyphenate(key))) {
2892 value = true;
2893 }
2894 }
2895 }
2896 return value;
2897}
2898function normalizePropsOptions(comp, appContext, asMixin = false) {
2899 if (!appContext.deopt && comp.__props) {
2900 return comp.__props;
2901 }
2902 const raw = comp.props;
2903 const normalized = {};
2904 const needCastKeys = [];
2905 // apply mixin/extends props
2906 let hasExtends = false;
2907 if (!isFunction(comp)) {
2908 const extendProps = (raw) => {
2909 hasExtends = true;
2910 const [props, keys] = normalizePropsOptions(raw, appContext, true);
2911 extend(normalized, props);
2912 if (keys)
2913 needCastKeys.push(...keys);
2914 };
2915 if (!asMixin && appContext.mixins.length) {
2916 appContext.mixins.forEach(extendProps);
2917 }
2918 if (comp.extends) {
2919 extendProps(comp.extends);
2920 }
2921 if (comp.mixins) {
2922 comp.mixins.forEach(extendProps);
2923 }
2924 }
2925 if (!raw && !hasExtends) {
2926 return (comp.__props = EMPTY_ARR);
2927 }
2928 if (isArray(raw)) {
2929 for (let i = 0; i < raw.length; i++) {
2930 if (!isString(raw[i])) {
2931 warn(`props must be strings when using array syntax.`, raw[i]);
2932 }
2933 const normalizedKey = camelize(raw[i]);
2934 if (validatePropName(normalizedKey)) {
2935 normalized[normalizedKey] = EMPTY_OBJ;
2936 }
2937 }
2938 }
2939 else if (raw) {
2940 if (!isObject(raw)) {
2941 warn(`invalid props options`, raw);
2942 }
2943 for (const key in raw) {
2944 const normalizedKey = camelize(key);
2945 if (validatePropName(normalizedKey)) {
2946 const opt = raw[key];
2947 const prop = (normalized[normalizedKey] =
2948 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
2949 if (prop) {
2950 const booleanIndex = getTypeIndex(Boolean, prop.type);
2951 const stringIndex = getTypeIndex(String, prop.type);
2952 prop[0 /* shouldCast */] = booleanIndex > -1;
2953 prop[1 /* shouldCastTrue */] =
2954 stringIndex < 0 || booleanIndex < stringIndex;
2955 // if the prop needs boolean casting or default value
2956 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
2957 needCastKeys.push(normalizedKey);
2958 }
2959 }
2960 }
2961 }
2962 }
2963 return (comp.__props = [normalized, needCastKeys]);
2964}
2965function validatePropName(key) {
2966 if (key[0] !== '$') {
2967 return true;
2968 }
2969 else {
2970 warn(`Invalid prop name: "${key}" is a reserved property.`);
2971 }
2972 return false;
2973}
2974// use function string name to check type constructors
2975// so that it works across vms / iframes.
2976function getType(ctor) {
2977 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
2978 return match ? match[1] : '';
2979}
2980function isSameType(a, b) {
2981 return getType(a) === getType(b);
2982}
2983function getTypeIndex(type, expectedTypes) {
2984 if (isArray(expectedTypes)) {
2985 for (let i = 0, len = expectedTypes.length; i < len; i++) {
2986 if (isSameType(expectedTypes[i], type)) {
2987 return i;
2988 }
2989 }
2990 }
2991 else if (isFunction(expectedTypes)) {
2992 return isSameType(expectedTypes, type) ? 0 : -1;
2993 }
2994 return -1;
2995}
2996/**
2997 * dev only
2998 */
2999function validateProps(props, instance) {
3000 const rawValues = toRaw(props);
3001 const options = instance.propsOptions[0];
3002 for (const key in options) {
3003 let opt = options[key];
3004 if (opt == null)
3005 continue;
3006 validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
3007 }
3008}
3009/**
3010 * dev only
3011 */
3012function validateProp(name, value, prop, isAbsent) {
3013 const { type, required, validator } = prop;
3014 // required!
3015 if (required && isAbsent) {
3016 warn('Missing required prop: "' + name + '"');
3017 return;
3018 }
3019 // missing but optional
3020 if (value == null && !prop.required) {
3021 return;
3022 }
3023 // type check
3024 if (type != null && type !== true) {
3025 let isValid = false;
3026 const types = isArray(type) ? type : [type];
3027 const expectedTypes = [];
3028 // value is valid as long as one of the specified types match
3029 for (let i = 0; i < types.length && !isValid; i++) {
3030 const { valid, expectedType } = assertType(value, types[i]);
3031 expectedTypes.push(expectedType || '');
3032 isValid = valid;
3033 }
3034 if (!isValid) {
3035 warn(getInvalidTypeMessage(name, value, expectedTypes));
3036 return;
3037 }
3038 }
3039 // custom validator
3040 if (validator && !validator(value)) {
3041 warn('Invalid prop: custom validator check failed for prop "' + name + '".');
3042 }
3043}
3044const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
3045/**
3046 * dev only
3047 */
3048function assertType(value, type) {
3049 let valid;
3050 const expectedType = getType(type);
3051 if (isSimpleType(expectedType)) {
3052 const t = typeof value;
3053 valid = t === expectedType.toLowerCase();
3054 // for primitive wrapper objects
3055 if (!valid && t === 'object') {
3056 valid = value instanceof type;
3057 }
3058 }
3059 else if (expectedType === 'Object') {
3060 valid = isObject(value);
3061 }
3062 else if (expectedType === 'Array') {
3063 valid = isArray(value);
3064 }
3065 else {
3066 valid = value instanceof type;
3067 }
3068 return {
3069 valid,
3070 expectedType
3071 };
3072}
3073/**
3074 * dev only
3075 */
3076function getInvalidTypeMessage(name, value, expectedTypes) {
3077 let message = `Invalid prop: type check failed for prop "${name}".` +
3078 ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
3079 const expectedType = expectedTypes[0];
3080 const receivedType = toRawType(value);
3081 const expectedValue = styleValue(value, expectedType);
3082 const receivedValue = styleValue(value, receivedType);
3083 // check if we need to specify expected value
3084 if (expectedTypes.length === 1 &&
3085 isExplicable(expectedType) &&
3086 !isBoolean(expectedType, receivedType)) {
3087 message += ` with value ${expectedValue}`;
3088 }
3089 message += `, got ${receivedType} `;
3090 // check if we need to specify received value
3091 if (isExplicable(receivedType)) {
3092 message += `with value ${receivedValue}.`;
3093 }
3094 return message;
3095}
3096/**
3097 * dev only
3098 */
3099function styleValue(value, type) {
3100 if (type === 'String') {
3101 return `"${value}"`;
3102 }
3103 else if (type === 'Number') {
3104 return `${Number(value)}`;
3105 }
3106 else {
3107 return `${value}`;
3108 }
3109}
3110/**
3111 * dev only
3112 */
3113function isExplicable(type) {
3114 const explicitTypes = ['string', 'number', 'boolean'];
3115 return explicitTypes.some(elem => type.toLowerCase() === elem);
3116}
3117/**
3118 * dev only
3119 */
3120function isBoolean(...args) {
3121 return args.some(elem => elem.toLowerCase() === 'boolean');
3122}
3123
3124function injectHook(type, hook, target = currentInstance, prepend = false) {
3125 if (target) {
3126 const hooks = target[type] || (target[type] = []);
3127 // cache the error handling wrapper for injected hooks so the same hook
3128 // can be properly deduped by the scheduler. "__weh" stands for "with error
3129 // handling".
3130 const wrappedHook = hook.__weh ||
3131 (hook.__weh = (...args) => {
3132 if (target.isUnmounted) {
3133 return;
3134 }
3135 // disable tracking inside all lifecycle hooks
3136 // since they can potentially be called inside effects.
3137 pauseTracking();
3138 // Set currentInstance during hook invocation.
3139 // This assumes the hook does not synchronously trigger other hooks, which
3140 // can only be false when the user does something really funky.
3141 setCurrentInstance(target);
3142 const res = callWithAsyncErrorHandling(hook, target, type, args);
3143 setCurrentInstance(null);
3144 resetTracking();
3145 return res;
3146 });
3147 if (prepend) {
3148 hooks.unshift(wrappedHook);
3149 }
3150 else {
3151 hooks.push(wrappedHook);
3152 }
3153 return wrappedHook;
3154 }
3155 else {
3156 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
3157 warn(`${apiName} is called when there is no active component instance to be ` +
3158 `associated with. ` +
3159 `Lifecycle injection APIs can only be used during execution of setup().` +
3160 (` If you are using async setup(), make sure to register lifecycle ` +
3161 `hooks before the first await statement.`
3162 ));
3163 }
3164}
3165const createHook = (lifecycle) => (hook, target = currentInstance) =>
3166// post-create lifecycle registrations are noops during SSR
3167!isInSSRComponentSetup && injectHook(lifecycle, hook, target);
3168const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
3169const onMounted = createHook("m" /* MOUNTED */);
3170const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
3171const onUpdated = createHook("u" /* UPDATED */);
3172const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
3173const onUnmounted = createHook("um" /* UNMOUNTED */);
3174const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
3175const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
3176const onErrorCaptured = (hook, target = currentInstance) => {
3177 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
3178};
3179
3180// Simple effect.
3181function watchEffect(effect, options) {
3182 return doWatch(effect, null, options);
3183}
3184// initial value for watchers to trigger on undefined initial values
3185const INITIAL_WATCHER_VALUE = {};
3186// implementation
3187function watch(source, cb, options) {
3188 if (!isFunction(cb)) {
3189 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3190 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3191 `supports \`watch(source, cb, options?) signature.`);
3192 }
3193 return doWatch(source, cb, options);
3194}
3195function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
3196 if (!cb) {
3197 if (immediate !== undefined) {
3198 warn(`watch() "immediate" option is only respected when using the ` +
3199 `watch(source, callback, options?) signature.`);
3200 }
3201 if (deep !== undefined) {
3202 warn(`watch() "deep" option is only respected when using the ` +
3203 `watch(source, callback, options?) signature.`);
3204 }
3205 }
3206 const warnInvalidSource = (s) => {
3207 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3208 `a reactive object, or an array of these types.`);
3209 };
3210 let getter;
3211 let forceTrigger = false;
3212 if (isRef(source)) {
3213 getter = () => source.value;
3214 forceTrigger = !!source._shallow;
3215 }
3216 else if (isReactive(source)) {
3217 getter = () => source;
3218 deep = true;
3219 }
3220 else if (isArray(source)) {
3221 getter = () => source.map(s => {
3222 if (isRef(s)) {
3223 return s.value;
3224 }
3225 else if (isReactive(s)) {
3226 return traverse(s);
3227 }
3228 else if (isFunction(s)) {
3229 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */, [
3230 instance && instance.proxy
3231 ]);
3232 }
3233 else {
3234 warnInvalidSource(s);
3235 }
3236 });
3237 }
3238 else if (isFunction(source)) {
3239 if (cb) {
3240 // getter with cb
3241 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */, [
3242 instance && instance.proxy
3243 ]);
3244 }
3245 else {
3246 // no cb -> simple effect
3247 getter = () => {
3248 if (instance && instance.isUnmounted) {
3249 return;
3250 }
3251 if (cleanup) {
3252 cleanup();
3253 }
3254 return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
3255 };
3256 }
3257 }
3258 else {
3259 getter = NOOP;
3260 warnInvalidSource(source);
3261 }
3262 if (cb && deep) {
3263 const baseGetter = getter;
3264 getter = () => traverse(baseGetter());
3265 }
3266 let cleanup;
3267 const onInvalidate = (fn) => {
3268 cleanup = runner.options.onStop = () => {
3269 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
3270 };
3271 };
3272 let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
3273 const job = () => {
3274 if (!runner.active) {
3275 return;
3276 }
3277 if (cb) {
3278 // watch(source, cb)
3279 const newValue = runner();
3280 if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
3281 // cleanup before running cb again
3282 if (cleanup) {
3283 cleanup();
3284 }
3285 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
3286 newValue,
3287 // pass undefined as the old value when it's changed for the first time
3288 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
3289 onInvalidate
3290 ]);
3291 oldValue = newValue;
3292 }
3293 }
3294 else {
3295 // watchEffect
3296 runner();
3297 }
3298 };
3299 // important: mark the job as a watcher callback so that scheduler knows
3300 // it is allowed to self-trigger (#1727)
3301 job.allowRecurse = !!cb;
3302 let scheduler;
3303 if (flush === 'sync') {
3304 scheduler = job;
3305 }
3306 else if (flush === 'post') {
3307 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3308 }
3309 else {
3310 // default: 'pre'
3311 scheduler = () => {
3312 if (!instance || instance.isMounted) {
3313 queuePreFlushCb(job);
3314 }
3315 else {
3316 // with 'pre' option, the first call must happen before
3317 // the component is mounted so it is called synchronously.
3318 job();
3319 }
3320 };
3321 }
3322 const runner = effect(getter, {
3323 lazy: true,
3324 onTrack,
3325 onTrigger,
3326 scheduler
3327 });
3328 recordInstanceBoundEffect(runner, instance);
3329 // initial run
3330 if (cb) {
3331 if (immediate) {
3332 job();
3333 }
3334 else {
3335 oldValue = runner();
3336 }
3337 }
3338 else if (flush === 'post') {
3339 queuePostRenderEffect(runner, instance && instance.suspense);
3340 }
3341 else {
3342 runner();
3343 }
3344 return () => {
3345 stop(runner);
3346 if (instance) {
3347 remove(instance.effects, runner);
3348 }
3349 };
3350}
3351// this.$watch
3352function instanceWatch(source, cb, options) {
3353 const publicThis = this.proxy;
3354 const getter = isString(source)
3355 ? () => publicThis[source]
3356 : source.bind(publicThis);
3357 return doWatch(getter, cb.bind(publicThis), options, this);
3358}
3359function traverse(value, seen = new Set()) {
3360 if (!isObject(value) || seen.has(value)) {
3361 return value;
3362 }
3363 seen.add(value);
3364 if (isRef(value)) {
3365 traverse(value.value, seen);
3366 }
3367 else if (isArray(value)) {
3368 for (let i = 0; i < value.length; i++) {
3369 traverse(value[i], seen);
3370 }
3371 }
3372 else if (isSet(value) || isMap(value)) {
3373 value.forEach((v) => {
3374 traverse(v, seen);
3375 });
3376 }
3377 else {
3378 for (const key in value) {
3379 traverse(value[key], seen);
3380 }
3381 }
3382 return value;
3383}
3384
3385function useTransitionState() {
3386 const state = {
3387 isMounted: false,
3388 isLeaving: false,
3389 isUnmounting: false,
3390 leavingVNodes: new Map()
3391 };
3392 onMounted(() => {
3393 state.isMounted = true;
3394 });
3395 onBeforeUnmount(() => {
3396 state.isUnmounting = true;
3397 });
3398 return state;
3399}
3400const TransitionHookValidator = [Function, Array];
3401const BaseTransitionImpl = {
3402 name: `BaseTransition`,
3403 props: {
3404 mode: String,
3405 appear: Boolean,
3406 persisted: Boolean,
3407 // enter
3408 onBeforeEnter: TransitionHookValidator,
3409 onEnter: TransitionHookValidator,
3410 onAfterEnter: TransitionHookValidator,
3411 onEnterCancelled: TransitionHookValidator,
3412 // leave
3413 onBeforeLeave: TransitionHookValidator,
3414 onLeave: TransitionHookValidator,
3415 onAfterLeave: TransitionHookValidator,
3416 onLeaveCancelled: TransitionHookValidator,
3417 // appear
3418 onBeforeAppear: TransitionHookValidator,
3419 onAppear: TransitionHookValidator,
3420 onAfterAppear: TransitionHookValidator,
3421 onAppearCancelled: TransitionHookValidator
3422 },
3423 setup(props, { slots }) {
3424 const instance = getCurrentInstance();
3425 const state = useTransitionState();
3426 let prevTransitionKey;
3427 return () => {
3428 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3429 if (!children || !children.length) {
3430 return;
3431 }
3432 // warn multiple elements
3433 if (children.length > 1) {
3434 warn('<transition> can only be used on a single element or component. Use ' +
3435 '<transition-group> for lists.');
3436 }
3437 // there's no need to track reactivity for these props so use the raw
3438 // props for a bit better perf
3439 const rawProps = toRaw(props);
3440 const { mode } = rawProps;
3441 // check mode
3442 if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
3443 warn(`invalid <transition> mode: ${mode}`);
3444 }
3445 // at this point children has a guaranteed length of 1.
3446 const child = children[0];
3447 if (state.isLeaving) {
3448 return emptyPlaceholder(child);
3449 }
3450 // in the case of <transition><keep-alive/></transition>, we need to
3451 // compare the type of the kept-alive children.
3452 const innerChild = getKeepAliveChild(child);
3453 if (!innerChild) {
3454 return emptyPlaceholder(child);
3455 }
3456 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3457 setTransitionHooks(innerChild, enterHooks);
3458 const oldChild = instance.subTree;
3459 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3460 let transitionKeyChanged = false;
3461 const { getTransitionKey } = innerChild.type;
3462 if (getTransitionKey) {
3463 const key = getTransitionKey();
3464 if (prevTransitionKey === undefined) {
3465 prevTransitionKey = key;
3466 }
3467 else if (key !== prevTransitionKey) {
3468 prevTransitionKey = key;
3469 transitionKeyChanged = true;
3470 }
3471 }
3472 // handle mode
3473 if (oldInnerChild &&
3474 oldInnerChild.type !== Comment &&
3475 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3476 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3477 // update old tree's hooks in case of dynamic transition
3478 setTransitionHooks(oldInnerChild, leavingHooks);
3479 // switching between different views
3480 if (mode === 'out-in') {
3481 state.isLeaving = true;
3482 // return placeholder node and queue update when leave finishes
3483 leavingHooks.afterLeave = () => {
3484 state.isLeaving = false;
3485 instance.update();
3486 };
3487 return emptyPlaceholder(child);
3488 }
3489 else if (mode === 'in-out') {
3490 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3491 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3492 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3493 // early removal callback
3494 el._leaveCb = () => {
3495 earlyRemove();
3496 el._leaveCb = undefined;
3497 delete enterHooks.delayedLeave;
3498 };
3499 enterHooks.delayedLeave = delayedLeave;
3500 };
3501 }
3502 }
3503 return child;
3504 };
3505 }
3506};
3507// export the public type for h/tsx inference
3508// also to avoid inline import() in generated d.ts files
3509const BaseTransition = BaseTransitionImpl;
3510function getLeavingNodesForType(state, vnode) {
3511 const { leavingVNodes } = state;
3512 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3513 if (!leavingVNodesCache) {
3514 leavingVNodesCache = Object.create(null);
3515 leavingVNodes.set(vnode.type, leavingVNodesCache);
3516 }
3517 return leavingVNodesCache;
3518}
3519// The transition hooks are attached to the vnode as vnode.transition
3520// and will be called at appropriate timing in the renderer.
3521function resolveTransitionHooks(vnode, props, state, instance) {
3522 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3523 const key = String(vnode.key);
3524 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3525 const callHook = (hook, args) => {
3526 hook &&
3527 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
3528 };
3529 const hooks = {
3530 mode,
3531 persisted,
3532 beforeEnter(el) {
3533 let hook = onBeforeEnter;
3534 if (!state.isMounted) {
3535 if (appear) {
3536 hook = onBeforeAppear || onBeforeEnter;
3537 }
3538 else {
3539 return;
3540 }
3541 }
3542 // for same element (v-show)
3543 if (el._leaveCb) {
3544 el._leaveCb(true /* cancelled */);
3545 }
3546 // for toggled element with same key (v-if)
3547 const leavingVNode = leavingVNodesCache[key];
3548 if (leavingVNode &&
3549 isSameVNodeType(vnode, leavingVNode) &&
3550 leavingVNode.el._leaveCb) {
3551 // force early removal (not cancelled)
3552 leavingVNode.el._leaveCb();
3553 }
3554 callHook(hook, [el]);
3555 },
3556 enter(el) {
3557 let hook = onEnter;
3558 let afterHook = onAfterEnter;
3559 let cancelHook = onEnterCancelled;
3560 if (!state.isMounted) {
3561 if (appear) {
3562 hook = onAppear || onEnter;
3563 afterHook = onAfterAppear || onAfterEnter;
3564 cancelHook = onAppearCancelled || onEnterCancelled;
3565 }
3566 else {
3567 return;
3568 }
3569 }
3570 let called = false;
3571 const done = (el._enterCb = (cancelled) => {
3572 if (called)
3573 return;
3574 called = true;
3575 if (cancelled) {
3576 callHook(cancelHook, [el]);
3577 }
3578 else {
3579 callHook(afterHook, [el]);
3580 }
3581 if (hooks.delayedLeave) {
3582 hooks.delayedLeave();
3583 }
3584 el._enterCb = undefined;
3585 });
3586 if (hook) {
3587 hook(el, done);
3588 if (hook.length <= 1) {
3589 done();
3590 }
3591 }
3592 else {
3593 done();
3594 }
3595 },
3596 leave(el, remove) {
3597 const key = String(vnode.key);
3598 if (el._enterCb) {
3599 el._enterCb(true /* cancelled */);
3600 }
3601 if (state.isUnmounting) {
3602 return remove();
3603 }
3604 callHook(onBeforeLeave, [el]);
3605 let called = false;
3606 const done = (el._leaveCb = (cancelled) => {
3607 if (called)
3608 return;
3609 called = true;
3610 remove();
3611 if (cancelled) {
3612 callHook(onLeaveCancelled, [el]);
3613 }
3614 else {
3615 callHook(onAfterLeave, [el]);
3616 }
3617 el._leaveCb = undefined;
3618 if (leavingVNodesCache[key] === vnode) {
3619 delete leavingVNodesCache[key];
3620 }
3621 });
3622 leavingVNodesCache[key] = vnode;
3623 if (onLeave) {
3624 onLeave(el, done);
3625 if (onLeave.length <= 1) {
3626 done();
3627 }
3628 }
3629 else {
3630 done();
3631 }
3632 },
3633 clone(vnode) {
3634 return resolveTransitionHooks(vnode, props, state, instance);
3635 }
3636 };
3637 return hooks;
3638}
3639// the placeholder really only handles one special case: KeepAlive
3640// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3641// placeholder with empty content to avoid the KeepAlive instance from being
3642// unmounted.
3643function emptyPlaceholder(vnode) {
3644 if (isKeepAlive(vnode)) {
3645 vnode = cloneVNode(vnode);
3646 vnode.children = null;
3647 return vnode;
3648 }
3649}
3650function getKeepAliveChild(vnode) {
3651 return isKeepAlive(vnode)
3652 ? vnode.children
3653 ? vnode.children[0]
3654 : undefined
3655 : vnode;
3656}
3657function setTransitionHooks(vnode, hooks) {
3658 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
3659 setTransitionHooks(vnode.component.subTree, hooks);
3660 }
3661 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
3662 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3663 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3664 }
3665 else {
3666 vnode.transition = hooks;
3667 }
3668}
3669function getTransitionRawChildren(children, keepComment = false) {
3670 let ret = [];
3671 let keyedFragmentCount = 0;
3672 for (let i = 0; i < children.length; i++) {
3673 const child = children[i];
3674 // handle fragment children case, e.g. v-for
3675 if (child.type === Fragment) {
3676 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
3677 keyedFragmentCount++;
3678 ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
3679 }
3680 // comment placeholders should be skipped, e.g. v-if
3681 else if (keepComment || child.type !== Comment) {
3682 ret.push(child);
3683 }
3684 }
3685 // #1126 if a transition children list contains multiple sub fragments, these
3686 // fragments will be merged into a flat children array. Since each v-for
3687 // fragment may contain different static bindings inside, we need to de-op
3688 // these children to force full diffs to ensure correct behavior.
3689 if (keyedFragmentCount > 1) {
3690 for (let i = 0; i < ret.length; i++) {
3691 ret[i].patchFlag = -2 /* BAIL */;
3692 }
3693 }
3694 return ret;
3695}
3696
3697const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3698const KeepAliveImpl = {
3699 name: `KeepAlive`,
3700 // Marker for special handling inside the renderer. We are not using a ===
3701 // check directly on KeepAlive in the renderer, because importing it directly
3702 // would prevent it from being tree-shaken.
3703 __isKeepAlive: true,
3704 props: {
3705 include: [String, RegExp, Array],
3706 exclude: [String, RegExp, Array],
3707 max: [String, Number]
3708 },
3709 setup(props, { slots }) {
3710 const cache = new Map();
3711 const keys = new Set();
3712 let current = null;
3713 const instance = getCurrentInstance();
3714 const parentSuspense = instance.suspense;
3715 // KeepAlive communicates with the instantiated renderer via the
3716 // ctx where the renderer passes in its internals,
3717 // and the KeepAlive instance exposes activate/deactivate implementations.
3718 // The whole point of this is to avoid importing KeepAlive directly in the
3719 // renderer to facilitate tree-shaking.
3720 const sharedContext = instance.ctx;
3721 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3722 const storageContainer = createElement('div');
3723 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3724 const instance = vnode.component;
3725 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3726 // in case props have changed
3727 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, optimized);
3728 queuePostRenderEffect(() => {
3729 instance.isDeactivated = false;
3730 if (instance.a) {
3731 invokeArrayFns(instance.a);
3732 }
3733 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3734 if (vnodeHook) {
3735 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3736 }
3737 }, parentSuspense);
3738 };
3739 sharedContext.deactivate = (vnode) => {
3740 const instance = vnode.component;
3741 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3742 queuePostRenderEffect(() => {
3743 if (instance.da) {
3744 invokeArrayFns(instance.da);
3745 }
3746 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3747 if (vnodeHook) {
3748 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3749 }
3750 instance.isDeactivated = true;
3751 }, parentSuspense);
3752 };
3753 function unmount(vnode) {
3754 // reset the shapeFlag so it can be properly unmounted
3755 resetShapeFlag(vnode);
3756 _unmount(vnode, instance, parentSuspense);
3757 }
3758 function pruneCache(filter) {
3759 cache.forEach((vnode, key) => {
3760 const name = getComponentName(vnode.type);
3761 if (name && (!filter || !filter(name))) {
3762 pruneCacheEntry(key);
3763 }
3764 });
3765 }
3766 function pruneCacheEntry(key) {
3767 const cached = cache.get(key);
3768 if (!current || cached.type !== current.type) {
3769 unmount(cached);
3770 }
3771 else if (current) {
3772 // current active instance should no longer be kept-alive.
3773 // we can't unmount it now but it might be later, so reset its flag now.
3774 resetShapeFlag(current);
3775 }
3776 cache.delete(key);
3777 keys.delete(key);
3778 }
3779 // prune cache on include/exclude prop change
3780 watch(() => [props.include, props.exclude], ([include, exclude]) => {
3781 include && pruneCache(name => matches(include, name));
3782 exclude && pruneCache(name => !matches(exclude, name));
3783 },
3784 // prune post-render after `current` has been updated
3785 { flush: 'post', deep: true });
3786 // cache sub tree after render
3787 let pendingCacheKey = null;
3788 const cacheSubtree = () => {
3789 // fix #1621, the pendingCacheKey could be 0
3790 if (pendingCacheKey != null) {
3791 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
3792 }
3793 };
3794 onMounted(cacheSubtree);
3795 onUpdated(cacheSubtree);
3796 onBeforeUnmount(() => {
3797 cache.forEach(cached => {
3798 const { subTree, suspense } = instance;
3799 const vnode = getInnerChild(subTree);
3800 if (cached.type === vnode.type) {
3801 // current instance will be unmounted as part of keep-alive's unmount
3802 resetShapeFlag(vnode);
3803 // but invoke its deactivated hook here
3804 const da = vnode.component.da;
3805 da && queuePostRenderEffect(da, suspense);
3806 return;
3807 }
3808 unmount(cached);
3809 });
3810 });
3811 return () => {
3812 pendingCacheKey = null;
3813 if (!slots.default) {
3814 return null;
3815 }
3816 const children = slots.default();
3817 const rawVNode = children[0];
3818 if (children.length > 1) {
3819 {
3820 warn(`KeepAlive should contain exactly one component child.`);
3821 }
3822 current = null;
3823 return children;
3824 }
3825 else if (!isVNode(rawVNode) ||
3826 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
3827 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
3828 current = null;
3829 return rawVNode;
3830 }
3831 let vnode = getInnerChild(rawVNode);
3832 const comp = vnode.type;
3833 const name = getComponentName(comp);
3834 const { include, exclude, max } = props;
3835 if ((include && (!name || !matches(include, name))) ||
3836 (exclude && name && matches(exclude, name))) {
3837 current = vnode;
3838 return rawVNode;
3839 }
3840 const key = vnode.key == null ? comp : vnode.key;
3841 const cachedVNode = cache.get(key);
3842 // clone vnode if it's reused because we are going to mutate it
3843 if (vnode.el) {
3844 vnode = cloneVNode(vnode);
3845 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
3846 rawVNode.ssContent = vnode;
3847 }
3848 }
3849 // #1513 it's possible for the returned vnode to be cloned due to attr
3850 // fallthrough or scopeId, so the vnode here may not be the final vnode
3851 // that is mounted. Instead of caching it directly, we store the pending
3852 // key and cache `instance.subTree` (the normalized vnode) in
3853 // beforeMount/beforeUpdate hooks.
3854 pendingCacheKey = key;
3855 if (cachedVNode) {
3856 // copy over mounted state
3857 vnode.el = cachedVNode.el;
3858 vnode.component = cachedVNode.component;
3859 if (vnode.transition) {
3860 // recursively update transition hooks on subTree
3861 setTransitionHooks(vnode, vnode.transition);
3862 }
3863 // avoid vnode being mounted as fresh
3864 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
3865 // make this key the freshest
3866 keys.delete(key);
3867 keys.add(key);
3868 }
3869 else {
3870 keys.add(key);
3871 // prune oldest entry
3872 if (max && keys.size > parseInt(max, 10)) {
3873 pruneCacheEntry(keys.values().next().value);
3874 }
3875 }
3876 // avoid vnode being unmounted
3877 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
3878 current = vnode;
3879 return rawVNode;
3880 };
3881 }
3882};
3883// export the public type for h/tsx inference
3884// also to avoid inline import() in generated d.ts files
3885const KeepAlive = KeepAliveImpl;
3886function matches(pattern, name) {
3887 if (isArray(pattern)) {
3888 return pattern.some((p) => matches(p, name));
3889 }
3890 else if (isString(pattern)) {
3891 return pattern.split(',').indexOf(name) > -1;
3892 }
3893 else if (pattern.test) {
3894 return pattern.test(name);
3895 }
3896 /* istanbul ignore next */
3897 return false;
3898}
3899function onActivated(hook, target) {
3900 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
3901}
3902function onDeactivated(hook, target) {
3903 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
3904}
3905function registerKeepAliveHook(hook, type, target = currentInstance) {
3906 // cache the deactivate branch check wrapper for injected hooks so the same
3907 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
3908 // deactivation check".
3909 const wrappedHook = hook.__wdc ||
3910 (hook.__wdc = () => {
3911 // only fire the hook if the target instance is NOT in a deactivated branch.
3912 let current = target;
3913 while (current) {
3914 if (current.isDeactivated) {
3915 return;
3916 }
3917 current = current.parent;
3918 }
3919 hook();
3920 });
3921 injectHook(type, wrappedHook, target);
3922 // In addition to registering it on the target instance, we walk up the parent
3923 // chain and register it on all ancestor instances that are keep-alive roots.
3924 // This avoids the need to walk the entire component tree when invoking these
3925 // hooks, and more importantly, avoids the need to track child components in
3926 // arrays.
3927 if (target) {
3928 let current = target.parent;
3929 while (current && current.parent) {
3930 if (isKeepAlive(current.parent.vnode)) {
3931 injectToKeepAliveRoot(wrappedHook, type, target, current);
3932 }
3933 current = current.parent;
3934 }
3935 }
3936}
3937function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
3938 // injectHook wraps the original for error handling, so make sure to remove
3939 // the wrapped version.
3940 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
3941 onUnmounted(() => {
3942 remove(keepAliveRoot[type], injected);
3943 }, target);
3944}
3945function resetShapeFlag(vnode) {
3946 let shapeFlag = vnode.shapeFlag;
3947 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
3948 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
3949 }
3950 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
3951 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
3952 }
3953 vnode.shapeFlag = shapeFlag;
3954}
3955function getInnerChild(vnode) {
3956 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
3957}
3958
3959const isInternalKey = (key) => key[0] === '_' || key === '$stable';
3960const normalizeSlotValue = (value) => isArray(value)
3961 ? value.map(normalizeVNode)
3962 : [normalizeVNode(value)];
3963const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => {
3964 if (currentInstance) {
3965 warn(`Slot "${key}" invoked outside of the render function: ` +
3966 `this will not track dependencies used in the slot. ` +
3967 `Invoke the slot function inside the render function instead.`);
3968 }
3969 return normalizeSlotValue(rawSlot(props));
3970}, ctx);
3971const normalizeObjectSlots = (rawSlots, slots) => {
3972 const ctx = rawSlots._ctx;
3973 for (const key in rawSlots) {
3974 if (isInternalKey(key))
3975 continue;
3976 const value = rawSlots[key];
3977 if (isFunction(value)) {
3978 slots[key] = normalizeSlot(key, value, ctx);
3979 }
3980 else if (value != null) {
3981 {
3982 warn(`Non-function value encountered for slot "${key}". ` +
3983 `Prefer function slots for better performance.`);
3984 }
3985 const normalized = normalizeSlotValue(value);
3986 slots[key] = () => normalized;
3987 }
3988 }
3989};
3990const normalizeVNodeSlots = (instance, children) => {
3991 if (!isKeepAlive(instance.vnode)) {
3992 warn(`Non-function value encountered for default slot. ` +
3993 `Prefer function slots for better performance.`);
3994 }
3995 const normalized = normalizeSlotValue(children);
3996 instance.slots.default = () => normalized;
3997};
3998const initSlots = (instance, children) => {
3999 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4000 const type = children._;
4001 if (type) {
4002 instance.slots = children;
4003 // make compiler marker non-enumerable
4004 def(children, '_', type);
4005 }
4006 else {
4007 normalizeObjectSlots(children, (instance.slots = {}));
4008 }
4009 }
4010 else {
4011 instance.slots = {};
4012 if (children) {
4013 normalizeVNodeSlots(instance, children);
4014 }
4015 }
4016 def(instance.slots, InternalObjectKey, 1);
4017};
4018const updateSlots = (instance, children) => {
4019 const { vnode, slots } = instance;
4020 let needDeletionCheck = true;
4021 let deletionComparisonTarget = EMPTY_OBJ;
4022 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4023 const type = children._;
4024 if (type) {
4025 // compiled slots.
4026 if (isHmrUpdating) {
4027 // Parent was HMR updated so slot content may have changed.
4028 // force update slots and mark instance for hmr as well
4029 extend(slots, children);
4030 }
4031 else if (type === 1 /* STABLE */) {
4032 // compiled AND stable.
4033 // no need to update, and skip stale slots removal.
4034 needDeletionCheck = false;
4035 }
4036 else {
4037 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
4038 // normalization.
4039 extend(slots, children);
4040 }
4041 }
4042 else {
4043 needDeletionCheck = !children.$stable;
4044 normalizeObjectSlots(children, slots);
4045 }
4046 deletionComparisonTarget = children;
4047 }
4048 else if (children) {
4049 // non slot object children (direct value) passed to a component
4050 normalizeVNodeSlots(instance, children);
4051 deletionComparisonTarget = { default: 1 };
4052 }
4053 // delete stale slots
4054 if (needDeletionCheck) {
4055 for (const key in slots) {
4056 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
4057 delete slots[key];
4058 }
4059 }
4060 }
4061};
4062
4063/**
4064Runtime helper for applying directives to a vnode. Example usage:
4065
4066const comp = resolveComponent('comp')
4067const foo = resolveDirective('foo')
4068const bar = resolveDirective('bar')
4069
4070return withDirectives(h(comp), [
4071 [foo, this.x],
4072 [bar, this.y]
4073])
4074*/
4075const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
4076function validateDirectiveName(name) {
4077 if (isBuiltInDirective(name)) {
4078 warn('Do not use built-in directive ids as custom directive id: ' + name);
4079 }
4080}
4081/**
4082 * Adds directives to a VNode.
4083 */
4084function withDirectives(vnode, directives) {
4085 const internalInstance = currentRenderingInstance;
4086 if (internalInstance === null) {
4087 warn(`withDirectives can only be used inside render functions.`);
4088 return vnode;
4089 }
4090 const instance = internalInstance.proxy;
4091 const bindings = vnode.dirs || (vnode.dirs = []);
4092 for (let i = 0; i < directives.length; i++) {
4093 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4094 if (isFunction(dir)) {
4095 dir = {
4096 mounted: dir,
4097 updated: dir
4098 };
4099 }
4100 bindings.push({
4101 dir,
4102 instance,
4103 value,
4104 oldValue: void 0,
4105 arg,
4106 modifiers
4107 });
4108 }
4109 return vnode;
4110}
4111function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4112 const bindings = vnode.dirs;
4113 const oldBindings = prevVNode && prevVNode.dirs;
4114 for (let i = 0; i < bindings.length; i++) {
4115 const binding = bindings[i];
4116 if (oldBindings) {
4117 binding.oldValue = oldBindings[i].value;
4118 }
4119 const hook = binding.dir[name];
4120 if (hook) {
4121 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4122 vnode.el,
4123 binding,
4124 vnode,
4125 prevVNode
4126 ]);
4127 }
4128 }
4129}
4130
4131function createAppContext() {
4132 return {
4133 app: null,
4134 config: {
4135 isNativeTag: NO,
4136 performance: false,
4137 globalProperties: {},
4138 optionMergeStrategies: {},
4139 isCustomElement: NO,
4140 errorHandler: undefined,
4141 warnHandler: undefined
4142 },
4143 mixins: [],
4144 components: {},
4145 directives: {},
4146 provides: Object.create(null)
4147 };
4148}
4149let uid$1 = 0;
4150function createAppAPI(render, hydrate) {
4151 return function createApp(rootComponent, rootProps = null) {
4152 if (rootProps != null && !isObject(rootProps)) {
4153 warn(`root props passed to app.mount() must be an object.`);
4154 rootProps = null;
4155 }
4156 const context = createAppContext();
4157 const installedPlugins = new Set();
4158 let isMounted = false;
4159 const app = (context.app = {
4160 _uid: uid$1++,
4161 _component: rootComponent,
4162 _props: rootProps,
4163 _container: null,
4164 _context: context,
4165 version,
4166 get config() {
4167 return context.config;
4168 },
4169 set config(v) {
4170 {
4171 warn(`app.config cannot be replaced. Modify individual options instead.`);
4172 }
4173 },
4174 use(plugin, ...options) {
4175 if (installedPlugins.has(plugin)) {
4176 warn(`Plugin has already been applied to target app.`);
4177 }
4178 else if (plugin && isFunction(plugin.install)) {
4179 installedPlugins.add(plugin);
4180 plugin.install(app, ...options);
4181 }
4182 else if (isFunction(plugin)) {
4183 installedPlugins.add(plugin);
4184 plugin(app, ...options);
4185 }
4186 else {
4187 warn(`A plugin must either be a function or an object with an "install" ` +
4188 `function.`);
4189 }
4190 return app;
4191 },
4192 mixin(mixin) {
4193 {
4194 if (!context.mixins.includes(mixin)) {
4195 context.mixins.push(mixin);
4196 // global mixin with props/emits de-optimizes props/emits
4197 // normalization caching.
4198 if (mixin.props || mixin.emits) {
4199 context.deopt = true;
4200 }
4201 }
4202 else {
4203 warn('Mixin has already been applied to target app' +
4204 (mixin.name ? `: ${mixin.name}` : ''));
4205 }
4206 }
4207 return app;
4208 },
4209 component(name, component) {
4210 {
4211 validateComponentName(name, context.config);
4212 }
4213 if (!component) {
4214 return context.components[name];
4215 }
4216 if (context.components[name]) {
4217 warn(`Component "${name}" has already been registered in target app.`);
4218 }
4219 context.components[name] = component;
4220 return app;
4221 },
4222 directive(name, directive) {
4223 {
4224 validateDirectiveName(name);
4225 }
4226 if (!directive) {
4227 return context.directives[name];
4228 }
4229 if (context.directives[name]) {
4230 warn(`Directive "${name}" has already been registered in target app.`);
4231 }
4232 context.directives[name] = directive;
4233 return app;
4234 },
4235 mount(rootContainer, isHydrate) {
4236 if (!isMounted) {
4237 const vnode = createVNode(rootComponent, rootProps);
4238 // store app context on the root VNode.
4239 // this will be set on the root instance on initial mount.
4240 vnode.appContext = context;
4241 // HMR root reload
4242 {
4243 context.reload = () => {
4244 render(cloneVNode(vnode), rootContainer);
4245 };
4246 }
4247 if (isHydrate && hydrate) {
4248 hydrate(vnode, rootContainer);
4249 }
4250 else {
4251 render(vnode, rootContainer);
4252 }
4253 isMounted = true;
4254 app._container = rootContainer;
4255 rootContainer.__vue_app__ = app;
4256 {
4257 devtoolsInitApp(app, version);
4258 }
4259 return vnode.component.proxy;
4260 }
4261 else {
4262 warn(`App has already been mounted.\n` +
4263 `If you want to remount the same app, move your app creation logic ` +
4264 `into a factory function and create fresh app instances for each ` +
4265 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
4266 }
4267 },
4268 unmount() {
4269 if (isMounted) {
4270 render(null, app._container);
4271 {
4272 devtoolsUnmountApp(app);
4273 }
4274 delete app._container.__vue_app__;
4275 }
4276 else {
4277 warn(`Cannot unmount an app that is not mounted.`);
4278 }
4279 },
4280 provide(key, value) {
4281 if (key in context.provides) {
4282 warn(`App already provides property with key "${String(key)}". ` +
4283 `It will be overwritten with the new value.`);
4284 }
4285 // TypeScript doesn't allow symbols as index type
4286 // https://github.com/Microsoft/TypeScript/issues/24587
4287 context.provides[key] = value;
4288 return app;
4289 }
4290 });
4291 return app;
4292 };
4293}
4294
4295let hasMismatch = false;
4296const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4297const isComment = (node) => node.nodeType === 8 /* COMMENT */;
4298// Note: hydration is DOM-specific
4299// But we have to place it in core due to tight coupling with core - splitting
4300// it out creates a ton of unnecessary complexity.
4301// Hydration also depends on some renderer internal logic which needs to be
4302// passed in via arguments.
4303function createHydrationFunctions(rendererInternals) {
4304 const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
4305 const hydrate = (vnode, container) => {
4306 if (!container.hasChildNodes()) {
4307 warn(`Attempting to hydrate existing markup but container is empty. ` +
4308 `Performing full mount instead.`);
4309 patch(null, vnode, container);
4310 return;
4311 }
4312 hasMismatch = false;
4313 hydrateNode(container.firstChild, vnode, null, null);
4314 flushPostFlushCbs();
4315 if (hasMismatch && !false) {
4316 // this error should show up in production
4317 console.error(`Hydration completed but contains mismatches.`);
4318 }
4319 };
4320 const hydrateNode = (node, vnode, parentComponent, parentSuspense, optimized = false) => {
4321 const isFragmentStart = isComment(node) && node.data === '[';
4322 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, isFragmentStart);
4323 const { type, ref, shapeFlag } = vnode;
4324 const domType = node.nodeType;
4325 vnode.el = node;
4326 let nextNode = null;
4327 switch (type) {
4328 case Text:
4329 if (domType !== 3 /* TEXT */) {
4330 nextNode = onMismatch();
4331 }
4332 else {
4333 if (node.data !== vnode.children) {
4334 hasMismatch = true;
4335 warn(`Hydration text mismatch:` +
4336 `\n- Client: ${JSON.stringify(node.data)}` +
4337 `\n- Server: ${JSON.stringify(vnode.children)}`);
4338 node.data = vnode.children;
4339 }
4340 nextNode = nextSibling(node);
4341 }
4342 break;
4343 case Comment:
4344 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
4345 nextNode = onMismatch();
4346 }
4347 else {
4348 nextNode = nextSibling(node);
4349 }
4350 break;
4351 case Static:
4352 if (domType !== 1 /* ELEMENT */) {
4353 nextNode = onMismatch();
4354 }
4355 else {
4356 // determine anchor, adopt content
4357 nextNode = node;
4358 // if the static vnode has its content stripped during build,
4359 // adopt it from the server-rendered HTML.
4360 const needToAdoptContent = !vnode.children.length;
4361 for (let i = 0; i < vnode.staticCount; i++) {
4362 if (needToAdoptContent)
4363 vnode.children += nextNode.outerHTML;
4364 if (i === vnode.staticCount - 1) {
4365 vnode.anchor = nextNode;
4366 }
4367 nextNode = nextSibling(nextNode);
4368 }
4369 return nextNode;
4370 }
4371 break;
4372 case Fragment:
4373 if (!isFragmentStart) {
4374 nextNode = onMismatch();
4375 }
4376 else {
4377 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, optimized);
4378 }
4379 break;
4380 default:
4381 if (shapeFlag & 1 /* ELEMENT */) {
4382 if (domType !== 1 /* ELEMENT */ ||
4383 vnode.type !== node.tagName.toLowerCase()) {
4384 nextNode = onMismatch();
4385 }
4386 else {
4387 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, optimized);
4388 }
4389 }
4390 else if (shapeFlag & 6 /* COMPONENT */) {
4391 // when setting up the render effect, if the initial vnode already
4392 // has .el set, the component will perform hydration instead of mount
4393 // on its sub-tree.
4394 const container = parentNode(node);
4395 const hydrateComponent = () => {
4396 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
4397 };
4398 // async component
4399 const loadAsync = vnode.type.__asyncLoader;
4400 if (loadAsync) {
4401 loadAsync().then(hydrateComponent);
4402 }
4403 else {
4404 hydrateComponent();
4405 }
4406 // component may be async, so in the case of fragments we cannot rely
4407 // on component's rendered output to determine the end of the fragment
4408 // instead, we do a lookahead to find the end anchor node.
4409 nextNode = isFragmentStart
4410 ? locateClosingAsyncAnchor(node)
4411 : nextSibling(node);
4412 }
4413 else if (shapeFlag & 64 /* TELEPORT */) {
4414 if (domType !== 8 /* COMMENT */) {
4415 nextNode = onMismatch();
4416 }
4417 else {
4418 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, optimized, rendererInternals, hydrateChildren);
4419 }
4420 }
4421 else if (shapeFlag & 128 /* SUSPENSE */) {
4422 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), optimized, rendererInternals, hydrateNode);
4423 }
4424 else {
4425 warn('Invalid HostVNode type:', type, `(${typeof type})`);
4426 }
4427 }
4428 if (ref != null) {
4429 setRef(ref, null, parentSuspense, vnode);
4430 }
4431 return nextNode;
4432 };
4433 const hydrateElement = (el, vnode, parentComponent, parentSuspense, optimized) => {
4434 optimized = optimized || !!vnode.dynamicChildren;
4435 const { props, patchFlag, shapeFlag, dirs } = vnode;
4436 // skip props & children if this is hoisted static nodes
4437 if (patchFlag !== -1 /* HOISTED */) {
4438 if (dirs) {
4439 invokeDirectiveHook(vnode, null, parentComponent, 'created');
4440 }
4441 // props
4442 if (props) {
4443 if (!optimized ||
4444 (patchFlag & 16 /* FULL_PROPS */ ||
4445 patchFlag & 32 /* HYDRATE_EVENTS */)) {
4446 for (const key in props) {
4447 if (!isReservedProp(key) && isOn(key)) {
4448 patchProp(el, key, null, props[key]);
4449 }
4450 }
4451 }
4452 else if (props.onClick) {
4453 // Fast path for click listeners (which is most often) to avoid
4454 // iterating through props.
4455 patchProp(el, 'onClick', null, props.onClick);
4456 }
4457 }
4458 // vnode / directive hooks
4459 let vnodeHooks;
4460 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
4461 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4462 }
4463 if (dirs) {
4464 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
4465 }
4466 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
4467 queueEffectWithSuspense(() => {
4468 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4469 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
4470 }, parentSuspense);
4471 }
4472 // children
4473 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
4474 // skip if element has innerHTML / textContent
4475 !(props && (props.innerHTML || props.textContent))) {
4476 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, optimized);
4477 let hasWarned = false;
4478 while (next) {
4479 hasMismatch = true;
4480 if (!hasWarned) {
4481 warn(`Hydration children mismatch in <${vnode.type}>: ` +
4482 `server rendered element contains more child nodes than client vdom.`);
4483 hasWarned = true;
4484 }
4485 // The SSRed DOM contains more nodes than it should. Remove them.
4486 const cur = next;
4487 next = next.nextSibling;
4488 remove(cur);
4489 }
4490 }
4491 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
4492 if (el.textContent !== vnode.children) {
4493 hasMismatch = true;
4494 warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
4495 `- Client: ${el.textContent}\n` +
4496 `- Server: ${vnode.children}`);
4497 el.textContent = vnode.children;
4498 }
4499 }
4500 }
4501 return el.nextSibling;
4502 };
4503 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, optimized) => {
4504 optimized = optimized || !!parentVNode.dynamicChildren;
4505 const children = parentVNode.children;
4506 const l = children.length;
4507 let hasWarned = false;
4508 for (let i = 0; i < l; i++) {
4509 const vnode = optimized
4510 ? children[i]
4511 : (children[i] = normalizeVNode(children[i]));
4512 if (node) {
4513 node = hydrateNode(node, vnode, parentComponent, parentSuspense, optimized);
4514 }
4515 else {
4516 hasMismatch = true;
4517 if (!hasWarned) {
4518 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
4519 `server rendered element contains fewer child nodes than client vdom.`);
4520 hasWarned = true;
4521 }
4522 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
4523 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container));
4524 }
4525 }
4526 return node;
4527 };
4528 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, optimized) => {
4529 const container = parentNode(node);
4530 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, optimized);
4531 if (next && isComment(next) && next.data === ']') {
4532 return nextSibling((vnode.anchor = next));
4533 }
4534 else {
4535 // fragment didn't hydrate successfully, since we didn't get a end anchor
4536 // back. This should have led to node/children mismatch warnings.
4537 hasMismatch = true;
4538 // since the anchor is missing, we need to create one and insert it
4539 insert((vnode.anchor = createComment(`]`)), container, next);
4540 return next;
4541 }
4542 };
4543 const handleMismatch = (node, vnode, parentComponent, parentSuspense, isFragment) => {
4544 hasMismatch = true;
4545 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
4546 ? `(text)`
4547 : isComment(node) && node.data === '['
4548 ? `(start of fragment)`
4549 : ``);
4550 vnode.el = null;
4551 if (isFragment) {
4552 // remove excessive fragment nodes
4553 const end = locateClosingAsyncAnchor(node);
4554 while (true) {
4555 const next = nextSibling(node);
4556 if (next && next !== end) {
4557 remove(next);
4558 }
4559 else {
4560 break;
4561 }
4562 }
4563 }
4564 const next = nextSibling(node);
4565 const container = parentNode(node);
4566 remove(node);
4567 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container));
4568 return next;
4569 };
4570 const locateClosingAsyncAnchor = (node) => {
4571 let match = 0;
4572 while (node) {
4573 node = nextSibling(node);
4574 if (node && isComment(node)) {
4575 if (node.data === '[')
4576 match++;
4577 if (node.data === ']') {
4578 if (match === 0) {
4579 return nextSibling(node);
4580 }
4581 else {
4582 match--;
4583 }
4584 }
4585 }
4586 }
4587 return node;
4588 };
4589 return [hydrate, hydrateNode];
4590}
4591
4592let supported;
4593let perf;
4594function startMeasure(instance, type) {
4595 if (instance.appContext.config.performance && isSupported()) {
4596 perf.mark(`vue-${type}-${instance.uid}`);
4597 }
4598}
4599function endMeasure(instance, type) {
4600 if (instance.appContext.config.performance && isSupported()) {
4601 const startTag = `vue-${type}-${instance.uid}`;
4602 const endTag = startTag + `:end`;
4603 perf.mark(endTag);
4604 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
4605 perf.clearMarks(startTag);
4606 perf.clearMarks(endTag);
4607 }
4608}
4609function isSupported() {
4610 if (supported !== undefined) {
4611 return supported;
4612 }
4613 /* eslint-disable no-restricted-globals */
4614 if (typeof window !== 'undefined' && window.performance) {
4615 supported = true;
4616 perf = window.performance;
4617 }
4618 else {
4619 supported = false;
4620 }
4621 /* eslint-enable no-restricted-globals */
4622 return supported;
4623}
4624
4625// implementation, close to no-op
4626function defineComponent(options) {
4627 return isFunction(options) ? { setup: options, name: options.name } : options;
4628}
4629
4630const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
4631function defineAsyncComponent(source) {
4632 if (isFunction(source)) {
4633 source = { loader: source };
4634 }
4635 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
4636 suspensible = true, onError: userOnError } = source;
4637 let pendingRequest = null;
4638 let resolvedComp;
4639 let retries = 0;
4640 const retry = () => {
4641 retries++;
4642 pendingRequest = null;
4643 return load();
4644 };
4645 const load = () => {
4646 let thisRequest;
4647 return (pendingRequest ||
4648 (thisRequest = pendingRequest = loader()
4649 .catch(err => {
4650 err = err instanceof Error ? err : new Error(String(err));
4651 if (userOnError) {
4652 return new Promise((resolve, reject) => {
4653 const userRetry = () => resolve(retry());
4654 const userFail = () => reject(err);
4655 userOnError(err, userRetry, userFail, retries + 1);
4656 });
4657 }
4658 else {
4659 throw err;
4660 }
4661 })
4662 .then((comp) => {
4663 if (thisRequest !== pendingRequest && pendingRequest) {
4664 return pendingRequest;
4665 }
4666 if (!comp) {
4667 warn(`Async component loader resolved to undefined. ` +
4668 `If you are using retry(), make sure to return its return value.`);
4669 }
4670 // interop module default
4671 if (comp &&
4672 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
4673 comp = comp.default;
4674 }
4675 if (comp && !isObject(comp) && !isFunction(comp)) {
4676 throw new Error(`Invalid async component load result: ${comp}`);
4677 }
4678 resolvedComp = comp;
4679 return comp;
4680 })));
4681 };
4682 return defineComponent({
4683 __asyncLoader: load,
4684 name: 'AsyncComponentWrapper',
4685 setup() {
4686 const instance = currentInstance;
4687 // already resolved
4688 if (resolvedComp) {
4689 return () => createInnerComp(resolvedComp, instance);
4690 }
4691 const onError = (err) => {
4692 pendingRequest = null;
4693 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
4694 };
4695 // suspense-controlled or SSR.
4696 if ((suspensible && instance.suspense) ||
4697 (false )) {
4698 return load()
4699 .then(comp => {
4700 return () => createInnerComp(comp, instance);
4701 })
4702 .catch(err => {
4703 onError(err);
4704 return () => errorComponent
4705 ? createVNode(errorComponent, {
4706 error: err
4707 })
4708 : null;
4709 });
4710 }
4711 const loaded = ref(false);
4712 const error = ref();
4713 const delayed = ref(!!delay);
4714 if (delay) {
4715 setTimeout(() => {
4716 delayed.value = false;
4717 }, delay);
4718 }
4719 if (timeout != null) {
4720 setTimeout(() => {
4721 if (!loaded.value && !error.value) {
4722 const err = new Error(`Async component timed out after ${timeout}ms.`);
4723 onError(err);
4724 error.value = err;
4725 }
4726 }, timeout);
4727 }
4728 load()
4729 .then(() => {
4730 loaded.value = true;
4731 })
4732 .catch(err => {
4733 onError(err);
4734 error.value = err;
4735 });
4736 return () => {
4737 if (loaded.value && resolvedComp) {
4738 return createInnerComp(resolvedComp, instance);
4739 }
4740 else if (error.value && errorComponent) {
4741 return createVNode(errorComponent, {
4742 error: error.value
4743 });
4744 }
4745 else if (loadingComponent && !delayed.value) {
4746 return createVNode(loadingComponent);
4747 }
4748 };
4749 }
4750 });
4751}
4752function createInnerComp(comp, { vnode: { ref, props, children } }) {
4753 const vnode = createVNode(comp, props, children);
4754 // ensure inner component inherits the async wrapper's ref owner
4755 vnode.ref = ref;
4756 return vnode;
4757}
4758
4759function createDevEffectOptions(instance) {
4760 return {
4761 scheduler: queueJob,
4762 allowRecurse: true,
4763 onTrack: instance.rtc ? e => invokeArrayFns(instance.rtc, e) : void 0,
4764 onTrigger: instance.rtg ? e => invokeArrayFns(instance.rtg, e) : void 0
4765 };
4766}
4767const queuePostRenderEffect = queueEffectWithSuspense
4768 ;
4769const setRef = (rawRef, oldRawRef, parentSuspense, vnode) => {
4770 if (isArray(rawRef)) {
4771 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode));
4772 return;
4773 }
4774 let value;
4775 if (!vnode || isAsyncWrapper(vnode)) {
4776 value = null;
4777 }
4778 else {
4779 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
4780 value = vnode.component.exposed || vnode.component.proxy;
4781 }
4782 else {
4783 value = vnode.el;
4784 }
4785 }
4786 const { i: owner, r: ref } = rawRef;
4787 if (!owner) {
4788 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
4789 `A vnode with ref must be created inside the render function.`);
4790 return;
4791 }
4792 const oldRef = oldRawRef && oldRawRef.r;
4793 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
4794 const setupState = owner.setupState;
4795 // unset old ref
4796 if (oldRef != null && oldRef !== ref) {
4797 if (isString(oldRef)) {
4798 refs[oldRef] = null;
4799 if (hasOwn(setupState, oldRef)) {
4800 setupState[oldRef] = null;
4801 }
4802 }
4803 else if (isRef(oldRef)) {
4804 oldRef.value = null;
4805 }
4806 }
4807 if (isString(ref)) {
4808 const doSet = () => {
4809 refs[ref] = value;
4810 if (hasOwn(setupState, ref)) {
4811 setupState[ref] = value;
4812 }
4813 };
4814 // #1789: for non-null values, set them after render
4815 // null values means this is unmount and it should not overwrite another
4816 // ref with the same key
4817 if (value) {
4818 doSet.id = -1;
4819 queuePostRenderEffect(doSet, parentSuspense);
4820 }
4821 else {
4822 doSet();
4823 }
4824 }
4825 else if (isRef(ref)) {
4826 const doSet = () => {
4827 ref.value = value;
4828 };
4829 if (value) {
4830 doSet.id = -1;
4831 queuePostRenderEffect(doSet, parentSuspense);
4832 }
4833 else {
4834 doSet();
4835 }
4836 }
4837 else if (isFunction(ref)) {
4838 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
4839 }
4840 else {
4841 warn('Invalid template ref type:', value, `(${typeof value})`);
4842 }
4843};
4844/**
4845 * The createRenderer function accepts two generic arguments:
4846 * HostNode and HostElement, corresponding to Node and Element types in the
4847 * host environment. For example, for runtime-dom, HostNode would be the DOM
4848 * `Node` interface and HostElement would be the DOM `Element` interface.
4849 *
4850 * Custom renderers can pass in the platform specific types like this:
4851 *
4852 * ``` js
4853 * const { render, createApp } = createRenderer<Node, Element>({
4854 * patchProp,
4855 * ...nodeOps
4856 * })
4857 * ```
4858 */
4859function createRenderer(options) {
4860 return baseCreateRenderer(options);
4861}
4862// Separate API for creating hydration-enabled renderer.
4863// Hydration logic is only used when calling this function, making it
4864// tree-shakable.
4865function createHydrationRenderer(options) {
4866 return baseCreateRenderer(options, createHydrationFunctions);
4867}
4868// implementation
4869function baseCreateRenderer(options, createHydrationFns) {
4870 {
4871 const target = getGlobalThis();
4872 target.__VUE__ = true;
4873 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__);
4874 }
4875 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;
4876 // Note: functions inside this closure should use `const xxx = () => {}`
4877 // style in order to prevent being inlined by minifiers.
4878 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) => {
4879 // patching & not same type, unmount old tree
4880 if (n1 && !isSameVNodeType(n1, n2)) {
4881 anchor = getNextHostNode(n1);
4882 unmount(n1, parentComponent, parentSuspense, true);
4883 n1 = null;
4884 }
4885 if (n2.patchFlag === -2 /* BAIL */) {
4886 optimized = false;
4887 n2.dynamicChildren = null;
4888 }
4889 const { type, ref, shapeFlag } = n2;
4890 switch (type) {
4891 case Text:
4892 processText(n1, n2, container, anchor);
4893 break;
4894 case Comment:
4895 processCommentNode(n1, n2, container, anchor);
4896 break;
4897 case Static:
4898 if (n1 == null) {
4899 mountStaticNode(n2, container, anchor, isSVG);
4900 }
4901 else {
4902 patchStaticNode(n1, n2, container, isSVG);
4903 }
4904 break;
4905 case Fragment:
4906 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
4907 break;
4908 default:
4909 if (shapeFlag & 1 /* ELEMENT */) {
4910 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
4911 }
4912 else if (shapeFlag & 6 /* COMPONENT */) {
4913 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
4914 }
4915 else if (shapeFlag & 64 /* TELEPORT */) {
4916 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);
4917 }
4918 else if (shapeFlag & 128 /* SUSPENSE */) {
4919 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);
4920 }
4921 else {
4922 warn('Invalid VNode type:', type, `(${typeof type})`);
4923 }
4924 }
4925 // set ref
4926 if (ref != null && parentComponent) {
4927 setRef(ref, n1 && n1.ref, parentSuspense, n2);
4928 }
4929 };
4930 const processText = (n1, n2, container, anchor) => {
4931 if (n1 == null) {
4932 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
4933 }
4934 else {
4935 const el = (n2.el = n1.el);
4936 if (n2.children !== n1.children) {
4937 hostSetText(el, n2.children);
4938 }
4939 }
4940 };
4941 const processCommentNode = (n1, n2, container, anchor) => {
4942 if (n1 == null) {
4943 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
4944 }
4945 else {
4946 // there's no support for dynamic comments
4947 n2.el = n1.el;
4948 }
4949 };
4950 const mountStaticNode = (n2, container, anchor, isSVG) => {
4951 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
4952 };
4953 /**
4954 * Dev / HMR only
4955 */
4956 const patchStaticNode = (n1, n2, container, isSVG) => {
4957 // static nodes are only patched during dev for HMR
4958 if (n2.children !== n1.children) {
4959 const anchor = hostNextSibling(n1.anchor);
4960 // remove existing
4961 removeStaticNode(n1);
4962 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
4963 }
4964 else {
4965 n2.el = n1.el;
4966 n2.anchor = n1.anchor;
4967 }
4968 };
4969 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
4970 let next;
4971 while (el && el !== anchor) {
4972 next = hostNextSibling(el);
4973 hostInsert(el, container, nextSibling);
4974 el = next;
4975 }
4976 hostInsert(anchor, container, nextSibling);
4977 };
4978 const removeStaticNode = ({ el, anchor }) => {
4979 let next;
4980 while (el && el !== anchor) {
4981 next = hostNextSibling(el);
4982 hostRemove(el);
4983 el = next;
4984 }
4985 hostRemove(anchor);
4986 };
4987 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
4988 isSVG = isSVG || n2.type === 'svg';
4989 if (n1 == null) {
4990 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
4991 }
4992 else {
4993 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);
4994 }
4995 };
4996 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
4997 let el;
4998 let vnodeHook;
4999 const { type, props, shapeFlag, transition, scopeId, patchFlag, dirs } = vnode;
5000 {
5001 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is);
5002 // mount children first, since some props may rely on child content
5003 // being already rendered, e.g. `<select value>`
5004 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5005 hostSetElementText(el, vnode.children);
5006 }
5007 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5008 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren);
5009 }
5010 if (dirs) {
5011 invokeDirectiveHook(vnode, null, parentComponent, 'created');
5012 }
5013 // props
5014 if (props) {
5015 for (const key in props) {
5016 if (!isReservedProp(key)) {
5017 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5018 }
5019 }
5020 if ((vnodeHook = props.onVnodeBeforeMount)) {
5021 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5022 }
5023 }
5024 // scopeId
5025 setScopeId(el, scopeId, vnode, parentComponent);
5026 }
5027 {
5028 Object.defineProperty(el, '__vnode', {
5029 value: vnode,
5030 enumerable: false
5031 });
5032 Object.defineProperty(el, '__vueParentComponent', {
5033 value: parentComponent,
5034 enumerable: false
5035 });
5036 }
5037 if (dirs) {
5038 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
5039 }
5040 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
5041 // #1689 For inside suspense + suspense resolved case, just call it
5042 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
5043 transition &&
5044 !transition.persisted;
5045 if (needCallTransitionHooks) {
5046 transition.beforeEnter(el);
5047 }
5048 hostInsert(el, container, anchor);
5049 if ((vnodeHook = props && props.onVnodeMounted) ||
5050 needCallTransitionHooks ||
5051 dirs) {
5052 queuePostRenderEffect(() => {
5053 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5054 needCallTransitionHooks && transition.enter(el);
5055 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
5056 }, parentSuspense);
5057 }
5058 };
5059 const setScopeId = (el, scopeId, vnode, parentComponent) => {
5060 if (scopeId) {
5061 hostSetScopeId(el, scopeId);
5062 }
5063 if (parentComponent) {
5064 const treeOwnerId = parentComponent.type.__scopeId;
5065 // vnode's own scopeId and the current patched component's scopeId is
5066 // different - this is a slot content node.
5067 if (treeOwnerId && treeOwnerId !== scopeId) {
5068 hostSetScopeId(el, treeOwnerId + '-s');
5069 }
5070 let subTree = parentComponent.subTree;
5071 if (subTree.type === Fragment) {
5072 subTree =
5073 filterSingleRoot(subTree.children) || subTree;
5074 }
5075 if (vnode === subTree) {
5076 setScopeId(el, parentComponent.vnode.scopeId, parentComponent.vnode, parentComponent.parent);
5077 }
5078 }
5079 };
5080 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => {
5081 for (let i = start; i < children.length; i++) {
5082 const child = (children[i] = optimized
5083 ? cloneIfMounted(children[i])
5084 : normalizeVNode(children[i]));
5085 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5086 }
5087 };
5088 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => {
5089 const el = (n2.el = n1.el);
5090 let { patchFlag, dynamicChildren, dirs } = n2;
5091 // #1426 take the old vnode's patch flag into account since user may clone a
5092 // compiler-generated vnode, which de-opts to FULL_PROPS
5093 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
5094 const oldProps = n1.props || EMPTY_OBJ;
5095 const newProps = n2.props || EMPTY_OBJ;
5096 let vnodeHook;
5097 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5098 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5099 }
5100 if (dirs) {
5101 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5102 }
5103 if (isHmrUpdating) {
5104 // HMR updated, force full diff
5105 patchFlag = 0;
5106 optimized = false;
5107 dynamicChildren = null;
5108 }
5109 if (patchFlag > 0) {
5110 // the presence of a patchFlag means this element's render code was
5111 // generated by the compiler and can take the fast path.
5112 // in this path old node and new node are guaranteed to have the same shape
5113 // (i.e. at the exact same position in the source template)
5114 if (patchFlag & 16 /* FULL_PROPS */) {
5115 // element props contain dynamic keys, full diff needed
5116 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5117 }
5118 else {
5119 // class
5120 // this flag is matched when the element has dynamic class bindings.
5121 if (patchFlag & 2 /* CLASS */) {
5122 if (oldProps.class !== newProps.class) {
5123 hostPatchProp(el, 'class', null, newProps.class, isSVG);
5124 }
5125 }
5126 // style
5127 // this flag is matched when the element has dynamic style bindings
5128 if (patchFlag & 4 /* STYLE */) {
5129 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
5130 }
5131 // props
5132 // This flag is matched when the element has dynamic prop/attr bindings
5133 // other than class and style. The keys of dynamic prop/attrs are saved for
5134 // faster iteration.
5135 // Note dynamic keys like :[foo]="bar" will cause this optimization to
5136 // bail out and go through a full diff because we need to unset the old key
5137 if (patchFlag & 8 /* PROPS */) {
5138 // if the flag is present then dynamicProps must be non-null
5139 const propsToUpdate = n2.dynamicProps;
5140 for (let i = 0; i < propsToUpdate.length; i++) {
5141 const key = propsToUpdate[i];
5142 const prev = oldProps[key];
5143 const next = newProps[key];
5144 if (next !== prev ||
5145 (hostForcePatchProp && hostForcePatchProp(el, key))) {
5146 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
5147 }
5148 }
5149 }
5150 }
5151 // text
5152 // This flag is matched when the element has only dynamic text children.
5153 if (patchFlag & 1 /* TEXT */) {
5154 if (n1.children !== n2.children) {
5155 hostSetElementText(el, n2.children);
5156 }
5157 }
5158 }
5159 else if (!optimized && dynamicChildren == null) {
5160 // unoptimized, full diff
5161 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5162 }
5163 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
5164 if (dynamicChildren) {
5165 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);
5166 if (parentComponent && parentComponent.type.__hmrId) {
5167 traverseStaticChildren(n1, n2);
5168 }
5169 }
5170 else if (!optimized) {
5171 // full diff
5172 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG);
5173 }
5174 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
5175 queuePostRenderEffect(() => {
5176 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5177 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
5178 }, parentSuspense);
5179 }
5180 };
5181 // The fast path for blocks.
5182 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) => {
5183 for (let i = 0; i < newChildren.length; i++) {
5184 const oldVNode = oldChildren[i];
5185 const newVNode = newChildren[i];
5186 // Determine the container (parent element) for the patch.
5187 const container =
5188 // - In the case of a Fragment, we need to provide the actual parent
5189 // of the Fragment itself so it can move its children.
5190 oldVNode.type === Fragment ||
5191 // - In the case of different nodes, there is going to be a replacement
5192 // which also requires the correct parent container
5193 !isSameVNodeType(oldVNode, newVNode) ||
5194 // - In the case of a component, it could contain anything.
5195 oldVNode.shapeFlag & 6 /* COMPONENT */ ||
5196 oldVNode.shapeFlag & 64 /* TELEPORT */
5197 ? hostParentNode(oldVNode.el)
5198 : // In other cases, the parent container is not actually used so we
5199 // just pass the block element here to avoid a DOM parentNode call.
5200 fallbackContainer;
5201 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, true);
5202 }
5203 };
5204 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
5205 if (oldProps !== newProps) {
5206 for (const key in newProps) {
5207 // empty string is not valid prop
5208 if (isReservedProp(key))
5209 continue;
5210 const next = newProps[key];
5211 const prev = oldProps[key];
5212 if (next !== prev ||
5213 (hostForcePatchProp && hostForcePatchProp(el, key))) {
5214 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5215 }
5216 }
5217 if (oldProps !== EMPTY_OBJ) {
5218 for (const key in oldProps) {
5219 if (!isReservedProp(key) && !(key in newProps)) {
5220 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5221 }
5222 }
5223 }
5224 }
5225 };
5226 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5227 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
5228 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
5229 let { patchFlag, dynamicChildren } = n2;
5230 if (patchFlag > 0) {
5231 optimized = true;
5232 }
5233 if (isHmrUpdating) {
5234 // HMR updated, force full diff
5235 patchFlag = 0;
5236 optimized = false;
5237 dynamicChildren = null;
5238 }
5239 if (n1 == null) {
5240 hostInsert(fragmentStartAnchor, container, anchor);
5241 hostInsert(fragmentEndAnchor, container, anchor);
5242 // a fragment can only have array children
5243 // since they are either generated by the compiler, or implicitly created
5244 // from arrays.
5245 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);
5246 }
5247 else {
5248 if (patchFlag > 0 &&
5249 patchFlag & 64 /* STABLE_FRAGMENT */ &&
5250 dynamicChildren &&
5251 // #2715 the previous fragment could've been a BAILed one as a result
5252 // of renderSlot() with no valid children
5253 n1.dynamicChildren) {
5254 // a stable fragment (template root or <template v-for>) doesn't need to
5255 // patch children order, but it may contain dynamicChildren.
5256 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG);
5257 if (parentComponent && parentComponent.type.__hmrId) {
5258 traverseStaticChildren(n1, n2);
5259 }
5260 else if (
5261 // #2080 if the stable fragment has a key, it's a <template v-for> that may
5262 // get moved around. Make sure all root level vnodes inherit el.
5263 // #2134 or if it's a component root, it may also get moved around
5264 // as the component is being moved.
5265 n2.key != null ||
5266 (parentComponent && n2 === parentComponent.subTree)) {
5267 traverseStaticChildren(n1, n2, true /* shallow */);
5268 }
5269 }
5270 else {
5271 // keyed / unkeyed, or manual fragments.
5272 // for keyed & unkeyed, since they are compiler generated from v-for,
5273 // each child is guaranteed to be a block so the fragment will never
5274 // have dynamicChildren.
5275 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);
5276 }
5277 }
5278 };
5279 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5280 if (n1 == null) {
5281 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
5282 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
5283 }
5284 else {
5285 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5286 }
5287 }
5288 else {
5289 updateComponent(n1, n2, optimized);
5290 }
5291 };
5292 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5293 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
5294 if (instance.type.__hmrId) {
5295 registerHMR(instance);
5296 }
5297 {
5298 pushWarningContext(initialVNode);
5299 startMeasure(instance, `mount`);
5300 }
5301 // inject renderer internals for keepAlive
5302 if (isKeepAlive(initialVNode)) {
5303 instance.ctx.renderer = internals;
5304 }
5305 // resolve props and slots for setup context
5306 {
5307 startMeasure(instance, `init`);
5308 }
5309 setupComponent(instance);
5310 {
5311 endMeasure(instance, `init`);
5312 }
5313 // setup() is async. This component relies on async logic to be resolved
5314 // before proceeding
5315 if (instance.asyncDep) {
5316 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
5317 // Give it a placeholder if this is not hydration
5318 // TODO handle self-defined fallback
5319 if (!initialVNode.el) {
5320 const placeholder = (instance.subTree = createVNode(Comment));
5321 processCommentNode(null, placeholder, container, anchor);
5322 }
5323 return;
5324 }
5325 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
5326 {
5327 popWarningContext();
5328 endMeasure(instance, `mount`);
5329 }
5330 };
5331 const updateComponent = (n1, n2, optimized) => {
5332 const instance = (n2.component = n1.component);
5333 if (shouldUpdateComponent(n1, n2, optimized)) {
5334 if (instance.asyncDep &&
5335 !instance.asyncResolved) {
5336 // async & still pending - just update props and slots
5337 // since the component's reactive effect for render isn't set-up yet
5338 {
5339 pushWarningContext(n2);
5340 }
5341 updateComponentPreRender(instance, n2, optimized);
5342 {
5343 popWarningContext();
5344 }
5345 return;
5346 }
5347 else {
5348 // normal update
5349 instance.next = n2;
5350 // in case the child component is also queued, remove it to avoid
5351 // double updating the same child component in the same flush.
5352 invalidateJob(instance.update);
5353 // instance.update is the reactive effect runner.
5354 instance.update();
5355 }
5356 }
5357 else {
5358 // no update needed. just copy over properties
5359 n2.component = n1.component;
5360 n2.el = n1.el;
5361 instance.vnode = n2;
5362 }
5363 };
5364 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
5365 // create reactive effect for rendering
5366 instance.update = effect(function componentEffect() {
5367 if (!instance.isMounted) {
5368 let vnodeHook;
5369 const { el, props } = initialVNode;
5370 const { bm, m, parent } = instance;
5371 // beforeMount hook
5372 if (bm) {
5373 invokeArrayFns(bm);
5374 }
5375 // onVnodeBeforeMount
5376 if ((vnodeHook = props && props.onVnodeBeforeMount)) {
5377 invokeVNodeHook(vnodeHook, parent, initialVNode);
5378 }
5379 // render
5380 {
5381 startMeasure(instance, `render`);
5382 }
5383 const subTree = (instance.subTree = renderComponentRoot(instance));
5384 {
5385 endMeasure(instance, `render`);
5386 }
5387 if (el && hydrateNode) {
5388 {
5389 startMeasure(instance, `hydrate`);
5390 }
5391 // vnode has adopted host node - perform hydration instead of mount.
5392 hydrateNode(initialVNode.el, subTree, instance, parentSuspense);
5393 {
5394 endMeasure(instance, `hydrate`);
5395 }
5396 }
5397 else {
5398 {
5399 startMeasure(instance, `patch`);
5400 }
5401 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
5402 {
5403 endMeasure(instance, `patch`);
5404 }
5405 initialVNode.el = subTree.el;
5406 }
5407 // mounted hook
5408 if (m) {
5409 queuePostRenderEffect(m, parentSuspense);
5410 }
5411 // onVnodeMounted
5412 if ((vnodeHook = props && props.onVnodeMounted)) {
5413 const scopedInitialVNode = initialVNode;
5414 queuePostRenderEffect(() => {
5415 invokeVNodeHook(vnodeHook, parent, scopedInitialVNode);
5416 }, parentSuspense);
5417 }
5418 // activated hook for keep-alive roots.
5419 // #1742 activated hook must be accessed after first render
5420 // since the hook may be injected by a child keep-alive
5421 const { a } = instance;
5422 if (a &&
5423 initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5424 queuePostRenderEffect(a, parentSuspense);
5425 }
5426 instance.isMounted = true;
5427 {
5428 devtoolsComponentAdded(instance);
5429 }
5430 // #2458: deference mount-only object parameters to prevent memleaks
5431 initialVNode = container = anchor = null;
5432 }
5433 else {
5434 // updateComponent
5435 // This is triggered by mutation of component's own state (next: null)
5436 // OR parent calling processComponent (next: VNode)
5437 let { next, bu, u, parent, vnode } = instance;
5438 let originNext = next;
5439 let vnodeHook;
5440 {
5441 pushWarningContext(next || instance.vnode);
5442 }
5443 if (next) {
5444 next.el = vnode.el;
5445 updateComponentPreRender(instance, next, optimized);
5446 }
5447 else {
5448 next = vnode;
5449 }
5450 // beforeUpdate hook
5451 if (bu) {
5452 invokeArrayFns(bu);
5453 }
5454 // onVnodeBeforeUpdate
5455 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
5456 invokeVNodeHook(vnodeHook, parent, next, vnode);
5457 }
5458 // render
5459 {
5460 startMeasure(instance, `render`);
5461 }
5462 const nextTree = renderComponentRoot(instance);
5463 {
5464 endMeasure(instance, `render`);
5465 }
5466 const prevTree = instance.subTree;
5467 instance.subTree = nextTree;
5468 {
5469 startMeasure(instance, `patch`);
5470 }
5471 patch(prevTree, nextTree,
5472 // parent may have changed if it's in a teleport
5473 hostParentNode(prevTree.el),
5474 // anchor may have changed if it's in a fragment
5475 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
5476 {
5477 endMeasure(instance, `patch`);
5478 }
5479 next.el = nextTree.el;
5480 if (originNext === null) {
5481 // self-triggered update. In case of HOC, update parent component
5482 // vnode el. HOC is indicated by parent instance's subTree pointing
5483 // to child component's vnode
5484 updateHOCHostEl(instance, nextTree.el);
5485 }
5486 // updated hook
5487 if (u) {
5488 queuePostRenderEffect(u, parentSuspense);
5489 }
5490 // onVnodeUpdated
5491 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
5492 queuePostRenderEffect(() => {
5493 invokeVNodeHook(vnodeHook, parent, next, vnode);
5494 }, parentSuspense);
5495 }
5496 {
5497 devtoolsComponentUpdated(instance);
5498 }
5499 {
5500 popWarningContext();
5501 }
5502 }
5503 }, createDevEffectOptions(instance) );
5504 };
5505 const updateComponentPreRender = (instance, nextVNode, optimized) => {
5506 nextVNode.component = instance;
5507 const prevProps = instance.vnode.props;
5508 instance.vnode = nextVNode;
5509 instance.next = null;
5510 updateProps(instance, nextVNode.props, prevProps, optimized);
5511 updateSlots(instance, nextVNode.children);
5512 // props update may have triggered pre-flush watchers.
5513 // flush them before the render update.
5514 flushPreFlushCbs(undefined, instance.update);
5515 };
5516 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) => {
5517 const c1 = n1 && n1.children;
5518 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
5519 const c2 = n2.children;
5520 const { patchFlag, shapeFlag } = n2;
5521 // fast path
5522 if (patchFlag > 0) {
5523 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
5524 // this could be either fully-keyed or mixed (some keyed some not)
5525 // presence of patchFlag means children are guaranteed to be arrays
5526 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5527 return;
5528 }
5529 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
5530 // unkeyed
5531 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5532 return;
5533 }
5534 }
5535 // children has 3 possibilities: text, array or no children.
5536 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5537 // text children fast path
5538 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5539 unmountChildren(c1, parentComponent, parentSuspense);
5540 }
5541 if (c2 !== c1) {
5542 hostSetElementText(container, c2);
5543 }
5544 }
5545 else {
5546 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5547 // prev children was array
5548 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5549 // two arrays, cannot assume anything, do full diff
5550 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5551 }
5552 else {
5553 // no new children, just unmount old
5554 unmountChildren(c1, parentComponent, parentSuspense, true);
5555 }
5556 }
5557 else {
5558 // prev children was text OR null
5559 // new children is array OR null
5560 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
5561 hostSetElementText(container, '');
5562 }
5563 // mount new if array
5564 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5565 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5566 }
5567 }
5568 }
5569 };
5570 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5571 c1 = c1 || EMPTY_ARR;
5572 c2 = c2 || EMPTY_ARR;
5573 const oldLength = c1.length;
5574 const newLength = c2.length;
5575 const commonLength = Math.min(oldLength, newLength);
5576 let i;
5577 for (i = 0; i < commonLength; i++) {
5578 const nextChild = (c2[i] = optimized
5579 ? cloneIfMounted(c2[i])
5580 : normalizeVNode(c2[i]));
5581 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized);
5582 }
5583 if (oldLength > newLength) {
5584 // remove old
5585 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
5586 }
5587 else {
5588 // mount new
5589 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength);
5590 }
5591 };
5592 // can be all-keyed or mixed
5593 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) => {
5594 let i = 0;
5595 const l2 = c2.length;
5596 let e1 = c1.length - 1; // prev ending index
5597 let e2 = l2 - 1; // next ending index
5598 // 1. sync from start
5599 // (a b) c
5600 // (a b) d e
5601 while (i <= e1 && i <= e2) {
5602 const n1 = c1[i];
5603 const n2 = (c2[i] = optimized
5604 ? cloneIfMounted(c2[i])
5605 : normalizeVNode(c2[i]));
5606 if (isSameVNodeType(n1, n2)) {
5607 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);
5608 }
5609 else {
5610 break;
5611 }
5612 i++;
5613 }
5614 // 2. sync from end
5615 // a (b c)
5616 // d e (b c)
5617 while (i <= e1 && i <= e2) {
5618 const n1 = c1[e1];
5619 const n2 = (c2[e2] = optimized
5620 ? cloneIfMounted(c2[e2])
5621 : normalizeVNode(c2[e2]));
5622 if (isSameVNodeType(n1, n2)) {
5623 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);
5624 }
5625 else {
5626 break;
5627 }
5628 e1--;
5629 e2--;
5630 }
5631 // 3. common sequence + mount
5632 // (a b)
5633 // (a b) c
5634 // i = 2, e1 = 1, e2 = 2
5635 // (a b)
5636 // c (a b)
5637 // i = 0, e1 = -1, e2 = 0
5638 if (i > e1) {
5639 if (i <= e2) {
5640 const nextPos = e2 + 1;
5641 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
5642 while (i <= e2) {
5643 patch(null, (c2[i] = optimized
5644 ? cloneIfMounted(c2[i])
5645 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG);
5646 i++;
5647 }
5648 }
5649 }
5650 // 4. common sequence + unmount
5651 // (a b) c
5652 // (a b)
5653 // i = 2, e1 = 2, e2 = 1
5654 // a (b c)
5655 // (b c)
5656 // i = 0, e1 = 0, e2 = -1
5657 else if (i > e2) {
5658 while (i <= e1) {
5659 unmount(c1[i], parentComponent, parentSuspense, true);
5660 i++;
5661 }
5662 }
5663 // 5. unknown sequence
5664 // [i ... e1 + 1]: a b [c d e] f g
5665 // [i ... e2 + 1]: a b [e d c h] f g
5666 // i = 2, e1 = 4, e2 = 5
5667 else {
5668 const s1 = i; // prev starting index
5669 const s2 = i; // next starting index
5670 // 5.1 build key:index map for newChildren
5671 const keyToNewIndexMap = new Map();
5672 for (i = s2; i <= e2; i++) {
5673 const nextChild = (c2[i] = optimized
5674 ? cloneIfMounted(c2[i])
5675 : normalizeVNode(c2[i]));
5676 if (nextChild.key != null) {
5677 if (keyToNewIndexMap.has(nextChild.key)) {
5678 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
5679 }
5680 keyToNewIndexMap.set(nextChild.key, i);
5681 }
5682 }
5683 // 5.2 loop through old children left to be patched and try to patch
5684 // matching nodes & remove nodes that are no longer present
5685 let j;
5686 let patched = 0;
5687 const toBePatched = e2 - s2 + 1;
5688 let moved = false;
5689 // used to track whether any node has moved
5690 let maxNewIndexSoFar = 0;
5691 // works as Map<newIndex, oldIndex>
5692 // Note that oldIndex is offset by +1
5693 // and oldIndex = 0 is a special value indicating the new node has
5694 // no corresponding old node.
5695 // used for determining longest stable subsequence
5696 const newIndexToOldIndexMap = new Array(toBePatched);
5697 for (i = 0; i < toBePatched; i++)
5698 newIndexToOldIndexMap[i] = 0;
5699 for (i = s1; i <= e1; i++) {
5700 const prevChild = c1[i];
5701 if (patched >= toBePatched) {
5702 // all new children have been patched so this can only be a removal
5703 unmount(prevChild, parentComponent, parentSuspense, true);
5704 continue;
5705 }
5706 let newIndex;
5707 if (prevChild.key != null) {
5708 newIndex = keyToNewIndexMap.get(prevChild.key);
5709 }
5710 else {
5711 // key-less node, try to locate a key-less node of the same type
5712 for (j = s2; j <= e2; j++) {
5713 if (newIndexToOldIndexMap[j - s2] === 0 &&
5714 isSameVNodeType(prevChild, c2[j])) {
5715 newIndex = j;
5716 break;
5717 }
5718 }
5719 }
5720 if (newIndex === undefined) {
5721 unmount(prevChild, parentComponent, parentSuspense, true);
5722 }
5723 else {
5724 newIndexToOldIndexMap[newIndex - s2] = i + 1;
5725 if (newIndex >= maxNewIndexSoFar) {
5726 maxNewIndexSoFar = newIndex;
5727 }
5728 else {
5729 moved = true;
5730 }
5731 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized);
5732 patched++;
5733 }
5734 }
5735 // 5.3 move and mount
5736 // generate longest stable subsequence only when nodes have moved
5737 const increasingNewIndexSequence = moved
5738 ? getSequence(newIndexToOldIndexMap)
5739 : EMPTY_ARR;
5740 j = increasingNewIndexSequence.length - 1;
5741 // looping backwards so that we can use last patched node as anchor
5742 for (i = toBePatched - 1; i >= 0; i--) {
5743 const nextIndex = s2 + i;
5744 const nextChild = c2[nextIndex];
5745 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
5746 if (newIndexToOldIndexMap[i] === 0) {
5747 // mount new
5748 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG);
5749 }
5750 else if (moved) {
5751 // move if:
5752 // There is no stable subsequence (e.g. a reverse)
5753 // OR current node is not among the stable sequence
5754 if (j < 0 || i !== increasingNewIndexSequence[j]) {
5755 move(nextChild, container, anchor, 2 /* REORDER */);
5756 }
5757 else {
5758 j--;
5759 }
5760 }
5761 }
5762 }
5763 };
5764 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
5765 const { el, type, transition, children, shapeFlag } = vnode;
5766 if (shapeFlag & 6 /* COMPONENT */) {
5767 move(vnode.component.subTree, container, anchor, moveType);
5768 return;
5769 }
5770 if (shapeFlag & 128 /* SUSPENSE */) {
5771 vnode.suspense.move(container, anchor, moveType);
5772 return;
5773 }
5774 if (shapeFlag & 64 /* TELEPORT */) {
5775 type.move(vnode, container, anchor, internals);
5776 return;
5777 }
5778 if (type === Fragment) {
5779 hostInsert(el, container, anchor);
5780 for (let i = 0; i < children.length; i++) {
5781 move(children[i], container, anchor, moveType);
5782 }
5783 hostInsert(vnode.anchor, container, anchor);
5784 return;
5785 }
5786 if (type === Static) {
5787 moveStaticNode(vnode, container, anchor);
5788 return;
5789 }
5790 // single nodes
5791 const needTransition = moveType !== 2 /* REORDER */ &&
5792 shapeFlag & 1 /* ELEMENT */ &&
5793 transition;
5794 if (needTransition) {
5795 if (moveType === 0 /* ENTER */) {
5796 transition.beforeEnter(el);
5797 hostInsert(el, container, anchor);
5798 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
5799 }
5800 else {
5801 const { leave, delayLeave, afterLeave } = transition;
5802 const remove = () => hostInsert(el, container, anchor);
5803 const performLeave = () => {
5804 leave(el, () => {
5805 remove();
5806 afterLeave && afterLeave();
5807 });
5808 };
5809 if (delayLeave) {
5810 delayLeave(el, remove, performLeave);
5811 }
5812 else {
5813 performLeave();
5814 }
5815 }
5816 }
5817 else {
5818 hostInsert(el, container, anchor);
5819 }
5820 };
5821 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
5822 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
5823 // unset ref
5824 if (ref != null) {
5825 setRef(ref, null, parentSuspense, null);
5826 }
5827 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5828 parentComponent.ctx.deactivate(vnode);
5829 return;
5830 }
5831 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
5832 let vnodeHook;
5833 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {
5834 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5835 }
5836 if (shapeFlag & 6 /* COMPONENT */) {
5837 unmountComponent(vnode.component, parentSuspense, doRemove);
5838 }
5839 else {
5840 if (shapeFlag & 128 /* SUSPENSE */) {
5841 vnode.suspense.unmount(parentSuspense, doRemove);
5842 return;
5843 }
5844 if (shouldInvokeDirs) {
5845 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
5846 }
5847 if (dynamicChildren &&
5848 // #1153: fast path should not be taken for non-stable (v-for) fragments
5849 (type !== Fragment ||
5850 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
5851 // fast path for block nodes: only need to unmount dynamic children.
5852 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
5853 }
5854 else if ((type === Fragment &&
5855 (patchFlag & 128 /* KEYED_FRAGMENT */ ||
5856 patchFlag & 256 /* UNKEYED_FRAGMENT */)) ||
5857 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
5858 unmountChildren(children, parentComponent, parentSuspense);
5859 }
5860 // an unmounted teleport should always remove its children if not disabled
5861 if (shapeFlag & 64 /* TELEPORT */ &&
5862 (doRemove || !isTeleportDisabled(vnode.props))) {
5863 vnode.type.remove(vnode, internals);
5864 }
5865 if (doRemove) {
5866 remove(vnode);
5867 }
5868 }
5869 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {
5870 queuePostRenderEffect(() => {
5871 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5872 shouldInvokeDirs &&
5873 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
5874 }, parentSuspense);
5875 }
5876 };
5877 const remove = vnode => {
5878 const { type, el, anchor, transition } = vnode;
5879 if (type === Fragment) {
5880 removeFragment(el, anchor);
5881 return;
5882 }
5883 if (type === Static) {
5884 removeStaticNode(vnode);
5885 return;
5886 }
5887 const performRemove = () => {
5888 hostRemove(el);
5889 if (transition && !transition.persisted && transition.afterLeave) {
5890 transition.afterLeave();
5891 }
5892 };
5893 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
5894 transition &&
5895 !transition.persisted) {
5896 const { leave, delayLeave } = transition;
5897 const performLeave = () => leave(el, performRemove);
5898 if (delayLeave) {
5899 delayLeave(vnode.el, performRemove, performLeave);
5900 }
5901 else {
5902 performLeave();
5903 }
5904 }
5905 else {
5906 performRemove();
5907 }
5908 };
5909 const removeFragment = (cur, end) => {
5910 // For fragments, directly remove all contained DOM nodes.
5911 // (fragment child nodes cannot have transition)
5912 let next;
5913 while (cur !== end) {
5914 next = hostNextSibling(cur);
5915 hostRemove(cur);
5916 cur = next;
5917 }
5918 hostRemove(end);
5919 };
5920 const unmountComponent = (instance, parentSuspense, doRemove) => {
5921 if (instance.type.__hmrId) {
5922 unregisterHMR(instance);
5923 }
5924 const { bum, effects, update, subTree, um } = instance;
5925 // beforeUnmount hook
5926 if (bum) {
5927 invokeArrayFns(bum);
5928 }
5929 if (effects) {
5930 for (let i = 0; i < effects.length; i++) {
5931 stop(effects[i]);
5932 }
5933 }
5934 // update may be null if a component is unmounted before its async
5935 // setup has resolved.
5936 if (update) {
5937 stop(update);
5938 unmount(subTree, instance, parentSuspense, doRemove);
5939 }
5940 // unmounted hook
5941 if (um) {
5942 queuePostRenderEffect(um, parentSuspense);
5943 }
5944 queuePostRenderEffect(() => {
5945 instance.isUnmounted = true;
5946 }, parentSuspense);
5947 // A component with async dep inside a pending suspense is unmounted before
5948 // its async dep resolves. This should remove the dep from the suspense, and
5949 // cause the suspense to resolve immediately if that was the last dep.
5950 if (parentSuspense &&
5951 parentSuspense.pendingBranch &&
5952 !parentSuspense.isUnmounted &&
5953 instance.asyncDep &&
5954 !instance.asyncResolved &&
5955 instance.suspenseId === parentSuspense.pendingId) {
5956 parentSuspense.deps--;
5957 if (parentSuspense.deps === 0) {
5958 parentSuspense.resolve();
5959 }
5960 }
5961 {
5962 devtoolsComponentRemoved(instance);
5963 }
5964 };
5965 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
5966 for (let i = start; i < children.length; i++) {
5967 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
5968 }
5969 };
5970 const getNextHostNode = vnode => {
5971 if (vnode.shapeFlag & 6 /* COMPONENT */) {
5972 return getNextHostNode(vnode.component.subTree);
5973 }
5974 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
5975 return vnode.suspense.next();
5976 }
5977 return hostNextSibling((vnode.anchor || vnode.el));
5978 };
5979 const render = (vnode, container) => {
5980 if (vnode == null) {
5981 if (container._vnode) {
5982 unmount(container._vnode, null, null, true);
5983 }
5984 }
5985 else {
5986 patch(container._vnode || null, vnode, container);
5987 }
5988 flushPostFlushCbs();
5989 container._vnode = vnode;
5990 };
5991 const internals = {
5992 p: patch,
5993 um: unmount,
5994 m: move,
5995 r: remove,
5996 mt: mountComponent,
5997 mc: mountChildren,
5998 pc: patchChildren,
5999 pbc: patchBlockChildren,
6000 n: getNextHostNode,
6001 o: options
6002 };
6003 let hydrate;
6004 let hydrateNode;
6005 if (createHydrationFns) {
6006 [hydrate, hydrateNode] = createHydrationFns(internals);
6007 }
6008 return {
6009 render,
6010 hydrate,
6011 createApp: createAppAPI(render, hydrate)
6012 };
6013}
6014function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6015 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6016 vnode,
6017 prevVNode
6018 ]);
6019}
6020/**
6021 * #1156
6022 * When a component is HMR-enabled, we need to make sure that all static nodes
6023 * inside a block also inherit the DOM element from the previous tree so that
6024 * HMR updates (which are full updates) can retrieve the element for patching.
6025 *
6026 * #2080
6027 * Inside keyed `template` fragment static children, if a fragment is moved,
6028 * the children will always moved so that need inherit el form previous nodes
6029 * to ensure correct moved position.
6030 */
6031function traverseStaticChildren(n1, n2, shallow = false) {
6032 const ch1 = n1.children;
6033 const ch2 = n2.children;
6034 if (isArray(ch1) && isArray(ch2)) {
6035 for (let i = 0; i < ch1.length; i++) {
6036 // this is only called in the optimized path so array children are
6037 // guaranteed to be vnodes
6038 const c1 = ch1[i];
6039 let c2 = ch2[i];
6040 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
6041 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
6042 c2 = ch2[i] = cloneIfMounted(ch2[i]);
6043 c2.el = c1.el;
6044 }
6045 if (!shallow)
6046 traverseStaticChildren(c1, c2);
6047 }
6048 // also inherit for comment nodes, but not placeholders (e.g. v-if which
6049 // would have received .el during block patch)
6050 if (c2.type === Comment && !c2.el) {
6051 c2.el = c1.el;
6052 }
6053 }
6054 }
6055}
6056// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
6057function getSequence(arr) {
6058 const p = arr.slice();
6059 const result = [0];
6060 let i, j, u, v, c;
6061 const len = arr.length;
6062 for (i = 0; i < len; i++) {
6063 const arrI = arr[i];
6064 if (arrI !== 0) {
6065 j = result[result.length - 1];
6066 if (arr[j] < arrI) {
6067 p[i] = j;
6068 result.push(i);
6069 continue;
6070 }
6071 u = 0;
6072 v = result.length - 1;
6073 while (u < v) {
6074 c = ((u + v) / 2) | 0;
6075 if (arr[result[c]] < arrI) {
6076 u = c + 1;
6077 }
6078 else {
6079 v = c;
6080 }
6081 }
6082 if (arrI < arr[result[u]]) {
6083 if (u > 0) {
6084 p[i] = result[u - 1];
6085 }
6086 result[u] = i;
6087 }
6088 }
6089 }
6090 u = result.length;
6091 v = result[u - 1];
6092 while (u-- > 0) {
6093 result[u] = v;
6094 v = p[v];
6095 }
6096 return result;
6097}
6098
6099const isTeleport = (type) => type.__isTeleport;
6100const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
6101const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
6102const resolveTarget = (props, select) => {
6103 const targetSelector = props && props.to;
6104 if (isString(targetSelector)) {
6105 if (!select) {
6106 warn(`Current renderer does not support string target for Teleports. ` +
6107 `(missing querySelector renderer option)`);
6108 return null;
6109 }
6110 else {
6111 const target = select(targetSelector);
6112 if (!target) {
6113 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
6114 `Note the target element must exist before the component is mounted - ` +
6115 `i.e. the target cannot be rendered by the component itself, and ` +
6116 `ideally should be outside of the entire Vue component tree.`);
6117 }
6118 return target;
6119 }
6120 }
6121 else {
6122 if (!targetSelector && !isTeleportDisabled(props)) {
6123 warn(`Invalid Teleport target: ${targetSelector}`);
6124 }
6125 return targetSelector;
6126 }
6127};
6128const TeleportImpl = {
6129 __isTeleport: true,
6130 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) {
6131 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
6132 const disabled = isTeleportDisabled(n2.props);
6133 const { shapeFlag, children } = n2;
6134 if (n1 == null) {
6135 // insert anchors in the main view
6136 const placeholder = (n2.el = createComment('teleport start')
6137 );
6138 const mainAnchor = (n2.anchor = createComment('teleport end')
6139 );
6140 insert(placeholder, container, anchor);
6141 insert(mainAnchor, container, anchor);
6142 const target = (n2.target = resolveTarget(n2.props, querySelector));
6143 const targetAnchor = (n2.targetAnchor = createText(''));
6144 if (target) {
6145 insert(targetAnchor, target);
6146 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
6147 isSVG = isSVG || isTargetSVG(target);
6148 }
6149 else if (!disabled) {
6150 warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
6151 }
6152 const mount = (container, anchor) => {
6153 // Teleport *always* has Array children. This is enforced in both the
6154 // compiler and vnode children normalization.
6155 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6156 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
6157 }
6158 };
6159 if (disabled) {
6160 mount(container, mainAnchor);
6161 }
6162 else if (target) {
6163 mount(target, targetAnchor);
6164 }
6165 }
6166 else {
6167 // update content
6168 n2.el = n1.el;
6169 const mainAnchor = (n2.anchor = n1.anchor);
6170 const target = (n2.target = n1.target);
6171 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
6172 const wasDisabled = isTeleportDisabled(n1.props);
6173 const currentContainer = wasDisabled ? container : target;
6174 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
6175 isSVG = isSVG || isTargetSVG(target);
6176 if (n2.dynamicChildren) {
6177 // fast path when the teleport happens to be a block root
6178 patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG);
6179 // even in block tree mode we need to make sure all root-level nodes
6180 // in the teleport inherit previous DOM references so that they can
6181 // be moved in future patches.
6182 traverseStaticChildren(n1, n2, true);
6183 }
6184 else if (!optimized) {
6185 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG);
6186 }
6187 if (disabled) {
6188 if (!wasDisabled) {
6189 // enabled -> disabled
6190 // move into main container
6191 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
6192 }
6193 }
6194 else {
6195 // target changed
6196 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
6197 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
6198 if (nextTarget) {
6199 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
6200 }
6201 else {
6202 warn('Invalid Teleport target on update:', target, `(${typeof target})`);
6203 }
6204 }
6205 else if (wasDisabled) {
6206 // disabled -> enabled
6207 // move into teleport target
6208 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
6209 }
6210 }
6211 }
6212 },
6213 remove(vnode, { r: remove, o: { remove: hostRemove } }) {
6214 const { shapeFlag, children, anchor } = vnode;
6215 hostRemove(anchor);
6216 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6217 for (let i = 0; i < children.length; i++) {
6218 remove(children[i]);
6219 }
6220 }
6221 },
6222 move: moveTeleport,
6223 hydrate: hydrateTeleport
6224};
6225function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
6226 // move target anchor if this is a target change.
6227 if (moveType === 0 /* TARGET_CHANGE */) {
6228 insert(vnode.targetAnchor, container, parentAnchor);
6229 }
6230 const { el, anchor, shapeFlag, children, props } = vnode;
6231 const isReorder = moveType === 2 /* REORDER */;
6232 // move main view anchor if this is a re-order.
6233 if (isReorder) {
6234 insert(el, container, parentAnchor);
6235 }
6236 // if this is a re-order and teleport is enabled (content is in target)
6237 // do not move children. So the opposite is: only move children if this
6238 // is not a reorder, or the teleport is disabled
6239 if (!isReorder || isTeleportDisabled(props)) {
6240 // Teleport has either Array children or no children.
6241 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6242 for (let i = 0; i < children.length; i++) {
6243 move(children[i], container, parentAnchor, 2 /* REORDER */);
6244 }
6245 }
6246 }
6247 // move main view anchor if this is a re-order.
6248 if (isReorder) {
6249 insert(anchor, container, parentAnchor);
6250 }
6251}
6252function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
6253 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
6254 if (target) {
6255 // if multiple teleports rendered to the same target element, we need to
6256 // pick up from where the last teleport finished instead of the first node
6257 const targetNode = target._lpa || target.firstChild;
6258 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
6259 if (isTeleportDisabled(vnode.props)) {
6260 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized);
6261 vnode.targetAnchor = targetNode;
6262 }
6263 else {
6264 vnode.anchor = nextSibling(node);
6265 vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized);
6266 }
6267 target._lpa =
6268 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
6269 }
6270 }
6271 return vnode.anchor && nextSibling(vnode.anchor);
6272}
6273// Force-casted public typing for h and TSX props inference
6274const Teleport = TeleportImpl;
6275
6276const COMPONENTS = 'components';
6277const DIRECTIVES = 'directives';
6278/**
6279 * @private
6280 */
6281function resolveComponent(name) {
6282 return resolveAsset(COMPONENTS, name) || name;
6283}
6284const NULL_DYNAMIC_COMPONENT = Symbol();
6285/**
6286 * @private
6287 */
6288function resolveDynamicComponent(component) {
6289 if (isString(component)) {
6290 return resolveAsset(COMPONENTS, component, false) || component;
6291 }
6292 else {
6293 // invalid types will fallthrough to createVNode and raise warning
6294 return (component || NULL_DYNAMIC_COMPONENT);
6295 }
6296}
6297/**
6298 * @private
6299 */
6300function resolveDirective(name) {
6301 return resolveAsset(DIRECTIVES, name);
6302}
6303// implementation
6304function resolveAsset(type, name, warnMissing = true) {
6305 const instance = currentRenderingInstance || currentInstance;
6306 if (instance) {
6307 const Component = instance.type;
6308 // self name has highest priority
6309 if (type === COMPONENTS) {
6310 // special self referencing call generated by compiler
6311 // inferred from SFC filename
6312 if (name === `_self`) {
6313 return Component;
6314 }
6315 const selfName = getComponentName(Component);
6316 if (selfName &&
6317 (selfName === name ||
6318 selfName === camelize(name) ||
6319 selfName === capitalize(camelize(name)))) {
6320 return Component;
6321 }
6322 }
6323 const res =
6324 // local registration
6325 // check instance[type] first for components with mixin or extends.
6326 resolve(instance[type] || Component[type], name) ||
6327 // global registration
6328 resolve(instance.appContext[type], name);
6329 if (warnMissing && !res) {
6330 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
6331 }
6332 return res;
6333 }
6334 else {
6335 warn(`resolve${capitalize(type.slice(0, -1))} ` +
6336 `can only be used in render() or setup().`);
6337 }
6338}
6339function resolve(registry, name) {
6340 return (registry &&
6341 (registry[name] ||
6342 registry[camelize(name)] ||
6343 registry[capitalize(camelize(name))]));
6344}
6345
6346const Fragment = Symbol('Fragment' );
6347const Text = Symbol('Text' );
6348const Comment = Symbol('Comment' );
6349const Static = Symbol('Static' );
6350// Since v-if and v-for are the two possible ways node structure can dynamically
6351// change, once we consider v-if branches and each v-for fragment a block, we
6352// can divide a template into nested blocks, and within each block the node
6353// structure would be stable. This allows us to skip most children diffing
6354// and only worry about the dynamic nodes (indicated by patch flags).
6355const blockStack = [];
6356let currentBlock = null;
6357/**
6358 * Open a block.
6359 * This must be called before `createBlock`. It cannot be part of `createBlock`
6360 * because the children of the block are evaluated before `createBlock` itself
6361 * is called. The generated code typically looks like this:
6362 *
6363 * ```js
6364 * function render() {
6365 * return (openBlock(),createBlock('div', null, [...]))
6366 * }
6367 * ```
6368 * disableTracking is true when creating a v-for fragment block, since a v-for
6369 * fragment always diffs its children.
6370 *
6371 * @private
6372 */
6373function openBlock(disableTracking = false) {
6374 blockStack.push((currentBlock = disableTracking ? null : []));
6375}
6376function closeBlock() {
6377 blockStack.pop();
6378 currentBlock = blockStack[blockStack.length - 1] || null;
6379}
6380// Whether we should be tracking dynamic child nodes inside a block.
6381// Only tracks when this value is > 0
6382// We are not using a simple boolean because this value may need to be
6383// incremented/decremented by nested usage of v-once (see below)
6384let shouldTrack$1 = 1;
6385/**
6386 * Block tracking sometimes needs to be disabled, for example during the
6387 * creation of a tree that needs to be cached by v-once. The compiler generates
6388 * code like this:
6389 *
6390 * ``` js
6391 * _cache[1] || (
6392 * setBlockTracking(-1),
6393 * _cache[1] = createVNode(...),
6394 * setBlockTracking(1),
6395 * _cache[1]
6396 * )
6397 * ```
6398 *
6399 * @private
6400 */
6401function setBlockTracking(value) {
6402 shouldTrack$1 += value;
6403}
6404/**
6405 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
6406 * A block root keeps track of dynamic nodes within the block in the
6407 * `dynamicChildren` array.
6408 *
6409 * @private
6410 */
6411function createBlock(type, props, children, patchFlag, dynamicProps) {
6412 const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
6413 // save current block children on the block vnode
6414 vnode.dynamicChildren = currentBlock || EMPTY_ARR;
6415 // close block
6416 closeBlock();
6417 // a block is always going to be patched, so track it as a child of its
6418 // parent block
6419 if (shouldTrack$1 > 0 && currentBlock) {
6420 currentBlock.push(vnode);
6421 }
6422 return vnode;
6423}
6424function isVNode(value) {
6425 return value ? value.__v_isVNode === true : false;
6426}
6427function isSameVNodeType(n1, n2) {
6428 if (n2.shapeFlag & 6 /* COMPONENT */ &&
6429 hmrDirtyComponents.has(n2.type)) {
6430 // HMR only: if the component has been hot-updated, force a reload.
6431 return false;
6432 }
6433 return n1.type === n2.type && n1.key === n2.key;
6434}
6435let vnodeArgsTransformer;
6436/**
6437 * Internal API for registering an arguments transform for createVNode
6438 * used for creating stubs in the test-utils
6439 * It is *internal* but needs to be exposed for test-utils to pick up proper
6440 * typings
6441 */
6442function transformVNodeArgs(transformer) {
6443 vnodeArgsTransformer = transformer;
6444}
6445const createVNodeWithArgsTransform = (...args) => {
6446 return _createVNode(...(vnodeArgsTransformer
6447 ? vnodeArgsTransformer(args, currentRenderingInstance)
6448 : args));
6449};
6450const InternalObjectKey = `__vInternal`;
6451const normalizeKey = ({ key }) => key != null ? key : null;
6452const normalizeRef = ({ ref }) => {
6453 return (ref != null
6454 ? isString(ref) || isRef(ref) || isFunction(ref)
6455 ? { i: currentRenderingInstance, r: ref }
6456 : ref
6457 : null);
6458};
6459const createVNode = (createVNodeWithArgsTransform
6460 );
6461function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
6462 if (!type || type === NULL_DYNAMIC_COMPONENT) {
6463 if (!type) {
6464 warn(`Invalid vnode type when creating vnode: ${type}.`);
6465 }
6466 type = Comment;
6467 }
6468 if (isVNode(type)) {
6469 // createVNode receiving an existing vnode. This happens in cases like
6470 // <component :is="vnode"/>
6471 // #2078 make sure to merge refs during the clone instead of overwriting it
6472 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
6473 if (children) {
6474 normalizeChildren(cloned, children);
6475 }
6476 return cloned;
6477 }
6478 // class component normalization.
6479 if (isClassComponent(type)) {
6480 type = type.__vccOpts;
6481 }
6482 // class & style normalization.
6483 if (props) {
6484 // for reactive or proxy objects, we need to clone it to enable mutation.
6485 if (isProxy(props) || InternalObjectKey in props) {
6486 props = extend({}, props);
6487 }
6488 let { class: klass, style } = props;
6489 if (klass && !isString(klass)) {
6490 props.class = normalizeClass(klass);
6491 }
6492 if (isObject(style)) {
6493 // reactive state objects need to be cloned since they are likely to be
6494 // mutated
6495 if (isProxy(style) && !isArray(style)) {
6496 style = extend({}, style);
6497 }
6498 props.style = normalizeStyle(style);
6499 }
6500 }
6501 // encode the vnode type information into a bitmap
6502 const shapeFlag = isString(type)
6503 ? 1 /* ELEMENT */
6504 : isSuspense(type)
6505 ? 128 /* SUSPENSE */
6506 : isTeleport(type)
6507 ? 64 /* TELEPORT */
6508 : isObject(type)
6509 ? 4 /* STATEFUL_COMPONENT */
6510 : isFunction(type)
6511 ? 2 /* FUNCTIONAL_COMPONENT */
6512 : 0;
6513 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
6514 type = toRaw(type);
6515 warn(`Vue received a Component which was made a reactive object. This can ` +
6516 `lead to unnecessary performance overhead, and should be avoided by ` +
6517 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
6518 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
6519 }
6520 const vnode = {
6521 __v_isVNode: true,
6522 ["__v_skip" /* SKIP */]: true,
6523 type,
6524 props,
6525 key: props && normalizeKey(props),
6526 ref: props && normalizeRef(props),
6527 scopeId: currentScopeId,
6528 children: null,
6529 component: null,
6530 suspense: null,
6531 ssContent: null,
6532 ssFallback: null,
6533 dirs: null,
6534 transition: null,
6535 el: null,
6536 anchor: null,
6537 target: null,
6538 targetAnchor: null,
6539 staticCount: 0,
6540 shapeFlag,
6541 patchFlag,
6542 dynamicProps,
6543 dynamicChildren: null,
6544 appContext: null
6545 };
6546 // validate key
6547 if (vnode.key !== vnode.key) {
6548 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
6549 }
6550 normalizeChildren(vnode, children);
6551 // normalize suspense children
6552 if (shapeFlag & 128 /* SUSPENSE */) {
6553 const { content, fallback } = normalizeSuspenseChildren(vnode);
6554 vnode.ssContent = content;
6555 vnode.ssFallback = fallback;
6556 }
6557 if (shouldTrack$1 > 0 &&
6558 // avoid a block node from tracking itself
6559 !isBlockNode &&
6560 // has current parent block
6561 currentBlock &&
6562 // presence of a patch flag indicates this node needs patching on updates.
6563 // component nodes also should always be patched, because even if the
6564 // component doesn't need to update, it needs to persist the instance on to
6565 // the next vnode so that it can be properly unmounted later.
6566 (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
6567 // the EVENTS flag is only for hydration and if it is the only flag, the
6568 // vnode should not be considered dynamic due to handler caching.
6569 patchFlag !== 32 /* HYDRATE_EVENTS */) {
6570 currentBlock.push(vnode);
6571 }
6572 return vnode;
6573}
6574function cloneVNode(vnode, extraProps, mergeRef = false) {
6575 // This is intentionally NOT using spread or extend to avoid the runtime
6576 // key enumeration cost.
6577 const { props, ref, patchFlag, children } = vnode;
6578 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
6579 return {
6580 __v_isVNode: true,
6581 ["__v_skip" /* SKIP */]: true,
6582 type: vnode.type,
6583 props: mergedProps,
6584 key: mergedProps && normalizeKey(mergedProps),
6585 ref: extraProps && extraProps.ref
6586 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
6587 // if the vnode itself already has a ref, cloneVNode will need to merge
6588 // the refs so the single vnode can be set on multiple refs
6589 mergeRef && ref
6590 ? isArray(ref)
6591 ? ref.concat(normalizeRef(extraProps))
6592 : [ref, normalizeRef(extraProps)]
6593 : normalizeRef(extraProps)
6594 : ref,
6595 scopeId: vnode.scopeId,
6596 children: patchFlag === -1 /* HOISTED */ && isArray(children)
6597 ? children.map(deepCloneVNode)
6598 : children,
6599 target: vnode.target,
6600 targetAnchor: vnode.targetAnchor,
6601 staticCount: vnode.staticCount,
6602 shapeFlag: vnode.shapeFlag,
6603 // if the vnode is cloned with extra props, we can no longer assume its
6604 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
6605 // note: perserve flag for fragments since they use the flag for children
6606 // fast paths only.
6607 patchFlag: extraProps && vnode.type !== Fragment
6608 ? patchFlag === -1 // hoisted node
6609 ? 16 /* FULL_PROPS */
6610 : patchFlag | 16 /* FULL_PROPS */
6611 : patchFlag,
6612 dynamicProps: vnode.dynamicProps,
6613 dynamicChildren: vnode.dynamicChildren,
6614 appContext: vnode.appContext,
6615 dirs: vnode.dirs,
6616 transition: vnode.transition,
6617 // These should technically only be non-null on mounted VNodes. However,
6618 // they *should* be copied for kept-alive vnodes. So we just always copy
6619 // them since them being non-null during a mount doesn't affect the logic as
6620 // they will simply be overwritten.
6621 component: vnode.component,
6622 suspense: vnode.suspense,
6623 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
6624 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
6625 el: vnode.el,
6626 anchor: vnode.anchor
6627 };
6628}
6629/**
6630 * Dev only, for HMR of hoisted vnodes reused in v-for
6631 * https://github.com/vitejs/vite/issues/2022
6632 */
6633function deepCloneVNode(vnode) {
6634 const cloned = cloneVNode(vnode);
6635 if (isArray(vnode.children)) {
6636 cloned.children = vnode.children.map(deepCloneVNode);
6637 }
6638 return cloned;
6639}
6640/**
6641 * @private
6642 */
6643function createTextVNode(text = ' ', flag = 0) {
6644 return createVNode(Text, null, text, flag);
6645}
6646/**
6647 * @private
6648 */
6649function createStaticVNode(content, numberOfNodes) {
6650 // A static vnode can contain multiple stringified elements, and the number
6651 // of elements is necessary for hydration.
6652 const vnode = createVNode(Static, null, content);
6653 vnode.staticCount = numberOfNodes;
6654 return vnode;
6655}
6656/**
6657 * @private
6658 */
6659function createCommentVNode(text = '',
6660// when used as the v-else branch, the comment node must be created as a
6661// block to ensure correct updates.
6662asBlock = false) {
6663 return asBlock
6664 ? (openBlock(), createBlock(Comment, null, text))
6665 : createVNode(Comment, null, text);
6666}
6667function normalizeVNode(child) {
6668 if (child == null || typeof child === 'boolean') {
6669 // empty placeholder
6670 return createVNode(Comment);
6671 }
6672 else if (isArray(child)) {
6673 // fragment
6674 return createVNode(Fragment, null, child);
6675 }
6676 else if (typeof child === 'object') {
6677 // already vnode, this should be the most common since compiled templates
6678 // always produce all-vnode children arrays
6679 return child.el === null ? child : cloneVNode(child);
6680 }
6681 else {
6682 // strings and numbers
6683 return createVNode(Text, null, String(child));
6684 }
6685}
6686// optimized normalization for template-compiled render fns
6687function cloneIfMounted(child) {
6688 return child.el === null ? child : cloneVNode(child);
6689}
6690function normalizeChildren(vnode, children) {
6691 let type = 0;
6692 const { shapeFlag } = vnode;
6693 if (children == null) {
6694 children = null;
6695 }
6696 else if (isArray(children)) {
6697 type = 16 /* ARRAY_CHILDREN */;
6698 }
6699 else if (typeof children === 'object') {
6700 if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
6701 // Normalize slot to plain children for plain element and Teleport
6702 const slot = children.default;
6703 if (slot) {
6704 // _c marker is added by withCtx() indicating this is a compiled slot
6705 slot._c && setCompiledSlotRendering(1);
6706 normalizeChildren(vnode, slot());
6707 slot._c && setCompiledSlotRendering(-1);
6708 }
6709 return;
6710 }
6711 else {
6712 type = 32 /* SLOTS_CHILDREN */;
6713 const slotFlag = children._;
6714 if (!slotFlag && !(InternalObjectKey in children)) {
6715 children._ctx = currentRenderingInstance;
6716 }
6717 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
6718 // a child component receives forwarded slots from the parent.
6719 // its slot type is determined by its parent's slot type.
6720 if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
6721 children._ = 2 /* DYNAMIC */;
6722 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
6723 }
6724 else {
6725 children._ = 1 /* STABLE */;
6726 }
6727 }
6728 }
6729 }
6730 else if (isFunction(children)) {
6731 children = { default: children, _ctx: currentRenderingInstance };
6732 type = 32 /* SLOTS_CHILDREN */;
6733 }
6734 else {
6735 children = String(children);
6736 // force teleport children to array so it can be moved around
6737 if (shapeFlag & 64 /* TELEPORT */) {
6738 type = 16 /* ARRAY_CHILDREN */;
6739 children = [createTextVNode(children)];
6740 }
6741 else {
6742 type = 8 /* TEXT_CHILDREN */;
6743 }
6744 }
6745 vnode.children = children;
6746 vnode.shapeFlag |= type;
6747}
6748function mergeProps(...args) {
6749 const ret = extend({}, args[0]);
6750 for (let i = 1; i < args.length; i++) {
6751 const toMerge = args[i];
6752 for (const key in toMerge) {
6753 if (key === 'class') {
6754 if (ret.class !== toMerge.class) {
6755 ret.class = normalizeClass([ret.class, toMerge.class]);
6756 }
6757 }
6758 else if (key === 'style') {
6759 ret.style = normalizeStyle([ret.style, toMerge.style]);
6760 }
6761 else if (isOn(key)) {
6762 const existing = ret[key];
6763 const incoming = toMerge[key];
6764 if (existing !== incoming) {
6765 ret[key] = existing
6766 ? [].concat(existing, toMerge[key])
6767 : incoming;
6768 }
6769 }
6770 else if (key !== '') {
6771 ret[key] = toMerge[key];
6772 }
6773 }
6774 }
6775 return ret;
6776}
6777
6778function provide(key, value) {
6779 if (!currentInstance) {
6780 {
6781 warn(`provide() can only be used inside setup().`);
6782 }
6783 }
6784 else {
6785 let provides = currentInstance.provides;
6786 // by default an instance inherits its parent's provides object
6787 // but when it needs to provide values of its own, it creates its
6788 // own provides object using parent provides object as prototype.
6789 // this way in `inject` we can simply look up injections from direct
6790 // parent and let the prototype chain do the work.
6791 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
6792 if (parentProvides === provides) {
6793 provides = currentInstance.provides = Object.create(parentProvides);
6794 }
6795 // TS doesn't allow symbol as index type
6796 provides[key] = value;
6797 }
6798}
6799function inject(key, defaultValue, treatDefaultAsFactory = false) {
6800 // fallback to `currentRenderingInstance` so that this can be called in
6801 // a functional component
6802 const instance = currentInstance || currentRenderingInstance;
6803 if (instance) {
6804 // #2400
6805 // to support `app.use` plugins,
6806 // fallback to appContext's `provides` if the intance is at root
6807 const provides = instance.parent == null
6808 ? instance.vnode.appContext && instance.vnode.appContext.provides
6809 : instance.parent.provides;
6810 if (provides && key in provides) {
6811 // TS doesn't allow symbol as index type
6812 return provides[key];
6813 }
6814 else if (arguments.length > 1) {
6815 return treatDefaultAsFactory && isFunction(defaultValue)
6816 ? defaultValue()
6817 : defaultValue;
6818 }
6819 else {
6820 warn(`injection "${String(key)}" not found.`);
6821 }
6822 }
6823 else {
6824 warn(`inject() can only be used inside setup() or functional components.`);
6825 }
6826}
6827
6828function createDuplicateChecker() {
6829 const cache = Object.create(null);
6830 return (type, key) => {
6831 if (cache[key]) {
6832 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
6833 }
6834 else {
6835 cache[key] = type;
6836 }
6837 };
6838}
6839let isInBeforeCreate = false;
6840function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
6841 const {
6842 // composition
6843 mixins, extends: extendsOptions,
6844 // state
6845 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
6846 // assets
6847 components, directives,
6848 // lifecycle
6849 beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured,
6850 // public API
6851 expose } = options;
6852 const publicThis = instance.proxy;
6853 const ctx = instance.ctx;
6854 const globalMixins = instance.appContext.mixins;
6855 if (asMixin && render && instance.render === NOOP) {
6856 instance.render = render;
6857 }
6858 // applyOptions is called non-as-mixin once per instance
6859 if (!asMixin) {
6860 isInBeforeCreate = true;
6861 callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
6862 isInBeforeCreate = false;
6863 // global mixins are applied first
6864 applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
6865 }
6866 // extending a base component...
6867 if (extendsOptions) {
6868 applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
6869 }
6870 // local mixins
6871 if (mixins) {
6872 applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
6873 }
6874 const checkDuplicateProperties = createDuplicateChecker() ;
6875 {
6876 const [propsOptions] = instance.propsOptions;
6877 if (propsOptions) {
6878 for (const key in propsOptions) {
6879 checkDuplicateProperties("Props" /* PROPS */, key);
6880 }
6881 }
6882 }
6883 // options initialization order (to be consistent with Vue 2):
6884 // - props (already done outside of this function)
6885 // - inject
6886 // - methods
6887 // - data (deferred since it relies on `this` access)
6888 // - computed
6889 // - watch (deferred since it relies on `this` access)
6890 if (injectOptions) {
6891 if (isArray(injectOptions)) {
6892 for (let i = 0; i < injectOptions.length; i++) {
6893 const key = injectOptions[i];
6894 ctx[key] = inject(key);
6895 {
6896 checkDuplicateProperties("Inject" /* INJECT */, key);
6897 }
6898 }
6899 }
6900 else {
6901 for (const key in injectOptions) {
6902 const opt = injectOptions[key];
6903 if (isObject(opt)) {
6904 ctx[key] = inject(opt.from || key, opt.default, true /* treat default function as factory */);
6905 }
6906 else {
6907 ctx[key] = inject(opt);
6908 }
6909 {
6910 checkDuplicateProperties("Inject" /* INJECT */, key);
6911 }
6912 }
6913 }
6914 }
6915 if (methods) {
6916 for (const key in methods) {
6917 const methodHandler = methods[key];
6918 if (isFunction(methodHandler)) {
6919 // In dev mode, we use the `createRenderContext` function to define methods to the proxy target,
6920 // and those are read-only but reconfigurable, so it needs to be redefined here
6921 {
6922 Object.defineProperty(ctx, key, {
6923 value: methodHandler.bind(publicThis),
6924 configurable: true,
6925 enumerable: true,
6926 writable: true
6927 });
6928 }
6929 {
6930 checkDuplicateProperties("Methods" /* METHODS */, key);
6931 }
6932 }
6933 else {
6934 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
6935 `Did you reference the function correctly?`);
6936 }
6937 }
6938 }
6939 if (!asMixin) {
6940 if (deferredData.length) {
6941 deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis));
6942 }
6943 if (dataOptions) {
6944 // @ts-ignore dataOptions is not fully type safe
6945 resolveData(instance, dataOptions, publicThis);
6946 }
6947 {
6948 const rawData = toRaw(instance.data);
6949 for (const key in rawData) {
6950 checkDuplicateProperties("Data" /* DATA */, key);
6951 // expose data on ctx during dev
6952 if (key[0] !== '$' && key[0] !== '_') {
6953 Object.defineProperty(ctx, key, {
6954 configurable: true,
6955 enumerable: true,
6956 get: () => rawData[key],
6957 set: NOOP
6958 });
6959 }
6960 }
6961 }
6962 }
6963 else if (dataOptions) {
6964 deferredData.push(dataOptions);
6965 }
6966 if (computedOptions) {
6967 for (const key in computedOptions) {
6968 const opt = computedOptions[key];
6969 const get = isFunction(opt)
6970 ? opt.bind(publicThis, publicThis)
6971 : isFunction(opt.get)
6972 ? opt.get.bind(publicThis, publicThis)
6973 : NOOP;
6974 if (get === NOOP) {
6975 warn(`Computed property "${key}" has no getter.`);
6976 }
6977 const set = !isFunction(opt) && isFunction(opt.set)
6978 ? opt.set.bind(publicThis)
6979 : () => {
6980 warn(`Write operation failed: computed property "${key}" is readonly.`);
6981 }
6982 ;
6983 const c = computed$1({
6984 get,
6985 set
6986 });
6987 Object.defineProperty(ctx, key, {
6988 enumerable: true,
6989 configurable: true,
6990 get: () => c.value,
6991 set: v => (c.value = v)
6992 });
6993 {
6994 checkDuplicateProperties("Computed" /* COMPUTED */, key);
6995 }
6996 }
6997 }
6998 if (watchOptions) {
6999 deferredWatch.push(watchOptions);
7000 }
7001 if (!asMixin && deferredWatch.length) {
7002 deferredWatch.forEach(watchOptions => {
7003 for (const key in watchOptions) {
7004 createWatcher(watchOptions[key], ctx, publicThis, key);
7005 }
7006 });
7007 }
7008 if (provideOptions) {
7009 deferredProvide.push(provideOptions);
7010 }
7011 if (!asMixin && deferredProvide.length) {
7012 deferredProvide.forEach(provideOptions => {
7013 const provides = isFunction(provideOptions)
7014 ? provideOptions.call(publicThis)
7015 : provideOptions;
7016 Reflect.ownKeys(provides).forEach(key => {
7017 provide(key, provides[key]);
7018 });
7019 });
7020 }
7021 // asset options.
7022 // To reduce memory usage, only components with mixins or extends will have
7023 // resolved asset registry attached to instance.
7024 if (asMixin) {
7025 if (components) {
7026 extend(instance.components ||
7027 (instance.components = extend({}, instance.type.components)), components);
7028 }
7029 if (directives) {
7030 extend(instance.directives ||
7031 (instance.directives = extend({}, instance.type.directives)), directives);
7032 }
7033 }
7034 // lifecycle options
7035 if (!asMixin) {
7036 callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
7037 }
7038 if (beforeMount) {
7039 onBeforeMount(beforeMount.bind(publicThis));
7040 }
7041 if (mounted) {
7042 onMounted(mounted.bind(publicThis));
7043 }
7044 if (beforeUpdate) {
7045 onBeforeUpdate(beforeUpdate.bind(publicThis));
7046 }
7047 if (updated) {
7048 onUpdated(updated.bind(publicThis));
7049 }
7050 if (activated) {
7051 onActivated(activated.bind(publicThis));
7052 }
7053 if (deactivated) {
7054 onDeactivated(deactivated.bind(publicThis));
7055 }
7056 if (errorCaptured) {
7057 onErrorCaptured(errorCaptured.bind(publicThis));
7058 }
7059 if (renderTracked) {
7060 onRenderTracked(renderTracked.bind(publicThis));
7061 }
7062 if (renderTriggered) {
7063 onRenderTriggered(renderTriggered.bind(publicThis));
7064 }
7065 if (beforeDestroy) {
7066 warn(`\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`);
7067 }
7068 if (beforeUnmount) {
7069 onBeforeUnmount(beforeUnmount.bind(publicThis));
7070 }
7071 if (destroyed) {
7072 warn(`\`destroyed\` has been renamed to \`unmounted\`.`);
7073 }
7074 if (unmounted) {
7075 onUnmounted(unmounted.bind(publicThis));
7076 }
7077 if (isArray(expose)) {
7078 if (!asMixin) {
7079 if (expose.length) {
7080 const exposed = instance.exposed || (instance.exposed = proxyRefs({}));
7081 expose.forEach(key => {
7082 exposed[key] = toRef(publicThis, key);
7083 });
7084 }
7085 else if (!instance.exposed) {
7086 instance.exposed = EMPTY_OBJ;
7087 }
7088 }
7089 else {
7090 warn(`The \`expose\` option is ignored when used in mixins.`);
7091 }
7092 }
7093}
7094function callSyncHook(name, type, options, instance, globalMixins) {
7095 callHookFromMixins(name, type, globalMixins, instance);
7096 const { extends: base, mixins } = options;
7097 if (base) {
7098 callHookFromExtends(name, type, base, instance);
7099 }
7100 if (mixins) {
7101 callHookFromMixins(name, type, mixins, instance);
7102 }
7103 const selfHook = options[name];
7104 if (selfHook) {
7105 callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
7106 }
7107}
7108function callHookFromExtends(name, type, base, instance) {
7109 if (base.extends) {
7110 callHookFromExtends(name, type, base.extends, instance);
7111 }
7112 const baseHook = base[name];
7113 if (baseHook) {
7114 callWithAsyncErrorHandling(baseHook.bind(instance.proxy), instance, type);
7115 }
7116}
7117function callHookFromMixins(name, type, mixins, instance) {
7118 for (let i = 0; i < mixins.length; i++) {
7119 const chainedMixins = mixins[i].mixins;
7120 if (chainedMixins) {
7121 callHookFromMixins(name, type, chainedMixins, instance);
7122 }
7123 const fn = mixins[i][name];
7124 if (fn) {
7125 callWithAsyncErrorHandling(fn.bind(instance.proxy), instance, type);
7126 }
7127 }
7128}
7129function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
7130 for (let i = 0; i < mixins.length; i++) {
7131 applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
7132 }
7133}
7134function resolveData(instance, dataFn, publicThis) {
7135 if (!isFunction(dataFn)) {
7136 warn(`The data option must be a function. ` +
7137 `Plain object usage is no longer supported.`);
7138 }
7139 const data = dataFn.call(publicThis, publicThis);
7140 if (isPromise(data)) {
7141 warn(`data() returned a Promise - note data() cannot be async; If you ` +
7142 `intend to perform data fetching before component renders, use ` +
7143 `async setup() + <Suspense>.`);
7144 }
7145 if (!isObject(data)) {
7146 warn(`data() should return an object.`);
7147 }
7148 else if (instance.data === EMPTY_OBJ) {
7149 instance.data = reactive(data);
7150 }
7151 else {
7152 // existing data: this is a mixin or extends.
7153 extend(instance.data, data);
7154 }
7155}
7156function createWatcher(raw, ctx, publicThis, key) {
7157 const getter = key.includes('.')
7158 ? createPathGetter(publicThis, key)
7159 : () => publicThis[key];
7160 if (isString(raw)) {
7161 const handler = ctx[raw];
7162 if (isFunction(handler)) {
7163 watch(getter, handler);
7164 }
7165 else {
7166 warn(`Invalid watch handler specified by key "${raw}"`, handler);
7167 }
7168 }
7169 else if (isFunction(raw)) {
7170 watch(getter, raw.bind(publicThis));
7171 }
7172 else if (isObject(raw)) {
7173 if (isArray(raw)) {
7174 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
7175 }
7176 else {
7177 const handler = isFunction(raw.handler)
7178 ? raw.handler.bind(publicThis)
7179 : ctx[raw.handler];
7180 if (isFunction(handler)) {
7181 watch(getter, handler, raw);
7182 }
7183 else {
7184 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
7185 }
7186 }
7187 }
7188 else {
7189 warn(`Invalid watch option: "${key}"`, raw);
7190 }
7191}
7192function createPathGetter(ctx, path) {
7193 const segments = path.split('.');
7194 return () => {
7195 let cur = ctx;
7196 for (let i = 0; i < segments.length && cur; i++) {
7197 cur = cur[segments[i]];
7198 }
7199 return cur;
7200 };
7201}
7202function resolveMergedOptions(instance) {
7203 const raw = instance.type;
7204 const { __merged, mixins, extends: extendsOptions } = raw;
7205 if (__merged)
7206 return __merged;
7207 const globalMixins = instance.appContext.mixins;
7208 if (!globalMixins.length && !mixins && !extendsOptions)
7209 return raw;
7210 const options = {};
7211 globalMixins.forEach(m => mergeOptions(options, m, instance));
7212 mergeOptions(options, raw, instance);
7213 return (raw.__merged = options);
7214}
7215function mergeOptions(to, from, instance) {
7216 const strats = instance.appContext.config.optionMergeStrategies;
7217 const { mixins, extends: extendsOptions } = from;
7218 extendsOptions && mergeOptions(to, extendsOptions, instance);
7219 mixins &&
7220 mixins.forEach((m) => mergeOptions(to, m, instance));
7221 for (const key in from) {
7222 if (strats && hasOwn(strats, key)) {
7223 to[key] = strats[key](to[key], from[key], instance.proxy, key);
7224 }
7225 else {
7226 to[key] = from[key];
7227 }
7228 }
7229}
7230
7231/**
7232 * #2437 In Vue 3, functional components do not have a public instance proxy but
7233 * they exist in the internal parent chain. For code that relies on traversing
7234 * public $parent chains, skip functional ones and go to the parent instead.
7235 */
7236const getPublicInstance = (i) => {
7237 if (!i)
7238 return null;
7239 if (isStatefulComponent(i))
7240 return i.exposed ? i.exposed : i.proxy;
7241 return getPublicInstance(i.parent);
7242};
7243const publicPropertiesMap = extend(Object.create(null), {
7244 $: i => i,
7245 $el: i => i.vnode.el,
7246 $data: i => i.data,
7247 $props: i => (shallowReadonly(i.props) ),
7248 $attrs: i => (shallowReadonly(i.attrs) ),
7249 $slots: i => (shallowReadonly(i.slots) ),
7250 $refs: i => (shallowReadonly(i.refs) ),
7251 $parent: i => getPublicInstance(i.parent),
7252 $root: i => getPublicInstance(i.root),
7253 $emit: i => i.emit,
7254 $options: i => (resolveMergedOptions(i) ),
7255 $forceUpdate: i => () => queueJob(i.update),
7256 $nextTick: i => nextTick.bind(i.proxy),
7257 $watch: i => (instanceWatch.bind(i) )
7258});
7259const PublicInstanceProxyHandlers = {
7260 get({ _: instance }, key) {
7261 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
7262 // let @vue/reactivity know it should never observe Vue public instances.
7263 if (key === "__v_skip" /* SKIP */) {
7264 return true;
7265 }
7266 // for internal formatters to know that this is a Vue instance
7267 if (key === '__isVue') {
7268 return true;
7269 }
7270 // data / props / ctx
7271 // This getter gets called for every property access on the render context
7272 // during render and is a major hotspot. The most expensive part of this
7273 // is the multiple hasOwn() calls. It's much faster to do a simple property
7274 // access on a plain object, so we use an accessCache object (with null
7275 // prototype) to memoize what access type a key corresponds to.
7276 let normalizedProps;
7277 if (key[0] !== '$') {
7278 const n = accessCache[key];
7279 if (n !== undefined) {
7280 switch (n) {
7281 case 0 /* SETUP */:
7282 return setupState[key];
7283 case 1 /* DATA */:
7284 return data[key];
7285 case 3 /* CONTEXT */:
7286 return ctx[key];
7287 case 2 /* PROPS */:
7288 return props[key];
7289 // default: just fallthrough
7290 }
7291 }
7292 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7293 accessCache[key] = 0 /* SETUP */;
7294 return setupState[key];
7295 }
7296 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7297 accessCache[key] = 1 /* DATA */;
7298 return data[key];
7299 }
7300 else if (
7301 // only cache other properties when instance has declared (thus stable)
7302 // props
7303 (normalizedProps = instance.propsOptions[0]) &&
7304 hasOwn(normalizedProps, key)) {
7305 accessCache[key] = 2 /* PROPS */;
7306 return props[key];
7307 }
7308 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7309 accessCache[key] = 3 /* CONTEXT */;
7310 return ctx[key];
7311 }
7312 else if (!isInBeforeCreate) {
7313 accessCache[key] = 4 /* OTHER */;
7314 }
7315 }
7316 const publicGetter = publicPropertiesMap[key];
7317 let cssModule, globalProperties;
7318 // public $xxx properties
7319 if (publicGetter) {
7320 if (key === '$attrs') {
7321 track(instance, "get" /* GET */, key);
7322 markAttrsAccessed();
7323 }
7324 return publicGetter(instance);
7325 }
7326 else if (
7327 // css module (injected by vue-loader)
7328 (cssModule = type.__cssModules) &&
7329 (cssModule = cssModule[key])) {
7330 return cssModule;
7331 }
7332 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7333 // user may set custom properties to `this` that start with `$`
7334 accessCache[key] = 3 /* CONTEXT */;
7335 return ctx[key];
7336 }
7337 else if (
7338 // global properties
7339 ((globalProperties = appContext.config.globalProperties),
7340 hasOwn(globalProperties, key))) {
7341 return globalProperties[key];
7342 }
7343 else if (currentRenderingInstance &&
7344 (!isString(key) ||
7345 // #1091 avoid internal isRef/isVNode checks on component instance leading
7346 // to infinite warning loop
7347 key.indexOf('__v') !== 0)) {
7348 if (data !== EMPTY_OBJ &&
7349 (key[0] === '$' || key[0] === '_') &&
7350 hasOwn(data, key)) {
7351 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
7352 `character ("$" or "_") and is not proxied on the render context.`);
7353 }
7354 else if (instance === currentRenderingInstance) {
7355 warn(`Property ${JSON.stringify(key)} was accessed during render ` +
7356 `but is not defined on instance.`);
7357 }
7358 }
7359 },
7360 set({ _: instance }, key, value) {
7361 const { data, setupState, ctx } = instance;
7362 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7363 setupState[key] = value;
7364 }
7365 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7366 data[key] = value;
7367 }
7368 else if (hasOwn(instance.props, key)) {
7369 warn(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
7370 return false;
7371 }
7372 if (key[0] === '$' && key.slice(1) in instance) {
7373 warn(`Attempting to mutate public property "${key}". ` +
7374 `Properties starting with $ are reserved and readonly.`, instance);
7375 return false;
7376 }
7377 else {
7378 if (key in instance.appContext.config.globalProperties) {
7379 Object.defineProperty(ctx, key, {
7380 enumerable: true,
7381 configurable: true,
7382 value
7383 });
7384 }
7385 else {
7386 ctx[key] = value;
7387 }
7388 }
7389 return true;
7390 },
7391 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7392 let normalizedProps;
7393 return (accessCache[key] !== undefined ||
7394 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7395 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7396 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
7397 hasOwn(ctx, key) ||
7398 hasOwn(publicPropertiesMap, key) ||
7399 hasOwn(appContext.config.globalProperties, key));
7400 }
7401};
7402{
7403 PublicInstanceProxyHandlers.ownKeys = (target) => {
7404 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
7405 `The keys will be empty in production mode to avoid performance overhead.`);
7406 return Reflect.ownKeys(target);
7407 };
7408}
7409const RuntimeCompiledPublicInstanceProxyHandlers = extend({}, PublicInstanceProxyHandlers, {
7410 get(target, key) {
7411 // fast path for unscopables when using `with` block
7412 if (key === Symbol.unscopables) {
7413 return;
7414 }
7415 return PublicInstanceProxyHandlers.get(target, key, target);
7416 },
7417 has(_, key) {
7418 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
7419 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
7420 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
7421 }
7422 return has;
7423 }
7424});
7425// In dev mode, the proxy target exposes the same properties as seen on `this`
7426// for easier console inspection. In prod mode it will be an empty object so
7427// these properties definitions can be skipped.
7428function createRenderContext(instance) {
7429 const target = {};
7430 // expose internal instance for proxy handlers
7431 Object.defineProperty(target, `_`, {
7432 configurable: true,
7433 enumerable: false,
7434 get: () => instance
7435 });
7436 // expose public properties
7437 Object.keys(publicPropertiesMap).forEach(key => {
7438 Object.defineProperty(target, key, {
7439 configurable: true,
7440 enumerable: false,
7441 get: () => publicPropertiesMap[key](instance),
7442 // intercepted by the proxy so no need for implementation,
7443 // but needed to prevent set errors
7444 set: NOOP
7445 });
7446 });
7447 // expose global properties
7448 const { globalProperties } = instance.appContext.config;
7449 Object.keys(globalProperties).forEach(key => {
7450 Object.defineProperty(target, key, {
7451 configurable: true,
7452 enumerable: false,
7453 get: () => globalProperties[key],
7454 set: NOOP
7455 });
7456 });
7457 return target;
7458}
7459// dev only
7460function exposePropsOnRenderContext(instance) {
7461 const { ctx, propsOptions: [propsOptions] } = instance;
7462 if (propsOptions) {
7463 Object.keys(propsOptions).forEach(key => {
7464 Object.defineProperty(ctx, key, {
7465 enumerable: true,
7466 configurable: true,
7467 get: () => instance.props[key],
7468 set: NOOP
7469 });
7470 });
7471 }
7472}
7473// dev only
7474function exposeSetupStateOnRenderContext(instance) {
7475 const { ctx, setupState } = instance;
7476 Object.keys(toRaw(setupState)).forEach(key => {
7477 if (key[0] === '$' || key[0] === '_') {
7478 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
7479 `which are reserved prefixes for Vue internals.`);
7480 return;
7481 }
7482 Object.defineProperty(ctx, key, {
7483 enumerable: true,
7484 configurable: true,
7485 get: () => setupState[key],
7486 set: NOOP
7487 });
7488 });
7489}
7490
7491const emptyAppContext = createAppContext();
7492let uid$2 = 0;
7493function createComponentInstance(vnode, parent, suspense) {
7494 const type = vnode.type;
7495 // inherit parent app context - or - if root, adopt from root vnode
7496 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
7497 const instance = {
7498 uid: uid$2++,
7499 vnode,
7500 type,
7501 parent,
7502 appContext,
7503 root: null,
7504 next: null,
7505 subTree: null,
7506 update: null,
7507 render: null,
7508 proxy: null,
7509 exposed: null,
7510 withProxy: null,
7511 effects: null,
7512 provides: parent ? parent.provides : Object.create(appContext.provides),
7513 accessCache: null,
7514 renderCache: [],
7515 // local resovled assets
7516 components: null,
7517 directives: null,
7518 // resolved props and emits options
7519 propsOptions: normalizePropsOptions(type, appContext),
7520 emitsOptions: normalizeEmitsOptions(type, appContext),
7521 // emit
7522 emit: null,
7523 emitted: null,
7524 // state
7525 ctx: EMPTY_OBJ,
7526 data: EMPTY_OBJ,
7527 props: EMPTY_OBJ,
7528 attrs: EMPTY_OBJ,
7529 slots: EMPTY_OBJ,
7530 refs: EMPTY_OBJ,
7531 setupState: EMPTY_OBJ,
7532 setupContext: null,
7533 // suspense related
7534 suspense,
7535 suspenseId: suspense ? suspense.pendingId : 0,
7536 asyncDep: null,
7537 asyncResolved: false,
7538 // lifecycle hooks
7539 // not using enums here because it results in computed properties
7540 isMounted: false,
7541 isUnmounted: false,
7542 isDeactivated: false,
7543 bc: null,
7544 c: null,
7545 bm: null,
7546 m: null,
7547 bu: null,
7548 u: null,
7549 um: null,
7550 bum: null,
7551 da: null,
7552 a: null,
7553 rtg: null,
7554 rtc: null,
7555 ec: null
7556 };
7557 {
7558 instance.ctx = createRenderContext(instance);
7559 }
7560 instance.root = parent ? parent.root : instance;
7561 instance.emit = emit.bind(null, instance);
7562 return instance;
7563}
7564let currentInstance = null;
7565const getCurrentInstance = () => currentInstance || currentRenderingInstance;
7566const setCurrentInstance = (instance) => {
7567 currentInstance = instance;
7568};
7569const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
7570function validateComponentName(name, config) {
7571 const appIsNativeTag = config.isNativeTag || NO;
7572 if (isBuiltInTag(name) || appIsNativeTag(name)) {
7573 warn('Do not use built-in or reserved HTML elements as component id: ' + name);
7574 }
7575}
7576function isStatefulComponent(instance) {
7577 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
7578}
7579let isInSSRComponentSetup = false;
7580function setupComponent(instance, isSSR = false) {
7581 isInSSRComponentSetup = isSSR;
7582 const { props, children } = instance.vnode;
7583 const isStateful = isStatefulComponent(instance);
7584 initProps(instance, props, isStateful, isSSR);
7585 initSlots(instance, children);
7586 const setupResult = isStateful
7587 ? setupStatefulComponent(instance, isSSR)
7588 : undefined;
7589 isInSSRComponentSetup = false;
7590 return setupResult;
7591}
7592function setupStatefulComponent(instance, isSSR) {
7593 const Component = instance.type;
7594 {
7595 if (Component.name) {
7596 validateComponentName(Component.name, instance.appContext.config);
7597 }
7598 if (Component.components) {
7599 const names = Object.keys(Component.components);
7600 for (let i = 0; i < names.length; i++) {
7601 validateComponentName(names[i], instance.appContext.config);
7602 }
7603 }
7604 if (Component.directives) {
7605 const names = Object.keys(Component.directives);
7606 for (let i = 0; i < names.length; i++) {
7607 validateDirectiveName(names[i]);
7608 }
7609 }
7610 }
7611 // 0. create render proxy property access cache
7612 instance.accessCache = Object.create(null);
7613 // 1. create public instance / render proxy
7614 // also mark it raw so it's never observed
7615 instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
7616 {
7617 exposePropsOnRenderContext(instance);
7618 }
7619 // 2. call setup()
7620 const { setup } = Component;
7621 if (setup) {
7622 const setupContext = (instance.setupContext =
7623 setup.length > 1 ? createSetupContext(instance) : null);
7624 currentInstance = instance;
7625 pauseTracking();
7626 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
7627 resetTracking();
7628 currentInstance = null;
7629 if (isPromise(setupResult)) {
7630 if (isSSR) {
7631 // return the promise so server-renderer can wait on it
7632 return setupResult.then((resolvedResult) => {
7633 handleSetupResult(instance, resolvedResult);
7634 });
7635 }
7636 else {
7637 // async setup returned Promise.
7638 // bail here and wait for re-entry.
7639 instance.asyncDep = setupResult;
7640 }
7641 }
7642 else {
7643 handleSetupResult(instance, setupResult);
7644 }
7645 }
7646 else {
7647 finishComponentSetup(instance);
7648 }
7649}
7650function handleSetupResult(instance, setupResult, isSSR) {
7651 if (isFunction(setupResult)) {
7652 // setup returned an inline render function
7653 {
7654 instance.render = setupResult;
7655 }
7656 }
7657 else if (isObject(setupResult)) {
7658 if (isVNode(setupResult)) {
7659 warn(`setup() should not return VNodes directly - ` +
7660 `return a render function instead.`);
7661 }
7662 // setup returned bindings.
7663 // assuming a render function compiled from template is present.
7664 {
7665 instance.devtoolsRawSetupState = setupResult;
7666 }
7667 instance.setupState = proxyRefs(setupResult);
7668 {
7669 exposeSetupStateOnRenderContext(instance);
7670 }
7671 }
7672 else if (setupResult !== undefined) {
7673 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
7674 }
7675 finishComponentSetup(instance);
7676}
7677let compile;
7678// dev only
7679const isRuntimeOnly = () => !compile;
7680/**
7681 * For runtime-dom to register the compiler.
7682 * Note the exported method uses any to avoid d.ts relying on the compiler types.
7683 */
7684function registerRuntimeCompiler(_compile) {
7685 compile = _compile;
7686}
7687function finishComponentSetup(instance, isSSR) {
7688 const Component = instance.type;
7689 // template / render function normalization
7690 if (!instance.render) {
7691 // could be set from setup()
7692 if (compile && Component.template && !Component.render) {
7693 {
7694 startMeasure(instance, `compile`);
7695 }
7696 Component.render = compile(Component.template, {
7697 isCustomElement: instance.appContext.config.isCustomElement,
7698 delimiters: Component.delimiters
7699 });
7700 {
7701 endMeasure(instance, `compile`);
7702 }
7703 }
7704 instance.render = (Component.render || NOOP);
7705 // for runtime-compiled render functions using `with` blocks, the render
7706 // proxy used needs a different `has` handler which is more performant and
7707 // also only allows a whitelist of globals to fallthrough.
7708 if (instance.render._rc) {
7709 instance.withProxy = new Proxy(instance.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
7710 }
7711 }
7712 // support for 2.x options
7713 {
7714 currentInstance = instance;
7715 pauseTracking();
7716 applyOptions(instance, Component);
7717 resetTracking();
7718 currentInstance = null;
7719 }
7720 // warn missing template/render
7721 if (!Component.render && instance.render === NOOP) {
7722 /* istanbul ignore if */
7723 if (!compile && Component.template) {
7724 warn(`Component provided template option but ` +
7725 `runtime compilation is not supported in this build of Vue.` +
7726 (` Use "vue.esm-browser.js" instead.`
7727 ) /* should not happen */);
7728 }
7729 else {
7730 warn(`Component is missing template or render function.`);
7731 }
7732 }
7733}
7734const attrHandlers = {
7735 get: (target, key) => {
7736 {
7737 markAttrsAccessed();
7738 }
7739 return target[key];
7740 },
7741 set: () => {
7742 warn(`setupContext.attrs is readonly.`);
7743 return false;
7744 },
7745 deleteProperty: () => {
7746 warn(`setupContext.attrs is readonly.`);
7747 return false;
7748 }
7749};
7750function createSetupContext(instance) {
7751 const expose = exposed => {
7752 if (instance.exposed) {
7753 warn(`expose() should be called only once per setup().`);
7754 }
7755 instance.exposed = proxyRefs(exposed);
7756 };
7757 {
7758 // We use getters in dev in case libs like test-utils overwrite instance
7759 // properties (overwrites should not be done in prod)
7760 return Object.freeze({
7761 get props() {
7762 return instance.props;
7763 },
7764 get attrs() {
7765 return new Proxy(instance.attrs, attrHandlers);
7766 },
7767 get slots() {
7768 return shallowReadonly(instance.slots);
7769 },
7770 get emit() {
7771 return (event, ...args) => instance.emit(event, ...args);
7772 },
7773 expose
7774 });
7775 }
7776}
7777// record effects created during a component's setup() so that they can be
7778// stopped when the component unmounts
7779function recordInstanceBoundEffect(effect, instance = currentInstance) {
7780 if (instance) {
7781 (instance.effects || (instance.effects = [])).push(effect);
7782 }
7783}
7784const classifyRE = /(?:^|[-_])(\w)/g;
7785const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
7786function getComponentName(Component) {
7787 return isFunction(Component)
7788 ? Component.displayName || Component.name
7789 : Component.name;
7790}
7791/* istanbul ignore next */
7792function formatComponentName(instance, Component, isRoot = false) {
7793 let name = getComponentName(Component);
7794 if (!name && Component.__file) {
7795 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
7796 if (match) {
7797 name = match[1];
7798 }
7799 }
7800 if (!name && instance && instance.parent) {
7801 // try to infer the name based on reverse resolution
7802 const inferFromRegistry = (registry) => {
7803 for (const key in registry) {
7804 if (registry[key] === Component) {
7805 return key;
7806 }
7807 }
7808 };
7809 name =
7810 inferFromRegistry(instance.components ||
7811 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
7812 }
7813 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
7814}
7815function isClassComponent(value) {
7816 return isFunction(value) && '__vccOpts' in value;
7817}
7818
7819function computed$1(getterOrOptions) {
7820 const c = computed(getterOrOptions);
7821 recordInstanceBoundEffect(c.effect);
7822 return c;
7823}
7824
7825// implementation
7826function defineProps() {
7827 {
7828 warn(`defineProps() is a compiler-hint helper that is only usable inside ` +
7829 `<script setup> of a single file component. Its arguments should be ` +
7830 `compiled away and passing it at runtime has no effect.`);
7831 }
7832 return null;
7833}
7834// implementation
7835function defineEmit() {
7836 {
7837 warn(`defineEmit() is a compiler-hint helper that is only usable inside ` +
7838 `<script setup> of a single file component. Its arguments should be ` +
7839 `compiled away and passing it at runtime has no effect.`);
7840 }
7841 return null;
7842}
7843function useContext() {
7844 const i = getCurrentInstance();
7845 if (!i) {
7846 warn(`useContext() called without active instance.`);
7847 }
7848 return i.setupContext || (i.setupContext = createSetupContext(i));
7849}
7850
7851// Actual implementation
7852function h(type, propsOrChildren, children) {
7853 const l = arguments.length;
7854 if (l === 2) {
7855 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
7856 // single vnode without props
7857 if (isVNode(propsOrChildren)) {
7858 return createVNode(type, null, [propsOrChildren]);
7859 }
7860 // props without children
7861 return createVNode(type, propsOrChildren);
7862 }
7863 else {
7864 // omit props
7865 return createVNode(type, null, propsOrChildren);
7866 }
7867 }
7868 else {
7869 if (l > 3) {
7870 children = Array.prototype.slice.call(arguments, 2);
7871 }
7872 else if (l === 3 && isVNode(children)) {
7873 children = [children];
7874 }
7875 return createVNode(type, propsOrChildren, children);
7876 }
7877}
7878
7879const ssrContextKey = Symbol(`ssrContext` );
7880const useSSRContext = () => {
7881 {
7882 const ctx = inject(ssrContextKey);
7883 if (!ctx) {
7884 warn(`Server rendering context not provided. Make sure to only call ` +
7885 `useSSRContext() conditionally in the server build.`);
7886 }
7887 return ctx;
7888 }
7889};
7890
7891function initCustomFormatter() {
7892 /* eslint-disable no-restricted-globals */
7893 if (typeof window === 'undefined') {
7894 return;
7895 }
7896 const vueStyle = { style: 'color:#3ba776' };
7897 const numberStyle = { style: 'color:#0b1bc9' };
7898 const stringStyle = { style: 'color:#b62e24' };
7899 const keywordStyle = { style: 'color:#9d288c' };
7900 // custom formatter for Chrome
7901 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
7902 const formatter = {
7903 header(obj) {
7904 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
7905 if (!isObject(obj)) {
7906 return null;
7907 }
7908 if (obj.__isVue) {
7909 return ['div', vueStyle, `VueInstance`];
7910 }
7911 else if (isRef(obj)) {
7912 return [
7913 'div',
7914 {},
7915 ['span', vueStyle, genRefFlag(obj)],
7916 '<',
7917 formatValue(obj.value),
7918 `>`
7919 ];
7920 }
7921 else if (isReactive(obj)) {
7922 return [
7923 'div',
7924 {},
7925 ['span', vueStyle, 'Reactive'],
7926 '<',
7927 formatValue(obj),
7928 `>${isReadonly(obj) ? ` (readonly)` : ``}`
7929 ];
7930 }
7931 else if (isReadonly(obj)) {
7932 return [
7933 'div',
7934 {},
7935 ['span', vueStyle, 'Readonly'],
7936 '<',
7937 formatValue(obj),
7938 '>'
7939 ];
7940 }
7941 return null;
7942 },
7943 hasBody(obj) {
7944 return obj && obj.__isVue;
7945 },
7946 body(obj) {
7947 if (obj && obj.__isVue) {
7948 return [
7949 'div',
7950 {},
7951 ...formatInstance(obj.$)
7952 ];
7953 }
7954 }
7955 };
7956 function formatInstance(instance) {
7957 const blocks = [];
7958 if (instance.type.props && instance.props) {
7959 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
7960 }
7961 if (instance.setupState !== EMPTY_OBJ) {
7962 blocks.push(createInstanceBlock('setup', instance.setupState));
7963 }
7964 if (instance.data !== EMPTY_OBJ) {
7965 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
7966 }
7967 const computed = extractKeys(instance, 'computed');
7968 if (computed) {
7969 blocks.push(createInstanceBlock('computed', computed));
7970 }
7971 const injected = extractKeys(instance, 'inject');
7972 if (injected) {
7973 blocks.push(createInstanceBlock('injected', injected));
7974 }
7975 blocks.push([
7976 'div',
7977 {},
7978 [
7979 'span',
7980 {
7981 style: keywordStyle.style + ';opacity:0.66'
7982 },
7983 '$ (internal): '
7984 ],
7985 ['object', { object: instance }]
7986 ]);
7987 return blocks;
7988 }
7989 function createInstanceBlock(type, target) {
7990 target = extend({}, target);
7991 if (!Object.keys(target).length) {
7992 return ['span', {}];
7993 }
7994 return [
7995 'div',
7996 { style: 'line-height:1.25em;margin-bottom:0.6em' },
7997 [
7998 'div',
7999 {
8000 style: 'color:#476582'
8001 },
8002 type
8003 ],
8004 [
8005 'div',
8006 {
8007 style: 'padding-left:1.25em'
8008 },
8009 ...Object.keys(target).map(key => {
8010 return [
8011 'div',
8012 {},
8013 ['span', keywordStyle, key + ': '],
8014 formatValue(target[key], false)
8015 ];
8016 })
8017 ]
8018 ];
8019 }
8020 function formatValue(v, asRaw = true) {
8021 if (typeof v === 'number') {
8022 return ['span', numberStyle, v];
8023 }
8024 else if (typeof v === 'string') {
8025 return ['span', stringStyle, JSON.stringify(v)];
8026 }
8027 else if (typeof v === 'boolean') {
8028 return ['span', keywordStyle, v];
8029 }
8030 else if (isObject(v)) {
8031 return ['object', { object: asRaw ? toRaw(v) : v }];
8032 }
8033 else {
8034 return ['span', stringStyle, String(v)];
8035 }
8036 }
8037 function extractKeys(instance, type) {
8038 const Comp = instance.type;
8039 if (isFunction(Comp)) {
8040 return;
8041 }
8042 const extracted = {};
8043 for (const key in instance.ctx) {
8044 if (isKeyOfType(Comp, key, type)) {
8045 extracted[key] = instance.ctx[key];
8046 }
8047 }
8048 return extracted;
8049 }
8050 function isKeyOfType(Comp, key, type) {
8051 const opts = Comp[type];
8052 if ((isArray(opts) && opts.includes(key)) ||
8053 (isObject(opts) && key in opts)) {
8054 return true;
8055 }
8056 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
8057 return true;
8058 }
8059 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
8060 return true;
8061 }
8062 }
8063 function genRefFlag(v) {
8064 if (v._shallow) {
8065 return `ShallowRef`;
8066 }
8067 if (v.effect) {
8068 return `ComputedRef`;
8069 }
8070 return `Ref`;
8071 }
8072 if (window.devtoolsFormatters) {
8073 window.devtoolsFormatters.push(formatter);
8074 }
8075 else {
8076 window.devtoolsFormatters = [formatter];
8077 }
8078}
8079
8080/**
8081 * Actual implementation
8082 */
8083function renderList(source, renderItem) {
8084 let ret;
8085 if (isArray(source) || isString(source)) {
8086 ret = new Array(source.length);
8087 for (let i = 0, l = source.length; i < l; i++) {
8088 ret[i] = renderItem(source[i], i);
8089 }
8090 }
8091 else if (typeof source === 'number') {
8092 if (!Number.isInteger(source)) {
8093 warn(`The v-for range expect an integer value but got ${source}.`);
8094 return [];
8095 }
8096 ret = new Array(source);
8097 for (let i = 0; i < source; i++) {
8098 ret[i] = renderItem(i + 1, i);
8099 }
8100 }
8101 else if (isObject(source)) {
8102 if (source[Symbol.iterator]) {
8103 ret = Array.from(source, renderItem);
8104 }
8105 else {
8106 const keys = Object.keys(source);
8107 ret = new Array(keys.length);
8108 for (let i = 0, l = keys.length; i < l; i++) {
8109 const key = keys[i];
8110 ret[i] = renderItem(source[key], key, i);
8111 }
8112 }
8113 }
8114 else {
8115 ret = [];
8116 }
8117 return ret;
8118}
8119
8120/**
8121 * For prefixing keys in v-on="obj" with "on"
8122 * @private
8123 */
8124function toHandlers(obj) {
8125 const ret = {};
8126 if (!isObject(obj)) {
8127 warn(`v-on with no argument expects an object value.`);
8128 return ret;
8129 }
8130 for (const key in obj) {
8131 ret[toHandlerKey(key)] = obj[key];
8132 }
8133 return ret;
8134}
8135
8136/**
8137 * Compiler runtime helper for creating dynamic slots object
8138 * @private
8139 */
8140function createSlots(slots, dynamicSlots) {
8141 for (let i = 0; i < dynamicSlots.length; i++) {
8142 const slot = dynamicSlots[i];
8143 // array of dynamic slot generated by <template v-for="..." #[...]>
8144 if (isArray(slot)) {
8145 for (let j = 0; j < slot.length; j++) {
8146 slots[slot[j].name] = slot[j].fn;
8147 }
8148 }
8149 else if (slot) {
8150 // conditional single slot generated by <template v-if="..." #foo>
8151 slots[slot.name] = slot.fn;
8152 }
8153 }
8154 return slots;
8155}
8156
8157// Core API ------------------------------------------------------------------
8158const version = "3.0.7";
8159/**
8160 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
8161 * @internal
8162 */
8163const ssrUtils = (null);
8164
8165const svgNS = 'http://www.w3.org/2000/svg';
8166const doc = (typeof document !== 'undefined' ? document : null);
8167let tempContainer;
8168let tempSVGContainer;
8169const nodeOps = {
8170 insert: (child, parent, anchor) => {
8171 parent.insertBefore(child, anchor || null);
8172 },
8173 remove: child => {
8174 const parent = child.parentNode;
8175 if (parent) {
8176 parent.removeChild(child);
8177 }
8178 },
8179 createElement: (tag, isSVG, is) => isSVG
8180 ? doc.createElementNS(svgNS, tag)
8181 : doc.createElement(tag, is ? { is } : undefined),
8182 createText: text => doc.createTextNode(text),
8183 createComment: text => doc.createComment(text),
8184 setText: (node, text) => {
8185 node.nodeValue = text;
8186 },
8187 setElementText: (el, text) => {
8188 el.textContent = text;
8189 },
8190 parentNode: node => node.parentNode,
8191 nextSibling: node => node.nextSibling,
8192 querySelector: selector => doc.querySelector(selector),
8193 setScopeId(el, id) {
8194 el.setAttribute(id, '');
8195 },
8196 cloneNode(el) {
8197 return el.cloneNode(true);
8198 },
8199 // __UNSAFE__
8200 // Reason: innerHTML.
8201 // Static content here can only come from compiled templates.
8202 // As long as the user only uses trusted templates, this is safe.
8203 insertStaticContent(content, parent, anchor, isSVG) {
8204 const temp = isSVG
8205 ? tempSVGContainer ||
8206 (tempSVGContainer = doc.createElementNS(svgNS, 'svg'))
8207 : tempContainer || (tempContainer = doc.createElement('div'));
8208 temp.innerHTML = content;
8209 const first = temp.firstChild;
8210 let node = first;
8211 let last = node;
8212 while (node) {
8213 last = node;
8214 nodeOps.insert(node, parent, anchor);
8215 node = temp.firstChild;
8216 }
8217 return [first, last];
8218 }
8219};
8220
8221// compiler should normalize class + :class bindings on the same element
8222// into a single binding ['staticClass', dynamic]
8223function patchClass(el, value, isSVG) {
8224 if (value == null) {
8225 value = '';
8226 }
8227 if (isSVG) {
8228 el.setAttribute('class', value);
8229 }
8230 else {
8231 // directly setting className should be faster than setAttribute in theory
8232 // if this is an element during a transition, take the temporary transition
8233 // classes into account.
8234 const transitionClasses = el._vtc;
8235 if (transitionClasses) {
8236 value = (value
8237 ? [value, ...transitionClasses]
8238 : [...transitionClasses]).join(' ');
8239 }
8240 el.className = value;
8241 }
8242}
8243
8244function patchStyle(el, prev, next) {
8245 const style = el.style;
8246 if (!next) {
8247 el.removeAttribute('style');
8248 }
8249 else if (isString(next)) {
8250 if (prev !== next) {
8251 const current = style.display;
8252 style.cssText = next;
8253 // indicates that the `display` of the element is controlled by `v-show`,
8254 // so we always keep the current `display` value regardless of the `style` value,
8255 // thus handing over control to `v-show`.
8256 if ('_vod' in el) {
8257 style.display = current;
8258 }
8259 }
8260 }
8261 else {
8262 for (const key in next) {
8263 setStyle(style, key, next[key]);
8264 }
8265 if (prev && !isString(prev)) {
8266 for (const key in prev) {
8267 if (next[key] == null) {
8268 setStyle(style, key, '');
8269 }
8270 }
8271 }
8272 }
8273}
8274const importantRE = /\s*!important$/;
8275function setStyle(style, name, val) {
8276 if (isArray(val)) {
8277 val.forEach(v => setStyle(style, name, v));
8278 }
8279 else {
8280 if (name.startsWith('--')) {
8281 // custom property definition
8282 style.setProperty(name, val);
8283 }
8284 else {
8285 const prefixed = autoPrefix(style, name);
8286 if (importantRE.test(val)) {
8287 // !important
8288 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
8289 }
8290 else {
8291 style[prefixed] = val;
8292 }
8293 }
8294 }
8295}
8296const prefixes = ['Webkit', 'Moz', 'ms'];
8297const prefixCache = {};
8298function autoPrefix(style, rawName) {
8299 const cached = prefixCache[rawName];
8300 if (cached) {
8301 return cached;
8302 }
8303 let name = camelize(rawName);
8304 if (name !== 'filter' && name in style) {
8305 return (prefixCache[rawName] = name);
8306 }
8307 name = capitalize(name);
8308 for (let i = 0; i < prefixes.length; i++) {
8309 const prefixed = prefixes[i] + name;
8310 if (prefixed in style) {
8311 return (prefixCache[rawName] = prefixed);
8312 }
8313 }
8314 return rawName;
8315}
8316
8317const xlinkNS = 'http://www.w3.org/1999/xlink';
8318function patchAttr(el, key, value, isSVG) {
8319 if (isSVG && key.startsWith('xlink:')) {
8320 if (value == null) {
8321 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
8322 }
8323 else {
8324 el.setAttributeNS(xlinkNS, key, value);
8325 }
8326 }
8327 else {
8328 // note we are only checking boolean attributes that don't have a
8329 // corresponding dom prop of the same name here.
8330 const isBoolean = isSpecialBooleanAttr(key);
8331 if (value == null || (isBoolean && value === false)) {
8332 el.removeAttribute(key);
8333 }
8334 else {
8335 el.setAttribute(key, isBoolean ? '' : value);
8336 }
8337 }
8338}
8339
8340// __UNSAFE__
8341// functions. The user is responsible for using them with only trusted content.
8342function patchDOMProp(el, key, value,
8343// the following args are passed only due to potential innerHTML/textContent
8344// overriding existing VNodes, in which case the old tree must be properly
8345// unmounted.
8346prevChildren, parentComponent, parentSuspense, unmountChildren) {
8347 if (key === 'innerHTML' || key === 'textContent') {
8348 if (prevChildren) {
8349 unmountChildren(prevChildren, parentComponent, parentSuspense);
8350 }
8351 el[key] = value == null ? '' : value;
8352 return;
8353 }
8354 if (key === 'value' && el.tagName !== 'PROGRESS') {
8355 // store value as _value as well since
8356 // non-string values will be stringified.
8357 el._value = value;
8358 const newValue = value == null ? '' : value;
8359 if (el.value !== newValue) {
8360 el.value = newValue;
8361 }
8362 return;
8363 }
8364 if (value === '' || value == null) {
8365 const type = typeof el[key];
8366 if (value === '' && type === 'boolean') {
8367 // e.g. <select multiple> compiles to { multiple: '' }
8368 el[key] = true;
8369 return;
8370 }
8371 else if (value == null && type === 'string') {
8372 // e.g. <div :id="null">
8373 el[key] = '';
8374 el.removeAttribute(key);
8375 return;
8376 }
8377 else if (type === 'number') {
8378 // e.g. <img :width="null">
8379 el[key] = 0;
8380 el.removeAttribute(key);
8381 return;
8382 }
8383 }
8384 // some properties perform value validation and throw
8385 try {
8386 el[key] = value;
8387 }
8388 catch (e) {
8389 {
8390 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
8391 `value ${value} is invalid.`, e);
8392 }
8393 }
8394}
8395
8396// Async edge case fix requires storing an event listener's attach timestamp.
8397let _getNow = Date.now;
8398// Determine what event timestamp the browser is using. Annoyingly, the
8399// timestamp can either be hi-res (relative to page load) or low-res
8400// (relative to UNIX epoch), so in order to compare time we have to use the
8401// same timestamp type when saving the flush timestamp.
8402if (typeof document !== 'undefined' &&
8403 _getNow() > document.createEvent('Event').timeStamp) {
8404 // if the low-res timestamp which is bigger than the event timestamp
8405 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
8406 // and we need to use the hi-res version for event listeners as well.
8407 _getNow = () => performance.now();
8408}
8409// To avoid the overhead of repeatedly calling performance.now(), we cache
8410// and use the same timestamp for all event listeners attached in the same tick.
8411let cachedNow = 0;
8412const p = Promise.resolve();
8413const reset = () => {
8414 cachedNow = 0;
8415};
8416const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
8417function addEventListener(el, event, handler, options) {
8418 el.addEventListener(event, handler, options);
8419}
8420function removeEventListener(el, event, handler, options) {
8421 el.removeEventListener(event, handler, options);
8422}
8423function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
8424 // vei = vue event invokers
8425 const invokers = el._vei || (el._vei = {});
8426 const existingInvoker = invokers[rawName];
8427 if (nextValue && existingInvoker) {
8428 // patch
8429 existingInvoker.value = nextValue;
8430 }
8431 else {
8432 const [name, options] = parseName(rawName);
8433 if (nextValue) {
8434 // add
8435 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
8436 addEventListener(el, name, invoker, options);
8437 }
8438 else if (existingInvoker) {
8439 // remove
8440 removeEventListener(el, name, existingInvoker, options);
8441 invokers[rawName] = undefined;
8442 }
8443 }
8444}
8445const optionsModifierRE = /(?:Once|Passive|Capture)$/;
8446function parseName(name) {
8447 let options;
8448 if (optionsModifierRE.test(name)) {
8449 options = {};
8450 let m;
8451 while ((m = name.match(optionsModifierRE))) {
8452 name = name.slice(0, name.length - m[0].length);
8453 options[m[0].toLowerCase()] = true;
8454 }
8455 }
8456 return [hyphenate(name.slice(2)), options];
8457}
8458function createInvoker(initialValue, instance) {
8459 const invoker = (e) => {
8460 // async edge case #6566: inner click event triggers patch, event handler
8461 // attached to outer element during patch, and triggered again. This
8462 // happens because browsers fire microtask ticks between event propagation.
8463 // the solution is simple: we save the timestamp when a handler is attached,
8464 // and the handler would only fire if the event passed to it was fired
8465 // AFTER it was attached.
8466 const timeStamp = e.timeStamp || _getNow();
8467 if (timeStamp >= invoker.attached - 1) {
8468 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
8469 }
8470 };
8471 invoker.value = initialValue;
8472 invoker.attached = getNow();
8473 return invoker;
8474}
8475function patchStopImmediatePropagation(e, value) {
8476 if (isArray(value)) {
8477 const originalStop = e.stopImmediatePropagation;
8478 e.stopImmediatePropagation = () => {
8479 originalStop.call(e);
8480 e._stopped = true;
8481 };
8482 return value.map(fn => (e) => !e._stopped && fn(e));
8483 }
8484 else {
8485 return value;
8486 }
8487}
8488
8489const nativeOnRE = /^on[a-z]/;
8490const forcePatchProp = (_, key) => key === 'value';
8491const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
8492 switch (key) {
8493 // special
8494 case 'class':
8495 patchClass(el, nextValue, isSVG);
8496 break;
8497 case 'style':
8498 patchStyle(el, prevValue, nextValue);
8499 break;
8500 default:
8501 if (isOn(key)) {
8502 // ignore v-model listeners
8503 if (!isModelListener(key)) {
8504 patchEvent(el, key, prevValue, nextValue, parentComponent);
8505 }
8506 }
8507 else if (shouldSetAsProp(el, key, nextValue, isSVG)) {
8508 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
8509 }
8510 else {
8511 // special case for <input v-model type="checkbox"> with
8512 // :true-value & :false-value
8513 // store value as dom properties since non-string values will be
8514 // stringified.
8515 if (key === 'true-value') {
8516 el._trueValue = nextValue;
8517 }
8518 else if (key === 'false-value') {
8519 el._falseValue = nextValue;
8520 }
8521 patchAttr(el, key, nextValue, isSVG);
8522 }
8523 break;
8524 }
8525};
8526function shouldSetAsProp(el, key, value, isSVG) {
8527 if (isSVG) {
8528 // most keys must be set as attribute on svg elements to work
8529 // ...except innerHTML
8530 if (key === 'innerHTML') {
8531 return true;
8532 }
8533 // or native onclick with function values
8534 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
8535 return true;
8536 }
8537 return false;
8538 }
8539 // spellcheck and draggable are numerated attrs, however their
8540 // corresponding DOM properties are actually booleans - this leads to
8541 // setting it with a string "false" value leading it to be coerced to
8542 // `true`, so we need to always treat them as attributes.
8543 // Note that `contentEditable` doesn't have this problem: its DOM
8544 // property is also enumerated string values.
8545 if (key === 'spellcheck' || key === 'draggable') {
8546 return false;
8547 }
8548 // #1787, #2840 form property on form elements is readonly and must be set as
8549 // attribute.
8550 if (key === 'form') {
8551 return false;
8552 }
8553 // #1526 <input list> must be set as attribute
8554 if (key === 'list' && el.tagName === 'INPUT') {
8555 return false;
8556 }
8557 // #2766 <textarea type> must be set as attribute
8558 if (key === 'type' && el.tagName === 'TEXTAREA') {
8559 return false;
8560 }
8561 // native onclick with string value, must be set as attribute
8562 if (nativeOnRE.test(key) && isString(value)) {
8563 return false;
8564 }
8565 return key in el;
8566}
8567
8568function useCssModule(name = '$style') {
8569 /* istanbul ignore else */
8570 {
8571 const instance = getCurrentInstance();
8572 if (!instance) {
8573 warn(`useCssModule must be called inside setup()`);
8574 return EMPTY_OBJ;
8575 }
8576 const modules = instance.type.__cssModules;
8577 if (!modules) {
8578 warn(`Current instance does not have CSS modules injected.`);
8579 return EMPTY_OBJ;
8580 }
8581 const mod = modules[name];
8582 if (!mod) {
8583 warn(`Current instance does not have CSS module named "${name}".`);
8584 return EMPTY_OBJ;
8585 }
8586 return mod;
8587 }
8588}
8589
8590/**
8591 * Runtime helper for SFC's CSS variable injection feature.
8592 * @private
8593 */
8594function useCssVars(getter) {
8595 const instance = getCurrentInstance();
8596 /* istanbul ignore next */
8597 if (!instance) {
8598 warn(`useCssVars is called without current active component instance.`);
8599 return;
8600 }
8601 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
8602 onMounted(() => watchEffect(setVars, { flush: 'post' }));
8603 onUpdated(setVars);
8604}
8605function setVarsOnVNode(vnode, vars) {
8606 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
8607 const suspense = vnode.suspense;
8608 vnode = suspense.activeBranch;
8609 if (suspense.pendingBranch && !suspense.isHydrating) {
8610 suspense.effects.push(() => {
8611 setVarsOnVNode(suspense.activeBranch, vars);
8612 });
8613 }
8614 }
8615 // drill down HOCs until it's a non-component vnode
8616 while (vnode.component) {
8617 vnode = vnode.component.subTree;
8618 }
8619 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
8620 const style = vnode.el.style;
8621 for (const key in vars) {
8622 style.setProperty(`--${key}`, vars[key]);
8623 }
8624 }
8625 else if (vnode.type === Fragment) {
8626 vnode.children.forEach(c => setVarsOnVNode(c, vars));
8627 }
8628}
8629
8630const TRANSITION = 'transition';
8631const ANIMATION = 'animation';
8632// DOM Transition is a higher-order-component based on the platform-agnostic
8633// base Transition component, with DOM-specific logic.
8634const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
8635Transition.displayName = 'Transition';
8636const DOMTransitionPropsValidators = {
8637 name: String,
8638 type: String,
8639 css: {
8640 type: Boolean,
8641 default: true
8642 },
8643 duration: [String, Number, Object],
8644 enterFromClass: String,
8645 enterActiveClass: String,
8646 enterToClass: String,
8647 appearFromClass: String,
8648 appearActiveClass: String,
8649 appearToClass: String,
8650 leaveFromClass: String,
8651 leaveActiveClass: String,
8652 leaveToClass: String
8653};
8654const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
8655function resolveTransitionProps(rawProps) {
8656 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;
8657 const baseProps = {};
8658 for (const key in rawProps) {
8659 if (!(key in DOMTransitionPropsValidators)) {
8660 baseProps[key] = rawProps[key];
8661 }
8662 }
8663 if (!css) {
8664 return baseProps;
8665 }
8666 const durations = normalizeDuration(duration);
8667 const enterDuration = durations && durations[0];
8668 const leaveDuration = durations && durations[1];
8669 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
8670 const finishEnter = (el, isAppear, done) => {
8671 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
8672 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
8673 done && done();
8674 };
8675 const finishLeave = (el, done) => {
8676 removeTransitionClass(el, leaveToClass);
8677 removeTransitionClass(el, leaveActiveClass);
8678 done && done();
8679 };
8680 const makeEnterHook = (isAppear) => {
8681 return (el, done) => {
8682 const hook = isAppear ? onAppear : onEnter;
8683 const resolve = () => finishEnter(el, isAppear, done);
8684 hook && hook(el, resolve);
8685 nextFrame(() => {
8686 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
8687 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
8688 if (!(hook && hook.length > 1)) {
8689 whenTransitionEnds(el, type, enterDuration, resolve);
8690 }
8691 });
8692 };
8693 };
8694 return extend(baseProps, {
8695 onBeforeEnter(el) {
8696 onBeforeEnter && onBeforeEnter(el);
8697 addTransitionClass(el, enterFromClass);
8698 addTransitionClass(el, enterActiveClass);
8699 },
8700 onBeforeAppear(el) {
8701 onBeforeAppear && onBeforeAppear(el);
8702 addTransitionClass(el, appearFromClass);
8703 addTransitionClass(el, appearActiveClass);
8704 },
8705 onEnter: makeEnterHook(false),
8706 onAppear: makeEnterHook(true),
8707 onLeave(el, done) {
8708 const resolve = () => finishLeave(el, done);
8709 addTransitionClass(el, leaveFromClass);
8710 // force reflow so *-leave-from classes immediately take effect (#2593)
8711 forceReflow();
8712 addTransitionClass(el, leaveActiveClass);
8713 nextFrame(() => {
8714 removeTransitionClass(el, leaveFromClass);
8715 addTransitionClass(el, leaveToClass);
8716 if (!(onLeave && onLeave.length > 1)) {
8717 whenTransitionEnds(el, type, leaveDuration, resolve);
8718 }
8719 });
8720 onLeave && onLeave(el, resolve);
8721 },
8722 onEnterCancelled(el) {
8723 finishEnter(el, false);
8724 onEnterCancelled && onEnterCancelled(el);
8725 },
8726 onAppearCancelled(el) {
8727 finishEnter(el, true);
8728 onAppearCancelled && onAppearCancelled(el);
8729 },
8730 onLeaveCancelled(el) {
8731 finishLeave(el);
8732 onLeaveCancelled && onLeaveCancelled(el);
8733 }
8734 });
8735}
8736function normalizeDuration(duration) {
8737 if (duration == null) {
8738 return null;
8739 }
8740 else if (isObject(duration)) {
8741 return [NumberOf(duration.enter), NumberOf(duration.leave)];
8742 }
8743 else {
8744 const n = NumberOf(duration);
8745 return [n, n];
8746 }
8747}
8748function NumberOf(val) {
8749 const res = toNumber(val);
8750 validateDuration(res);
8751 return res;
8752}
8753function validateDuration(val) {
8754 if (typeof val !== 'number') {
8755 warn(`<transition> explicit duration is not a valid number - ` +
8756 `got ${JSON.stringify(val)}.`);
8757 }
8758 else if (isNaN(val)) {
8759 warn(`<transition> explicit duration is NaN - ` +
8760 'the duration expression might be incorrect.');
8761 }
8762}
8763function addTransitionClass(el, cls) {
8764 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
8765 (el._vtc ||
8766 (el._vtc = new Set())).add(cls);
8767}
8768function removeTransitionClass(el, cls) {
8769 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
8770 const { _vtc } = el;
8771 if (_vtc) {
8772 _vtc.delete(cls);
8773 if (!_vtc.size) {
8774 el._vtc = undefined;
8775 }
8776 }
8777}
8778function nextFrame(cb) {
8779 requestAnimationFrame(() => {
8780 requestAnimationFrame(cb);
8781 });
8782}
8783let endId = 0;
8784function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
8785 const id = (el._endId = ++endId);
8786 const resolveIfNotStale = () => {
8787 if (id === el._endId) {
8788 resolve();
8789 }
8790 };
8791 if (explicitTimeout) {
8792 return setTimeout(resolveIfNotStale, explicitTimeout);
8793 }
8794 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
8795 if (!type) {
8796 return resolve();
8797 }
8798 const endEvent = type + 'end';
8799 let ended = 0;
8800 const end = () => {
8801 el.removeEventListener(endEvent, onEnd);
8802 resolveIfNotStale();
8803 };
8804 const onEnd = (e) => {
8805 if (e.target === el && ++ended >= propCount) {
8806 end();
8807 }
8808 };
8809 setTimeout(() => {
8810 if (ended < propCount) {
8811 end();
8812 }
8813 }, timeout + 1);
8814 el.addEventListener(endEvent, onEnd);
8815}
8816function getTransitionInfo(el, expectedType) {
8817 const styles = window.getComputedStyle(el);
8818 // JSDOM may return undefined for transition properties
8819 const getStyleProperties = (key) => (styles[key] || '').split(', ');
8820 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
8821 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
8822 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
8823 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
8824 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
8825 const animationTimeout = getTimeout(animationDelays, animationDurations);
8826 let type = null;
8827 let timeout = 0;
8828 let propCount = 0;
8829 /* istanbul ignore if */
8830 if (expectedType === TRANSITION) {
8831 if (transitionTimeout > 0) {
8832 type = TRANSITION;
8833 timeout = transitionTimeout;
8834 propCount = transitionDurations.length;
8835 }
8836 }
8837 else if (expectedType === ANIMATION) {
8838 if (animationTimeout > 0) {
8839 type = ANIMATION;
8840 timeout = animationTimeout;
8841 propCount = animationDurations.length;
8842 }
8843 }
8844 else {
8845 timeout = Math.max(transitionTimeout, animationTimeout);
8846 type =
8847 timeout > 0
8848 ? transitionTimeout > animationTimeout
8849 ? TRANSITION
8850 : ANIMATION
8851 : null;
8852 propCount = type
8853 ? type === TRANSITION
8854 ? transitionDurations.length
8855 : animationDurations.length
8856 : 0;
8857 }
8858 const hasTransform = type === TRANSITION &&
8859 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
8860 return {
8861 type,
8862 timeout,
8863 propCount,
8864 hasTransform
8865 };
8866}
8867function getTimeout(delays, durations) {
8868 while (delays.length < durations.length) {
8869 delays = delays.concat(delays);
8870 }
8871 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
8872}
8873// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
8874// numbers in a locale-dependent way, using a comma instead of a dot.
8875// If comma is not replaced with a dot, the input will be rounded down
8876// (i.e. acting as a floor function) causing unexpected behaviors
8877function toMs(s) {
8878 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
8879}
8880// synchronously force layout to put elements into a certain state
8881function forceReflow() {
8882 return document.body.offsetHeight;
8883}
8884
8885const positionMap = new WeakMap();
8886const newPositionMap = new WeakMap();
8887const TransitionGroupImpl = {
8888 name: 'TransitionGroup',
8889 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
8890 tag: String,
8891 moveClass: String
8892 }),
8893 setup(props, { slots }) {
8894 const instance = getCurrentInstance();
8895 const state = useTransitionState();
8896 let prevChildren;
8897 let children;
8898 onUpdated(() => {
8899 // children is guaranteed to exist after initial render
8900 if (!prevChildren.length) {
8901 return;
8902 }
8903 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
8904 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
8905 return;
8906 }
8907 // we divide the work into three loops to avoid mixing DOM reads and writes
8908 // in each iteration - which helps prevent layout thrashing.
8909 prevChildren.forEach(callPendingCbs);
8910 prevChildren.forEach(recordPosition);
8911 const movedChildren = prevChildren.filter(applyTranslation);
8912 // force reflow to put everything in position
8913 forceReflow();
8914 movedChildren.forEach(c => {
8915 const el = c.el;
8916 const style = el.style;
8917 addTransitionClass(el, moveClass);
8918 style.transform = style.webkitTransform = style.transitionDuration = '';
8919 const cb = (el._moveCb = (e) => {
8920 if (e && e.target !== el) {
8921 return;
8922 }
8923 if (!e || /transform$/.test(e.propertyName)) {
8924 el.removeEventListener('transitionend', cb);
8925 el._moveCb = null;
8926 removeTransitionClass(el, moveClass);
8927 }
8928 });
8929 el.addEventListener('transitionend', cb);
8930 });
8931 });
8932 return () => {
8933 const rawProps = toRaw(props);
8934 const cssTransitionProps = resolveTransitionProps(rawProps);
8935 const tag = rawProps.tag || Fragment;
8936 prevChildren = children;
8937 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
8938 for (let i = 0; i < children.length; i++) {
8939 const child = children[i];
8940 if (child.key != null) {
8941 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
8942 }
8943 else {
8944 warn(`<TransitionGroup> children must be keyed.`);
8945 }
8946 }
8947 if (prevChildren) {
8948 for (let i = 0; i < prevChildren.length; i++) {
8949 const child = prevChildren[i];
8950 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
8951 positionMap.set(child, child.el.getBoundingClientRect());
8952 }
8953 }
8954 return createVNode(tag, null, children);
8955 };
8956 }
8957};
8958const TransitionGroup = TransitionGroupImpl;
8959function callPendingCbs(c) {
8960 const el = c.el;
8961 if (el._moveCb) {
8962 el._moveCb();
8963 }
8964 if (el._enterCb) {
8965 el._enterCb();
8966 }
8967}
8968function recordPosition(c) {
8969 newPositionMap.set(c, c.el.getBoundingClientRect());
8970}
8971function applyTranslation(c) {
8972 const oldPos = positionMap.get(c);
8973 const newPos = newPositionMap.get(c);
8974 const dx = oldPos.left - newPos.left;
8975 const dy = oldPos.top - newPos.top;
8976 if (dx || dy) {
8977 const s = c.el.style;
8978 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
8979 s.transitionDuration = '0s';
8980 return c;
8981 }
8982}
8983function hasCSSTransform(el, root, moveClass) {
8984 // Detect whether an element with the move class applied has
8985 // CSS transitions. Since the element may be inside an entering
8986 // transition at this very moment, we make a clone of it and remove
8987 // all other transition classes applied to ensure only the move class
8988 // is applied.
8989 const clone = el.cloneNode();
8990 if (el._vtc) {
8991 el._vtc.forEach(cls => {
8992 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
8993 });
8994 }
8995 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
8996 clone.style.display = 'none';
8997 const container = (root.nodeType === 1
8998 ? root
8999 : root.parentNode);
9000 container.appendChild(clone);
9001 const { hasTransform } = getTransitionInfo(clone);
9002 container.removeChild(clone);
9003 return hasTransform;
9004}
9005
9006const getModelAssigner = (vnode) => {
9007 const fn = vnode.props['onUpdate:modelValue'];
9008 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
9009};
9010function onCompositionStart(e) {
9011 e.target.composing = true;
9012}
9013function onCompositionEnd(e) {
9014 const target = e.target;
9015 if (target.composing) {
9016 target.composing = false;
9017 trigger$1(target, 'input');
9018 }
9019}
9020function trigger$1(el, type) {
9021 const e = document.createEvent('HTMLEvents');
9022 e.initEvent(type, true, true);
9023 el.dispatchEvent(e);
9024}
9025// We are exporting the v-model runtime directly as vnode hooks so that it can
9026// be tree-shaken in case v-model is never used.
9027const vModelText = {
9028 created(el, { modifiers: { lazy, trim, number } }, vnode) {
9029 el._assign = getModelAssigner(vnode);
9030 const castToNumber = number || el.type === 'number';
9031 addEventListener(el, lazy ? 'change' : 'input', e => {
9032 if (e.target.composing)
9033 return;
9034 let domValue = el.value;
9035 if (trim) {
9036 domValue = domValue.trim();
9037 }
9038 else if (castToNumber) {
9039 domValue = toNumber(domValue);
9040 }
9041 el._assign(domValue);
9042 });
9043 if (trim) {
9044 addEventListener(el, 'change', () => {
9045 el.value = el.value.trim();
9046 });
9047 }
9048 if (!lazy) {
9049 addEventListener(el, 'compositionstart', onCompositionStart);
9050 addEventListener(el, 'compositionend', onCompositionEnd);
9051 // Safari < 10.2 & UIWebView doesn't fire compositionend when
9052 // switching focus before confirming composition choice
9053 // this also fixes the issue where some browsers e.g. iOS Chrome
9054 // fires "change" instead of "input" on autocomplete.
9055 addEventListener(el, 'change', onCompositionEnd);
9056 }
9057 },
9058 // set value on mounted so it's after min/max for type="range"
9059 mounted(el, { value }) {
9060 el.value = value == null ? '' : value;
9061 },
9062 beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
9063 el._assign = getModelAssigner(vnode);
9064 // avoid clearing unresolved text. #2302
9065 if (el.composing)
9066 return;
9067 if (document.activeElement === el) {
9068 if (trim && el.value.trim() === value) {
9069 return;
9070 }
9071 if ((number || el.type === 'number') && toNumber(el.value) === value) {
9072 return;
9073 }
9074 }
9075 const newValue = value == null ? '' : value;
9076 if (el.value !== newValue) {
9077 el.value = newValue;
9078 }
9079 }
9080};
9081const vModelCheckbox = {
9082 created(el, _, vnode) {
9083 el._assign = getModelAssigner(vnode);
9084 addEventListener(el, 'change', () => {
9085 const modelValue = el._modelValue;
9086 const elementValue = getValue(el);
9087 const checked = el.checked;
9088 const assign = el._assign;
9089 if (isArray(modelValue)) {
9090 const index = looseIndexOf(modelValue, elementValue);
9091 const found = index !== -1;
9092 if (checked && !found) {
9093 assign(modelValue.concat(elementValue));
9094 }
9095 else if (!checked && found) {
9096 const filtered = [...modelValue];
9097 filtered.splice(index, 1);
9098 assign(filtered);
9099 }
9100 }
9101 else if (isSet(modelValue)) {
9102 const cloned = new Set(modelValue);
9103 if (checked) {
9104 cloned.add(elementValue);
9105 }
9106 else {
9107 cloned.delete(elementValue);
9108 }
9109 assign(cloned);
9110 }
9111 else {
9112 assign(getCheckboxValue(el, checked));
9113 }
9114 });
9115 },
9116 // set initial checked on mount to wait for true-value/false-value
9117 mounted: setChecked,
9118 beforeUpdate(el, binding, vnode) {
9119 el._assign = getModelAssigner(vnode);
9120 setChecked(el, binding, vnode);
9121 }
9122};
9123function setChecked(el, { value, oldValue }, vnode) {
9124 el._modelValue = value;
9125 if (isArray(value)) {
9126 el.checked = looseIndexOf(value, vnode.props.value) > -1;
9127 }
9128 else if (isSet(value)) {
9129 el.checked = value.has(vnode.props.value);
9130 }
9131 else if (value !== oldValue) {
9132 el.checked = looseEqual(value, getCheckboxValue(el, true));
9133 }
9134}
9135const vModelRadio = {
9136 created(el, { value }, vnode) {
9137 el.checked = looseEqual(value, vnode.props.value);
9138 el._assign = getModelAssigner(vnode);
9139 addEventListener(el, 'change', () => {
9140 el._assign(getValue(el));
9141 });
9142 },
9143 beforeUpdate(el, { value, oldValue }, vnode) {
9144 el._assign = getModelAssigner(vnode);
9145 if (value !== oldValue) {
9146 el.checked = looseEqual(value, vnode.props.value);
9147 }
9148 }
9149};
9150const vModelSelect = {
9151 created(el, { value, modifiers: { number } }, vnode) {
9152 const isSetModel = isSet(value);
9153 addEventListener(el, 'change', () => {
9154 const selectedVal = Array.prototype.filter
9155 .call(el.options, (o) => o.selected)
9156 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
9157 el._assign(el.multiple
9158 ? isSetModel
9159 ? new Set(selectedVal)
9160 : selectedVal
9161 : selectedVal[0]);
9162 });
9163 el._assign = getModelAssigner(vnode);
9164 },
9165 // set value in mounted & updated because <select> relies on its children
9166 // <option>s.
9167 mounted(el, { value }) {
9168 setSelected(el, value);
9169 },
9170 beforeUpdate(el, _binding, vnode) {
9171 el._assign = getModelAssigner(vnode);
9172 },
9173 updated(el, { value }) {
9174 setSelected(el, value);
9175 }
9176};
9177function setSelected(el, value) {
9178 const isMultiple = el.multiple;
9179 if (isMultiple && !isArray(value) && !isSet(value)) {
9180 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
9181 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
9182 return;
9183 }
9184 for (let i = 0, l = el.options.length; i < l; i++) {
9185 const option = el.options[i];
9186 const optionValue = getValue(option);
9187 if (isMultiple) {
9188 if (isArray(value)) {
9189 option.selected = looseIndexOf(value, optionValue) > -1;
9190 }
9191 else {
9192 option.selected = value.has(optionValue);
9193 }
9194 }
9195 else {
9196 if (looseEqual(getValue(option), value)) {
9197 el.selectedIndex = i;
9198 return;
9199 }
9200 }
9201 }
9202 if (!isMultiple) {
9203 el.selectedIndex = -1;
9204 }
9205}
9206// retrieve raw value set via :value bindings
9207function getValue(el) {
9208 return '_value' in el ? el._value : el.value;
9209}
9210// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
9211function getCheckboxValue(el, checked) {
9212 const key = checked ? '_trueValue' : '_falseValue';
9213 return key in el ? el[key] : checked;
9214}
9215const vModelDynamic = {
9216 created(el, binding, vnode) {
9217 callModelHook(el, binding, vnode, null, 'created');
9218 },
9219 mounted(el, binding, vnode) {
9220 callModelHook(el, binding, vnode, null, 'mounted');
9221 },
9222 beforeUpdate(el, binding, vnode, prevVNode) {
9223 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
9224 },
9225 updated(el, binding, vnode, prevVNode) {
9226 callModelHook(el, binding, vnode, prevVNode, 'updated');
9227 }
9228};
9229function callModelHook(el, binding, vnode, prevVNode, hook) {
9230 let modelToUse;
9231 switch (el.tagName) {
9232 case 'SELECT':
9233 modelToUse = vModelSelect;
9234 break;
9235 case 'TEXTAREA':
9236 modelToUse = vModelText;
9237 break;
9238 default:
9239 switch (vnode.props && vnode.props.type) {
9240 case 'checkbox':
9241 modelToUse = vModelCheckbox;
9242 break;
9243 case 'radio':
9244 modelToUse = vModelRadio;
9245 break;
9246 default:
9247 modelToUse = vModelText;
9248 }
9249 }
9250 const fn = modelToUse[hook];
9251 fn && fn(el, binding, vnode, prevVNode);
9252}
9253
9254const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
9255const modifierGuards = {
9256 stop: e => e.stopPropagation(),
9257 prevent: e => e.preventDefault(),
9258 self: e => e.target !== e.currentTarget,
9259 ctrl: e => !e.ctrlKey,
9260 shift: e => !e.shiftKey,
9261 alt: e => !e.altKey,
9262 meta: e => !e.metaKey,
9263 left: e => 'button' in e && e.button !== 0,
9264 middle: e => 'button' in e && e.button !== 1,
9265 right: e => 'button' in e && e.button !== 2,
9266 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
9267};
9268/**
9269 * @private
9270 */
9271const withModifiers = (fn, modifiers) => {
9272 return (event, ...args) => {
9273 for (let i = 0; i < modifiers.length; i++) {
9274 const guard = modifierGuards[modifiers[i]];
9275 if (guard && guard(event, modifiers))
9276 return;
9277 }
9278 return fn(event, ...args);
9279 };
9280};
9281// Kept for 2.x compat.
9282// Note: IE11 compat for `spacebar` and `del` is removed for now.
9283const keyNames = {
9284 esc: 'escape',
9285 space: ' ',
9286 up: 'arrow-up',
9287 left: 'arrow-left',
9288 right: 'arrow-right',
9289 down: 'arrow-down',
9290 delete: 'backspace'
9291};
9292/**
9293 * @private
9294 */
9295const withKeys = (fn, modifiers) => {
9296 return (event) => {
9297 if (!('key' in event))
9298 return;
9299 const eventKey = hyphenate(event.key);
9300 if (
9301 // None of the provided key modifiers match the current event key
9302 !modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
9303 return;
9304 }
9305 return fn(event);
9306 };
9307};
9308
9309const vShow = {
9310 beforeMount(el, { value }, { transition }) {
9311 el._vod = el.style.display === 'none' ? '' : el.style.display;
9312 if (transition && value) {
9313 transition.beforeEnter(el);
9314 }
9315 else {
9316 setDisplay(el, value);
9317 }
9318 },
9319 mounted(el, { value }, { transition }) {
9320 if (transition && value) {
9321 transition.enter(el);
9322 }
9323 },
9324 updated(el, { value, oldValue }, { transition }) {
9325 if (!value === !oldValue)
9326 return;
9327 if (transition) {
9328 if (value) {
9329 transition.beforeEnter(el);
9330 setDisplay(el, true);
9331 transition.enter(el);
9332 }
9333 else {
9334 transition.leave(el, () => {
9335 setDisplay(el, false);
9336 });
9337 }
9338 }
9339 else {
9340 setDisplay(el, value);
9341 }
9342 },
9343 beforeUnmount(el, { value }) {
9344 setDisplay(el, value);
9345 }
9346};
9347function setDisplay(el, value) {
9348 el.style.display = value ? el._vod : 'none';
9349}
9350
9351const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps);
9352// lazy create the renderer - this makes core renderer logic tree-shakable
9353// in case the user only imports reactivity utilities from Vue.
9354let renderer;
9355let enabledHydration = false;
9356function ensureRenderer() {
9357 return renderer || (renderer = createRenderer(rendererOptions));
9358}
9359function ensureHydrationRenderer() {
9360 renderer = enabledHydration
9361 ? renderer
9362 : createHydrationRenderer(rendererOptions);
9363 enabledHydration = true;
9364 return renderer;
9365}
9366// use explicit type casts here to avoid import() calls in rolled-up d.ts
9367const render = ((...args) => {
9368 ensureRenderer().render(...args);
9369});
9370const hydrate = ((...args) => {
9371 ensureHydrationRenderer().hydrate(...args);
9372});
9373const createApp = ((...args) => {
9374 const app = ensureRenderer().createApp(...args);
9375 {
9376 injectNativeTagCheck(app);
9377 injectCustomElementCheck(app);
9378 }
9379 const { mount } = app;
9380 app.mount = (containerOrSelector) => {
9381 const container = normalizeContainer(containerOrSelector);
9382 if (!container)
9383 return;
9384 const component = app._component;
9385 if (!isFunction(component) && !component.render && !component.template) {
9386 component.template = container.innerHTML;
9387 }
9388 // clear content before mounting
9389 container.innerHTML = '';
9390 const proxy = mount(container);
9391 if (container instanceof Element) {
9392 container.removeAttribute('v-cloak');
9393 container.setAttribute('data-v-app', '');
9394 }
9395 return proxy;
9396 };
9397 return app;
9398});
9399const createSSRApp = ((...args) => {
9400 const app = ensureHydrationRenderer().createApp(...args);
9401 {
9402 injectNativeTagCheck(app);
9403 injectCustomElementCheck(app);
9404 }
9405 const { mount } = app;
9406 app.mount = (containerOrSelector) => {
9407 const container = normalizeContainer(containerOrSelector);
9408 if (container) {
9409 return mount(container, true);
9410 }
9411 };
9412 return app;
9413});
9414function injectNativeTagCheck(app) {
9415 // Inject `isNativeTag`
9416 // this is used for component name validation (dev only)
9417 Object.defineProperty(app.config, 'isNativeTag', {
9418 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
9419 writable: false
9420 });
9421}
9422// dev only
9423function injectCustomElementCheck(app) {
9424 if (isRuntimeOnly()) {
9425 const value = app.config.isCustomElement;
9426 Object.defineProperty(app.config, 'isCustomElement', {
9427 get() {
9428 return value;
9429 },
9430 set() {
9431 warn(`The \`isCustomElement\` config option is only respected when using the runtime compiler.` +
9432 `If you are using the runtime-only build, \`isCustomElement\` must be passed to \`@vue/compiler-dom\` in the build setup instead` +
9433 `- for example, via the \`compilerOptions\` option in vue-loader: https://vue-loader.vuejs.org/options.html#compileroptions.`);
9434 }
9435 });
9436 }
9437}
9438function normalizeContainer(container) {
9439 if (isString(container)) {
9440 const res = document.querySelector(container);
9441 if (!res) {
9442 warn(`Failed to mount app: mount target selector "${container}" returned null.`);
9443 }
9444 return res;
9445 }
9446 if (container instanceof window.ShadowRoot &&
9447 container.mode === 'closed') {
9448 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
9449 }
9450 return container;
9451}
9452
9453var runtimeDom = /*#__PURE__*/Object.freeze({
9454 __proto__: null,
9455 render: render,
9456 hydrate: hydrate,
9457 createApp: createApp,
9458 createSSRApp: createSSRApp,
9459 useCssModule: useCssModule,
9460 useCssVars: useCssVars,
9461 Transition: Transition,
9462 TransitionGroup: TransitionGroup,
9463 vModelText: vModelText,
9464 vModelCheckbox: vModelCheckbox,
9465 vModelRadio: vModelRadio,
9466 vModelSelect: vModelSelect,
9467 vModelDynamic: vModelDynamic,
9468 withModifiers: withModifiers,
9469 withKeys: withKeys,
9470 vShow: vShow,
9471 reactive: reactive,
9472 ref: ref,
9473 readonly: readonly,
9474 unref: unref,
9475 proxyRefs: proxyRefs,
9476 isRef: isRef,
9477 toRef: toRef,
9478 toRefs: toRefs,
9479 isProxy: isProxy,
9480 isReactive: isReactive,
9481 isReadonly: isReadonly,
9482 customRef: customRef,
9483 triggerRef: triggerRef,
9484 shallowRef: shallowRef,
9485 shallowReactive: shallowReactive,
9486 shallowReadonly: shallowReadonly,
9487 markRaw: markRaw,
9488 toRaw: toRaw,
9489 computed: computed$1,
9490 watch: watch,
9491 watchEffect: watchEffect,
9492 onBeforeMount: onBeforeMount,
9493 onMounted: onMounted,
9494 onBeforeUpdate: onBeforeUpdate,
9495 onUpdated: onUpdated,
9496 onBeforeUnmount: onBeforeUnmount,
9497 onUnmounted: onUnmounted,
9498 onActivated: onActivated,
9499 onDeactivated: onDeactivated,
9500 onRenderTracked: onRenderTracked,
9501 onRenderTriggered: onRenderTriggered,
9502 onErrorCaptured: onErrorCaptured,
9503 provide: provide,
9504 inject: inject,
9505 nextTick: nextTick,
9506 defineComponent: defineComponent,
9507 defineAsyncComponent: defineAsyncComponent,
9508 defineProps: defineProps,
9509 defineEmit: defineEmit,
9510 useContext: useContext,
9511 getCurrentInstance: getCurrentInstance,
9512 h: h,
9513 createVNode: createVNode,
9514 cloneVNode: cloneVNode,
9515 mergeProps: mergeProps,
9516 isVNode: isVNode,
9517 Fragment: Fragment,
9518 Text: Text,
9519 Comment: Comment,
9520 Static: Static,
9521 Teleport: Teleport,
9522 Suspense: Suspense,
9523 KeepAlive: KeepAlive,
9524 BaseTransition: BaseTransition,
9525 withDirectives: withDirectives,
9526 useSSRContext: useSSRContext,
9527 ssrContextKey: ssrContextKey,
9528 createRenderer: createRenderer,
9529 createHydrationRenderer: createHydrationRenderer,
9530 queuePostFlushCb: queuePostFlushCb,
9531 warn: warn,
9532 handleError: handleError,
9533 callWithErrorHandling: callWithErrorHandling,
9534 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
9535 resolveComponent: resolveComponent,
9536 resolveDirective: resolveDirective,
9537 resolveDynamicComponent: resolveDynamicComponent,
9538 registerRuntimeCompiler: registerRuntimeCompiler,
9539 isRuntimeOnly: isRuntimeOnly,
9540 useTransitionState: useTransitionState,
9541 resolveTransitionHooks: resolveTransitionHooks,
9542 setTransitionHooks: setTransitionHooks,
9543 getTransitionRawChildren: getTransitionRawChildren,
9544 initCustomFormatter: initCustomFormatter,
9545 get devtools () { return devtools; },
9546 setDevtoolsHook: setDevtoolsHook,
9547 withCtx: withCtx,
9548 renderList: renderList,
9549 toHandlers: toHandlers,
9550 renderSlot: renderSlot,
9551 createSlots: createSlots,
9552 pushScopeId: pushScopeId,
9553 popScopeId: popScopeId,
9554 withScopeId: withScopeId,
9555 openBlock: openBlock,
9556 createBlock: createBlock,
9557 setBlockTracking: setBlockTracking,
9558 createTextVNode: createTextVNode,
9559 createCommentVNode: createCommentVNode,
9560 createStaticVNode: createStaticVNode,
9561 toDisplayString: toDisplayString,
9562 camelize: camelize,
9563 capitalize: capitalize,
9564 toHandlerKey: toHandlerKey,
9565 transformVNodeArgs: transformVNodeArgs,
9566 version: version,
9567 ssrUtils: ssrUtils
9568});
9569
9570function initDev() {
9571 {
9572 {
9573 console.info(`You are running a development build of Vue.\n` +
9574 `Make sure to use the production build (*.prod.js) when deploying for production.`);
9575 }
9576 initCustomFormatter();
9577 }
9578}
9579
9580function defaultOnError(error) {
9581 throw error;
9582}
9583function createCompilerError(code, loc, messages, additionalMessage) {
9584 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
9585 ;
9586 const error = new SyntaxError(String(msg));
9587 error.code = code;
9588 error.loc = loc;
9589 return error;
9590}
9591const errorMessages = {
9592 // parse errors
9593 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
9594 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
9595 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
9596 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
9597 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
9598 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
9599 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
9600 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
9601 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
9602 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
9603 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
9604 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
9605 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
9606 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
9607 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
9608 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
9609 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
9610 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
9611 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
9612 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
9613 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
9614 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
9615 // Vue-specific parse errors
9616 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
9617 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
9618 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
9619 [26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
9620 'Note that dynamic directive argument cannot contain spaces.',
9621 // transform errors
9622 [27 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
9623 [28 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
9624 [29 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if.`,
9625 [30 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
9626 [31 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
9627 [32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
9628 [33 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
9629 [34 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
9630 [35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
9631 [36 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
9632 `When there are multiple named slots, all slots should use <template> ` +
9633 `syntax to avoid scope ambiguity.`,
9634 [37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
9635 [38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
9636 `default slot. These children will be ignored.`,
9637 [39 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
9638 [40 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
9639 [41 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
9640 [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.`,
9641 [43 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
9642 [44 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
9643 // generic errors
9644 [45 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
9645 [46 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
9646 [47 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
9647 [48 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`
9648};
9649
9650const FRAGMENT = Symbol(`Fragment` );
9651const TELEPORT = Symbol(`Teleport` );
9652const SUSPENSE = Symbol(`Suspense` );
9653const KEEP_ALIVE = Symbol(`KeepAlive` );
9654const BASE_TRANSITION = Symbol(`BaseTransition` );
9655const OPEN_BLOCK = Symbol(`openBlock` );
9656const CREATE_BLOCK = Symbol(`createBlock` );
9657const CREATE_VNODE = Symbol(`createVNode` );
9658const CREATE_COMMENT = Symbol(`createCommentVNode` );
9659const CREATE_TEXT = Symbol(`createTextVNode` );
9660const CREATE_STATIC = Symbol(`createStaticVNode` );
9661const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
9662const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
9663const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
9664const WITH_DIRECTIVES = Symbol(`withDirectives` );
9665const RENDER_LIST = Symbol(`renderList` );
9666const RENDER_SLOT = Symbol(`renderSlot` );
9667const CREATE_SLOTS = Symbol(`createSlots` );
9668const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
9669const MERGE_PROPS = Symbol(`mergeProps` );
9670const TO_HANDLERS = Symbol(`toHandlers` );
9671const CAMELIZE = Symbol(`camelize` );
9672const CAPITALIZE = Symbol(`capitalize` );
9673const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
9674const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
9675const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
9676const POP_SCOPE_ID = Symbol(`popScopeId` );
9677const WITH_SCOPE_ID = Symbol(`withScopeId` );
9678const WITH_CTX = Symbol(`withCtx` );
9679const UNREF = Symbol(`unref` );
9680const IS_REF = Symbol(`isRef` );
9681// Name mapping for runtime helpers that need to be imported from 'vue' in
9682// generated code. Make sure these are correctly exported in the runtime!
9683// Using `any` here because TS doesn't allow symbols as index type.
9684const helperNameMap = {
9685 [FRAGMENT]: `Fragment`,
9686 [TELEPORT]: `Teleport`,
9687 [SUSPENSE]: `Suspense`,
9688 [KEEP_ALIVE]: `KeepAlive`,
9689 [BASE_TRANSITION]: `BaseTransition`,
9690 [OPEN_BLOCK]: `openBlock`,
9691 [CREATE_BLOCK]: `createBlock`,
9692 [CREATE_VNODE]: `createVNode`,
9693 [CREATE_COMMENT]: `createCommentVNode`,
9694 [CREATE_TEXT]: `createTextVNode`,
9695 [CREATE_STATIC]: `createStaticVNode`,
9696 [RESOLVE_COMPONENT]: `resolveComponent`,
9697 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
9698 [RESOLVE_DIRECTIVE]: `resolveDirective`,
9699 [WITH_DIRECTIVES]: `withDirectives`,
9700 [RENDER_LIST]: `renderList`,
9701 [RENDER_SLOT]: `renderSlot`,
9702 [CREATE_SLOTS]: `createSlots`,
9703 [TO_DISPLAY_STRING]: `toDisplayString`,
9704 [MERGE_PROPS]: `mergeProps`,
9705 [TO_HANDLERS]: `toHandlers`,
9706 [CAMELIZE]: `camelize`,
9707 [CAPITALIZE]: `capitalize`,
9708 [TO_HANDLER_KEY]: `toHandlerKey`,
9709 [SET_BLOCK_TRACKING]: `setBlockTracking`,
9710 [PUSH_SCOPE_ID]: `pushScopeId`,
9711 [POP_SCOPE_ID]: `popScopeId`,
9712 [WITH_SCOPE_ID]: `withScopeId`,
9713 [WITH_CTX]: `withCtx`,
9714 [UNREF]: `unref`,
9715 [IS_REF]: `isRef`
9716};
9717function registerRuntimeHelpers(helpers) {
9718 Object.getOwnPropertySymbols(helpers).forEach(s => {
9719 helperNameMap[s] = helpers[s];
9720 });
9721}
9722
9723// AST Utilities ---------------------------------------------------------------
9724// Some expressions, e.g. sequence and conditional expressions, are never
9725// associated with template nodes, so their source locations are just a stub.
9726// Container types like CompoundExpression also don't need a real location.
9727const locStub = {
9728 source: '',
9729 start: { line: 1, column: 1, offset: 0 },
9730 end: { line: 1, column: 1, offset: 0 }
9731};
9732function createRoot(children, loc = locStub) {
9733 return {
9734 type: 0 /* ROOT */,
9735 children,
9736 helpers: [],
9737 components: [],
9738 directives: [],
9739 hoists: [],
9740 imports: [],
9741 cached: 0,
9742 temps: 0,
9743 codegenNode: undefined,
9744 loc
9745 };
9746}
9747function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, loc = locStub) {
9748 if (context) {
9749 if (isBlock) {
9750 context.helper(OPEN_BLOCK);
9751 context.helper(CREATE_BLOCK);
9752 }
9753 else {
9754 context.helper(CREATE_VNODE);
9755 }
9756 if (directives) {
9757 context.helper(WITH_DIRECTIVES);
9758 }
9759 }
9760 return {
9761 type: 13 /* VNODE_CALL */,
9762 tag,
9763 props,
9764 children,
9765 patchFlag,
9766 dynamicProps,
9767 directives,
9768 isBlock,
9769 disableTracking,
9770 loc
9771 };
9772}
9773function createArrayExpression(elements, loc = locStub) {
9774 return {
9775 type: 17 /* JS_ARRAY_EXPRESSION */,
9776 loc,
9777 elements
9778 };
9779}
9780function createObjectExpression(properties, loc = locStub) {
9781 return {
9782 type: 15 /* JS_OBJECT_EXPRESSION */,
9783 loc,
9784 properties
9785 };
9786}
9787function createObjectProperty(key, value) {
9788 return {
9789 type: 16 /* JS_PROPERTY */,
9790 loc: locStub,
9791 key: isString(key) ? createSimpleExpression(key, true) : key,
9792 value
9793 };
9794}
9795function createSimpleExpression(content, isStatic, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
9796 return {
9797 type: 4 /* SIMPLE_EXPRESSION */,
9798 loc,
9799 content,
9800 isStatic,
9801 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
9802 };
9803}
9804function createCompoundExpression(children, loc = locStub) {
9805 return {
9806 type: 8 /* COMPOUND_EXPRESSION */,
9807 loc,
9808 children
9809 };
9810}
9811function createCallExpression(callee, args = [], loc = locStub) {
9812 return {
9813 type: 14 /* JS_CALL_EXPRESSION */,
9814 loc,
9815 callee,
9816 arguments: args
9817 };
9818}
9819function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
9820 return {
9821 type: 18 /* JS_FUNCTION_EXPRESSION */,
9822 params,
9823 returns,
9824 newline,
9825 isSlot,
9826 loc
9827 };
9828}
9829function createConditionalExpression(test, consequent, alternate, newline = true) {
9830 return {
9831 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
9832 test,
9833 consequent,
9834 alternate,
9835 newline,
9836 loc: locStub
9837 };
9838}
9839function createCacheExpression(index, value, isVNode = false) {
9840 return {
9841 type: 20 /* JS_CACHE_EXPRESSION */,
9842 index,
9843 value,
9844 isVNode,
9845 loc: locStub
9846 };
9847}
9848
9849const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
9850const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
9851function isCoreComponent(tag) {
9852 if (isBuiltInType(tag, 'Teleport')) {
9853 return TELEPORT;
9854 }
9855 else if (isBuiltInType(tag, 'Suspense')) {
9856 return SUSPENSE;
9857 }
9858 else if (isBuiltInType(tag, 'KeepAlive')) {
9859 return KEEP_ALIVE;
9860 }
9861 else if (isBuiltInType(tag, 'BaseTransition')) {
9862 return BASE_TRANSITION;
9863 }
9864}
9865const nonIdentifierRE = /^\d|[^\$\w]/;
9866const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
9867const memberExpRE = /^[A-Za-z_$][\w$]*(?:\s*\.\s*[A-Za-z_$][\w$]*|\[[^\]]+\])*$/;
9868const isMemberExpression = (path) => {
9869 if (!path)
9870 return false;
9871 return memberExpRE.test(path.trim());
9872};
9873function getInnerRange(loc, offset, length) {
9874 const source = loc.source.substr(offset, length);
9875 const newLoc = {
9876 source,
9877 start: advancePositionWithClone(loc.start, loc.source, offset),
9878 end: loc.end
9879 };
9880 if (length != null) {
9881 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
9882 }
9883 return newLoc;
9884}
9885function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
9886 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
9887}
9888// advance by mutation without cloning (for performance reasons), since this
9889// gets called a lot in the parser
9890function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
9891 let linesCount = 0;
9892 let lastNewLinePos = -1;
9893 for (let i = 0; i < numberOfCharacters; i++) {
9894 if (source.charCodeAt(i) === 10 /* newline char code */) {
9895 linesCount++;
9896 lastNewLinePos = i;
9897 }
9898 }
9899 pos.offset += numberOfCharacters;
9900 pos.line += linesCount;
9901 pos.column =
9902 lastNewLinePos === -1
9903 ? pos.column + numberOfCharacters
9904 : numberOfCharacters - lastNewLinePos;
9905 return pos;
9906}
9907function assert(condition, msg) {
9908 /* istanbul ignore if */
9909 if (!condition) {
9910 throw new Error(msg || `unexpected compiler condition`);
9911 }
9912}
9913function findDir(node, name, allowEmpty = false) {
9914 for (let i = 0; i < node.props.length; i++) {
9915 const p = node.props[i];
9916 if (p.type === 7 /* DIRECTIVE */ &&
9917 (allowEmpty || p.exp) &&
9918 (isString(name) ? p.name === name : name.test(p.name))) {
9919 return p;
9920 }
9921 }
9922}
9923function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
9924 for (let i = 0; i < node.props.length; i++) {
9925 const p = node.props[i];
9926 if (p.type === 6 /* ATTRIBUTE */) {
9927 if (dynamicOnly)
9928 continue;
9929 if (p.name === name && (p.value || allowEmpty)) {
9930 return p;
9931 }
9932 }
9933 else if (p.name === 'bind' &&
9934 (p.exp || allowEmpty) &&
9935 isBindKey(p.arg, name)) {
9936 return p;
9937 }
9938 }
9939}
9940function isBindKey(arg, name) {
9941 return !!(arg && isStaticExp(arg) && arg.content === name);
9942}
9943function hasDynamicKeyVBind(node) {
9944 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
9945 p.name === 'bind' &&
9946 (!p.arg || // v-bind="obj"
9947 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
9948 !p.arg.isStatic) // v-bind:[foo]
9949 );
9950}
9951function isText(node) {
9952 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
9953}
9954function isVSlot(p) {
9955 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
9956}
9957function isTemplateNode(node) {
9958 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
9959}
9960function isSlotOutlet(node) {
9961 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
9962}
9963function injectProp(node, prop, context) {
9964 let propsWithInjection;
9965 const props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
9966 if (props == null || isString(props)) {
9967 propsWithInjection = createObjectExpression([prop]);
9968 }
9969 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
9970 // merged props... add ours
9971 // only inject key to object literal if it's the first argument so that
9972 // if doesn't override user provided keys
9973 const first = props.arguments[0];
9974 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
9975 first.properties.unshift(prop);
9976 }
9977 else {
9978 if (props.callee === TO_HANDLERS) {
9979 // #2366
9980 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
9981 createObjectExpression([prop]),
9982 props
9983 ]);
9984 }
9985 else {
9986 props.arguments.unshift(createObjectExpression([prop]));
9987 }
9988 }
9989 !propsWithInjection && (propsWithInjection = props);
9990 }
9991 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
9992 let alreadyExists = false;
9993 // check existing key to avoid overriding user provided keys
9994 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
9995 const propKeyName = prop.key.content;
9996 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
9997 p.key.content === propKeyName);
9998 }
9999 if (!alreadyExists) {
10000 props.properties.unshift(prop);
10001 }
10002 propsWithInjection = props;
10003 }
10004 else {
10005 // single v-bind with expression, return a merged replacement
10006 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
10007 createObjectExpression([prop]),
10008 props
10009 ]);
10010 }
10011 if (node.type === 13 /* VNODE_CALL */) {
10012 node.props = propsWithInjection;
10013 }
10014 else {
10015 node.arguments[2] = propsWithInjection;
10016 }
10017}
10018function toValidAssetId(name, type) {
10019 return `_${type}_${name.replace(/[^\w]/g, '_')}`;
10020}
10021
10022// The default decoder only provides escapes for characters reserved as part of
10023// the template syntax, and is only used if the custom renderer did not provide
10024// a platform-specific decoder.
10025const decodeRE = /&(gt|lt|amp|apos|quot);/g;
10026const decodeMap = {
10027 gt: '>',
10028 lt: '<',
10029 amp: '&',
10030 apos: "'",
10031 quot: '"'
10032};
10033const defaultParserOptions = {
10034 delimiters: [`{{`, `}}`],
10035 getNamespace: () => 0 /* HTML */,
10036 getTextMode: () => 0 /* DATA */,
10037 isVoidTag: NO,
10038 isPreTag: NO,
10039 isCustomElement: NO,
10040 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
10041 onError: defaultOnError,
10042 comments: false
10043};
10044function baseParse(content, options = {}) {
10045 const context = createParserContext(content, options);
10046 const start = getCursor(context);
10047 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
10048}
10049function createParserContext(content, rawOptions) {
10050 const options = extend({}, defaultParserOptions);
10051 for (const key in rawOptions) {
10052 // @ts-ignore
10053 options[key] = rawOptions[key] || defaultParserOptions[key];
10054 }
10055 return {
10056 options,
10057 column: 1,
10058 line: 1,
10059 offset: 0,
10060 originalSource: content,
10061 source: content,
10062 inPre: false,
10063 inVPre: false
10064 };
10065}
10066function parseChildren(context, mode, ancestors) {
10067 const parent = last(ancestors);
10068 const ns = parent ? parent.ns : 0 /* HTML */;
10069 const nodes = [];
10070 while (!isEnd(context, mode, ancestors)) {
10071 const s = context.source;
10072 let node = undefined;
10073 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
10074 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
10075 // '{{'
10076 node = parseInterpolation(context, mode);
10077 }
10078 else if (mode === 0 /* DATA */ && s[0] === '<') {
10079 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
10080 if (s.length === 1) {
10081 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
10082 }
10083 else if (s[1] === '!') {
10084 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
10085 if (startsWith(s, '<!--')) {
10086 node = parseComment(context);
10087 }
10088 else if (startsWith(s, '<!DOCTYPE')) {
10089 // Ignore DOCTYPE by a limitation.
10090 node = parseBogusComment(context);
10091 }
10092 else if (startsWith(s, '<![CDATA[')) {
10093 if (ns !== 0 /* HTML */) {
10094 node = parseCDATA(context, ancestors);
10095 }
10096 else {
10097 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
10098 node = parseBogusComment(context);
10099 }
10100 }
10101 else {
10102 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
10103 node = parseBogusComment(context);
10104 }
10105 }
10106 else if (s[1] === '/') {
10107 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
10108 if (s.length === 2) {
10109 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
10110 }
10111 else if (s[2] === '>') {
10112 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
10113 advanceBy(context, 3);
10114 continue;
10115 }
10116 else if (/[a-z]/i.test(s[2])) {
10117 emitError(context, 23 /* X_INVALID_END_TAG */);
10118 parseTag(context, 1 /* End */, parent);
10119 continue;
10120 }
10121 else {
10122 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
10123 node = parseBogusComment(context);
10124 }
10125 }
10126 else if (/[a-z]/i.test(s[1])) {
10127 node = parseElement(context, ancestors);
10128 }
10129 else if (s[1] === '?') {
10130 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
10131 node = parseBogusComment(context);
10132 }
10133 else {
10134 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
10135 }
10136 }
10137 }
10138 if (!node) {
10139 node = parseText(context, mode);
10140 }
10141 if (isArray(node)) {
10142 for (let i = 0; i < node.length; i++) {
10143 pushNode(nodes, node[i]);
10144 }
10145 }
10146 else {
10147 pushNode(nodes, node);
10148 }
10149 }
10150 // Whitespace management for more efficient output
10151 // (same as v2 whitespace: 'condense')
10152 let removedWhitespace = false;
10153 if (mode !== 2 /* RAWTEXT */) {
10154 for (let i = 0; i < nodes.length; i++) {
10155 const node = nodes[i];
10156 if (!context.inPre && node.type === 2 /* TEXT */) {
10157 if (!/[^\t\r\n\f ]/.test(node.content)) {
10158 const prev = nodes[i - 1];
10159 const next = nodes[i + 1];
10160 // If:
10161 // - the whitespace is the first or last node, or:
10162 // - the whitespace is adjacent to a comment, or:
10163 // - the whitespace is between two elements AND contains newline
10164 // Then the whitespace is ignored.
10165 if (!prev ||
10166 !next ||
10167 prev.type === 3 /* COMMENT */ ||
10168 next.type === 3 /* COMMENT */ ||
10169 (prev.type === 1 /* ELEMENT */ &&
10170 next.type === 1 /* ELEMENT */ &&
10171 /[\r\n]/.test(node.content))) {
10172 removedWhitespace = true;
10173 nodes[i] = null;
10174 }
10175 else {
10176 // Otherwise, condensed consecutive whitespace inside the text
10177 // down to a single space
10178 node.content = ' ';
10179 }
10180 }
10181 else {
10182 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
10183 }
10184 }
10185 }
10186 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
10187 // remove leading newline per html spec
10188 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
10189 const first = nodes[0];
10190 if (first && first.type === 2 /* TEXT */) {
10191 first.content = first.content.replace(/^\r?\n/, '');
10192 }
10193 }
10194 }
10195 return removedWhitespace ? nodes.filter(Boolean) : nodes;
10196}
10197function pushNode(nodes, node) {
10198 if (node.type === 2 /* TEXT */) {
10199 const prev = last(nodes);
10200 // Merge if both this and the previous node are text and those are
10201 // consecutive. This happens for cases like "a < b".
10202 if (prev &&
10203 prev.type === 2 /* TEXT */ &&
10204 prev.loc.end.offset === node.loc.start.offset) {
10205 prev.content += node.content;
10206 prev.loc.end = node.loc.end;
10207 prev.loc.source += node.loc.source;
10208 return;
10209 }
10210 }
10211 nodes.push(node);
10212}
10213function parseCDATA(context, ancestors) {
10214 advanceBy(context, 9);
10215 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
10216 if (context.source.length === 0) {
10217 emitError(context, 6 /* EOF_IN_CDATA */);
10218 }
10219 else {
10220 advanceBy(context, 3);
10221 }
10222 return nodes;
10223}
10224function parseComment(context) {
10225 const start = getCursor(context);
10226 let content;
10227 // Regular comment.
10228 const match = /--(\!)?>/.exec(context.source);
10229 if (!match) {
10230 content = context.source.slice(4);
10231 advanceBy(context, context.source.length);
10232 emitError(context, 7 /* EOF_IN_COMMENT */);
10233 }
10234 else {
10235 if (match.index <= 3) {
10236 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
10237 }
10238 if (match[1]) {
10239 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
10240 }
10241 content = context.source.slice(4, match.index);
10242 // Advancing with reporting nested comments.
10243 const s = context.source.slice(0, match.index);
10244 let prevIndex = 1, nestedIndex = 0;
10245 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
10246 advanceBy(context, nestedIndex - prevIndex + 1);
10247 if (nestedIndex + 4 < s.length) {
10248 emitError(context, 16 /* NESTED_COMMENT */);
10249 }
10250 prevIndex = nestedIndex + 1;
10251 }
10252 advanceBy(context, match.index + match[0].length - prevIndex + 1);
10253 }
10254 return {
10255 type: 3 /* COMMENT */,
10256 content,
10257 loc: getSelection(context, start)
10258 };
10259}
10260function parseBogusComment(context) {
10261 const start = getCursor(context);
10262 const contentStart = context.source[1] === '?' ? 1 : 2;
10263 let content;
10264 const closeIndex = context.source.indexOf('>');
10265 if (closeIndex === -1) {
10266 content = context.source.slice(contentStart);
10267 advanceBy(context, context.source.length);
10268 }
10269 else {
10270 content = context.source.slice(contentStart, closeIndex);
10271 advanceBy(context, closeIndex + 1);
10272 }
10273 return {
10274 type: 3 /* COMMENT */,
10275 content,
10276 loc: getSelection(context, start)
10277 };
10278}
10279function parseElement(context, ancestors) {
10280 // Start tag.
10281 const wasInPre = context.inPre;
10282 const wasInVPre = context.inVPre;
10283 const parent = last(ancestors);
10284 const element = parseTag(context, 0 /* Start */, parent);
10285 const isPreBoundary = context.inPre && !wasInPre;
10286 const isVPreBoundary = context.inVPre && !wasInVPre;
10287 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
10288 return element;
10289 }
10290 // Children.
10291 ancestors.push(element);
10292 const mode = context.options.getTextMode(element, parent);
10293 const children = parseChildren(context, mode, ancestors);
10294 ancestors.pop();
10295 element.children = children;
10296 // End tag.
10297 if (startsWithEndTagOpen(context.source, element.tag)) {
10298 parseTag(context, 1 /* End */, parent);
10299 }
10300 else {
10301 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
10302 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
10303 const first = children[0];
10304 if (first && startsWith(first.loc.source, '<!--')) {
10305 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
10306 }
10307 }
10308 }
10309 element.loc = getSelection(context, element.loc.start);
10310 if (isPreBoundary) {
10311 context.inPre = false;
10312 }
10313 if (isVPreBoundary) {
10314 context.inVPre = false;
10315 }
10316 return element;
10317}
10318const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
10319/**
10320 * Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
10321 */
10322function parseTag(context, type, parent) {
10323 // Tag open.
10324 const start = getCursor(context);
10325 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
10326 const tag = match[1];
10327 const ns = context.options.getNamespace(tag, parent);
10328 advanceBy(context, match[0].length);
10329 advanceSpaces(context);
10330 // save current state in case we need to re-parse attributes with v-pre
10331 const cursor = getCursor(context);
10332 const currentSource = context.source;
10333 // Attributes.
10334 let props = parseAttributes(context, type);
10335 // check <pre> tag
10336 if (context.options.isPreTag(tag)) {
10337 context.inPre = true;
10338 }
10339 // check v-pre
10340 if (!context.inVPre &&
10341 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
10342 context.inVPre = true;
10343 // reset context
10344 extend(context, cursor);
10345 context.source = currentSource;
10346 // re-parse attrs and filter out v-pre itself
10347 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
10348 }
10349 // Tag close.
10350 let isSelfClosing = false;
10351 if (context.source.length === 0) {
10352 emitError(context, 9 /* EOF_IN_TAG */);
10353 }
10354 else {
10355 isSelfClosing = startsWith(context.source, '/>');
10356 if (type === 1 /* End */ && isSelfClosing) {
10357 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
10358 }
10359 advanceBy(context, isSelfClosing ? 2 : 1);
10360 }
10361 let tagType = 0 /* ELEMENT */;
10362 const options = context.options;
10363 if (!context.inVPre && !options.isCustomElement(tag)) {
10364 const hasVIs = props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'is');
10365 if (options.isNativeTag && !hasVIs) {
10366 if (!options.isNativeTag(tag))
10367 tagType = 1 /* COMPONENT */;
10368 }
10369 else if (hasVIs ||
10370 isCoreComponent(tag) ||
10371 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
10372 /^[A-Z]/.test(tag) ||
10373 tag === 'component') {
10374 tagType = 1 /* COMPONENT */;
10375 }
10376 if (tag === 'slot') {
10377 tagType = 2 /* SLOT */;
10378 }
10379 else if (tag === 'template' &&
10380 props.some(p => {
10381 return (p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name));
10382 })) {
10383 tagType = 3 /* TEMPLATE */;
10384 }
10385 }
10386 return {
10387 type: 1 /* ELEMENT */,
10388 ns,
10389 tag,
10390 tagType,
10391 props,
10392 isSelfClosing,
10393 children: [],
10394 loc: getSelection(context, start),
10395 codegenNode: undefined // to be created during transform phase
10396 };
10397}
10398function parseAttributes(context, type) {
10399 const props = [];
10400 const attributeNames = new Set();
10401 while (context.source.length > 0 &&
10402 !startsWith(context.source, '>') &&
10403 !startsWith(context.source, '/>')) {
10404 if (startsWith(context.source, '/')) {
10405 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
10406 advanceBy(context, 1);
10407 advanceSpaces(context);
10408 continue;
10409 }
10410 if (type === 1 /* End */) {
10411 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
10412 }
10413 const attr = parseAttribute(context, attributeNames);
10414 if (type === 0 /* Start */) {
10415 props.push(attr);
10416 }
10417 if (/^[^\t\r\n\f />]/.test(context.source)) {
10418 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
10419 }
10420 advanceSpaces(context);
10421 }
10422 return props;
10423}
10424function parseAttribute(context, nameSet) {
10425 // Name.
10426 const start = getCursor(context);
10427 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
10428 const name = match[0];
10429 if (nameSet.has(name)) {
10430 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
10431 }
10432 nameSet.add(name);
10433 if (name[0] === '=') {
10434 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
10435 }
10436 {
10437 const pattern = /["'<]/g;
10438 let m;
10439 while ((m = pattern.exec(name))) {
10440 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
10441 }
10442 }
10443 advanceBy(context, name.length);
10444 // Value
10445 let value = undefined;
10446 if (/^[\t\r\n\f ]*=/.test(context.source)) {
10447 advanceSpaces(context);
10448 advanceBy(context, 1);
10449 advanceSpaces(context);
10450 value = parseAttributeValue(context);
10451 if (!value) {
10452 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
10453 }
10454 }
10455 const loc = getSelection(context, start);
10456 if (!context.inVPre && /^(v-|:|@|#)/.test(name)) {
10457 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
10458 const dirName = match[1] ||
10459 (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot');
10460 let arg;
10461 if (match[2]) {
10462 const isSlot = dirName === 'slot';
10463 const startOffset = name.indexOf(match[2]);
10464 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
10465 let content = match[2];
10466 let isStatic = true;
10467 if (content.startsWith('[')) {
10468 isStatic = false;
10469 if (!content.endsWith(']')) {
10470 emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
10471 }
10472 content = content.substr(1, content.length - 2);
10473 }
10474 else if (isSlot) {
10475 // #1241 special case for v-slot: vuetify relies extensively on slot
10476 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
10477 // supports such usage so we are keeping it consistent with 2.x.
10478 content += match[3] || '';
10479 }
10480 arg = {
10481 type: 4 /* SIMPLE_EXPRESSION */,
10482 content,
10483 isStatic,
10484 constType: isStatic
10485 ? 3 /* CAN_STRINGIFY */
10486 : 0 /* NOT_CONSTANT */,
10487 loc
10488 };
10489 }
10490 if (value && value.isQuoted) {
10491 const valueLoc = value.loc;
10492 valueLoc.start.offset++;
10493 valueLoc.start.column++;
10494 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
10495 valueLoc.source = valueLoc.source.slice(1, -1);
10496 }
10497 return {
10498 type: 7 /* DIRECTIVE */,
10499 name: dirName,
10500 exp: value && {
10501 type: 4 /* SIMPLE_EXPRESSION */,
10502 content: value.content,
10503 isStatic: false,
10504 // Treat as non-constant by default. This can be potentially set to
10505 // other values by `transformExpression` to make it eligible for hoisting.
10506 constType: 0 /* NOT_CONSTANT */,
10507 loc: value.loc
10508 },
10509 arg,
10510 modifiers: match[3] ? match[3].substr(1).split('.') : [],
10511 loc
10512 };
10513 }
10514 return {
10515 type: 6 /* ATTRIBUTE */,
10516 name,
10517 value: value && {
10518 type: 2 /* TEXT */,
10519 content: value.content,
10520 loc: value.loc
10521 },
10522 loc
10523 };
10524}
10525function parseAttributeValue(context) {
10526 const start = getCursor(context);
10527 let content;
10528 const quote = context.source[0];
10529 const isQuoted = quote === `"` || quote === `'`;
10530 if (isQuoted) {
10531 // Quoted value.
10532 advanceBy(context, 1);
10533 const endIndex = context.source.indexOf(quote);
10534 if (endIndex === -1) {
10535 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
10536 }
10537 else {
10538 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
10539 advanceBy(context, 1);
10540 }
10541 }
10542 else {
10543 // Unquoted
10544 const match = /^[^\t\r\n\f >]+/.exec(context.source);
10545 if (!match) {
10546 return undefined;
10547 }
10548 const unexpectedChars = /["'<=`]/g;
10549 let m;
10550 while ((m = unexpectedChars.exec(match[0]))) {
10551 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
10552 }
10553 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
10554 }
10555 return { content, isQuoted, loc: getSelection(context, start) };
10556}
10557function parseInterpolation(context, mode) {
10558 const [open, close] = context.options.delimiters;
10559 const closeIndex = context.source.indexOf(close, open.length);
10560 if (closeIndex === -1) {
10561 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
10562 return undefined;
10563 }
10564 const start = getCursor(context);
10565 advanceBy(context, open.length);
10566 const innerStart = getCursor(context);
10567 const innerEnd = getCursor(context);
10568 const rawContentLength = closeIndex - open.length;
10569 const rawContent = context.source.slice(0, rawContentLength);
10570 const preTrimContent = parseTextData(context, rawContentLength, mode);
10571 const content = preTrimContent.trim();
10572 const startOffset = preTrimContent.indexOf(content);
10573 if (startOffset > 0) {
10574 advancePositionWithMutation(innerStart, rawContent, startOffset);
10575 }
10576 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
10577 advancePositionWithMutation(innerEnd, rawContent, endOffset);
10578 advanceBy(context, close.length);
10579 return {
10580 type: 5 /* INTERPOLATION */,
10581 content: {
10582 type: 4 /* SIMPLE_EXPRESSION */,
10583 isStatic: false,
10584 // Set `isConstant` to false by default and will decide in transformExpression
10585 constType: 0 /* NOT_CONSTANT */,
10586 content,
10587 loc: getSelection(context, innerStart, innerEnd)
10588 },
10589 loc: getSelection(context, start)
10590 };
10591}
10592function parseText(context, mode) {
10593 const endTokens = ['<', context.options.delimiters[0]];
10594 if (mode === 3 /* CDATA */) {
10595 endTokens.push(']]>');
10596 }
10597 let endIndex = context.source.length;
10598 for (let i = 0; i < endTokens.length; i++) {
10599 const index = context.source.indexOf(endTokens[i], 1);
10600 if (index !== -1 && endIndex > index) {
10601 endIndex = index;
10602 }
10603 }
10604 const start = getCursor(context);
10605 const content = parseTextData(context, endIndex, mode);
10606 return {
10607 type: 2 /* TEXT */,
10608 content,
10609 loc: getSelection(context, start)
10610 };
10611}
10612/**
10613 * Get text data with a given length from the current location.
10614 * This translates HTML entities in the text data.
10615 */
10616function parseTextData(context, length, mode) {
10617 const rawText = context.source.slice(0, length);
10618 advanceBy(context, length);
10619 if (mode === 2 /* RAWTEXT */ ||
10620 mode === 3 /* CDATA */ ||
10621 rawText.indexOf('&') === -1) {
10622 return rawText;
10623 }
10624 else {
10625 // DATA or RCDATA containing "&"". Entity decoding required.
10626 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
10627 }
10628}
10629function getCursor(context) {
10630 const { column, line, offset } = context;
10631 return { column, line, offset };
10632}
10633function getSelection(context, start, end) {
10634 end = end || getCursor(context);
10635 return {
10636 start,
10637 end,
10638 source: context.originalSource.slice(start.offset, end.offset)
10639 };
10640}
10641function last(xs) {
10642 return xs[xs.length - 1];
10643}
10644function startsWith(source, searchString) {
10645 return source.startsWith(searchString);
10646}
10647function advanceBy(context, numberOfCharacters) {
10648 const { source } = context;
10649 advancePositionWithMutation(context, source, numberOfCharacters);
10650 context.source = source.slice(numberOfCharacters);
10651}
10652function advanceSpaces(context) {
10653 const match = /^[\t\r\n\f ]+/.exec(context.source);
10654 if (match) {
10655 advanceBy(context, match[0].length);
10656 }
10657}
10658function getNewPosition(context, start, numberOfCharacters) {
10659 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
10660}
10661function emitError(context, code, offset, loc = getCursor(context)) {
10662 if (offset) {
10663 loc.offset += offset;
10664 loc.column += offset;
10665 }
10666 context.options.onError(createCompilerError(code, {
10667 start: loc,
10668 end: loc,
10669 source: ''
10670 }));
10671}
10672function isEnd(context, mode, ancestors) {
10673 const s = context.source;
10674 switch (mode) {
10675 case 0 /* DATA */:
10676 if (startsWith(s, '</')) {
10677 // TODO: probably bad performance
10678 for (let i = ancestors.length - 1; i >= 0; --i) {
10679 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
10680 return true;
10681 }
10682 }
10683 }
10684 break;
10685 case 1 /* RCDATA */:
10686 case 2 /* RAWTEXT */: {
10687 const parent = last(ancestors);
10688 if (parent && startsWithEndTagOpen(s, parent.tag)) {
10689 return true;
10690 }
10691 break;
10692 }
10693 case 3 /* CDATA */:
10694 if (startsWith(s, ']]>')) {
10695 return true;
10696 }
10697 break;
10698 }
10699 return !s;
10700}
10701function startsWithEndTagOpen(source, tag) {
10702 return (startsWith(source, '</') &&
10703 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
10704 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
10705}
10706
10707function hoistStatic(root, context) {
10708 walk(root, context,
10709 // Root node is unfortunately non-hoistable due to potential parent
10710 // fallthrough attributes.
10711 isSingleElementRoot(root, root.children[0]));
10712}
10713function isSingleElementRoot(root, child) {
10714 const { children } = root;
10715 return (children.length === 1 &&
10716 child.type === 1 /* ELEMENT */ &&
10717 !isSlotOutlet(child));
10718}
10719function walk(node, context, doNotHoistNode = false) {
10720 let hasHoistedNode = false;
10721 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
10722 // static bindings with expressions. These expressions are guaranteed to be
10723 // constant so they are still eligible for hoisting, but they are only
10724 // available at runtime and therefore cannot be evaluated ahead of time.
10725 // This is only a concern for pre-stringification (via transformHoist by
10726 // @vue/compiler-dom), but doing it here allows us to perform only one full
10727 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
10728 // stringficiation threshold is met.
10729 let canStringify = true;
10730 const { children } = node;
10731 for (let i = 0; i < children.length; i++) {
10732 const child = children[i];
10733 // only plain elements & text calls are eligible for hoisting.
10734 if (child.type === 1 /* ELEMENT */ &&
10735 child.tagType === 0 /* ELEMENT */) {
10736 const constantType = doNotHoistNode
10737 ? 0 /* NOT_CONSTANT */
10738 : getConstantType(child, context);
10739 if (constantType > 0 /* NOT_CONSTANT */) {
10740 if (constantType < 3 /* CAN_STRINGIFY */) {
10741 canStringify = false;
10742 }
10743 if (constantType >= 2 /* CAN_HOIST */) {
10744 child.codegenNode.patchFlag =
10745 -1 /* HOISTED */ + (` /* HOISTED */` );
10746 child.codegenNode = context.hoist(child.codegenNode);
10747 hasHoistedNode = true;
10748 continue;
10749 }
10750 }
10751 else {
10752 // node may contain dynamic children, but its props may be eligible for
10753 // hoisting.
10754 const codegenNode = child.codegenNode;
10755 if (codegenNode.type === 13 /* VNODE_CALL */) {
10756 const flag = getPatchFlag(codegenNode);
10757 if ((!flag ||
10758 flag === 512 /* NEED_PATCH */ ||
10759 flag === 1 /* TEXT */) &&
10760 getGeneratedPropsConstantType(child, context) >=
10761 2 /* CAN_HOIST */) {
10762 const props = getNodeProps(child);
10763 if (props) {
10764 codegenNode.props = context.hoist(props);
10765 }
10766 }
10767 }
10768 }
10769 }
10770 else if (child.type === 12 /* TEXT_CALL */) {
10771 const contentType = getConstantType(child.content, context);
10772 if (contentType > 0) {
10773 if (contentType < 3 /* CAN_STRINGIFY */) {
10774 canStringify = false;
10775 }
10776 if (contentType >= 2 /* CAN_HOIST */) {
10777 child.codegenNode = context.hoist(child.codegenNode);
10778 hasHoistedNode = true;
10779 }
10780 }
10781 }
10782 // walk further
10783 if (child.type === 1 /* ELEMENT */) {
10784 walk(child, context);
10785 }
10786 else if (child.type === 11 /* FOR */) {
10787 // Do not hoist v-for single child because it has to be a block
10788 walk(child, context, child.children.length === 1);
10789 }
10790 else if (child.type === 9 /* IF */) {
10791 for (let i = 0; i < child.branches.length; i++) {
10792 // Do not hoist v-if single child because it has to be a block
10793 walk(child.branches[i], context, child.branches[i].children.length === 1);
10794 }
10795 }
10796 }
10797 if (canStringify && hasHoistedNode && context.transformHoist) {
10798 context.transformHoist(children, context, node);
10799 }
10800}
10801function getConstantType(node, context) {
10802 const { constantCache } = context;
10803 switch (node.type) {
10804 case 1 /* ELEMENT */:
10805 if (node.tagType !== 0 /* ELEMENT */) {
10806 return 0 /* NOT_CONSTANT */;
10807 }
10808 const cached = constantCache.get(node);
10809 if (cached !== undefined) {
10810 return cached;
10811 }
10812 const codegenNode = node.codegenNode;
10813 if (codegenNode.type !== 13 /* VNODE_CALL */) {
10814 return 0 /* NOT_CONSTANT */;
10815 }
10816 const flag = getPatchFlag(codegenNode);
10817 if (!flag) {
10818 let returnType = 3 /* CAN_STRINGIFY */;
10819 // Element itself has no patch flag. However we still need to check:
10820 // 1. Even for a node with no patch flag, it is possible for it to contain
10821 // non-hoistable expressions that refers to scope variables, e.g. compiler
10822 // injected keys or cached event handlers. Therefore we need to always
10823 // check the codegenNode's props to be sure.
10824 const generatedPropsType = getGeneratedPropsConstantType(node, context);
10825 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
10826 constantCache.set(node, 0 /* NOT_CONSTANT */);
10827 return 0 /* NOT_CONSTANT */;
10828 }
10829 if (generatedPropsType < returnType) {
10830 returnType = generatedPropsType;
10831 }
10832 // 2. its children.
10833 for (let i = 0; i < node.children.length; i++) {
10834 const childType = getConstantType(node.children[i], context);
10835 if (childType === 0 /* NOT_CONSTANT */) {
10836 constantCache.set(node, 0 /* NOT_CONSTANT */);
10837 return 0 /* NOT_CONSTANT */;
10838 }
10839 if (childType < returnType) {
10840 returnType = childType;
10841 }
10842 }
10843 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
10844 // type, check if any of the props can cause the type to be lowered
10845 // we can skip can_patch because it's guaranteed by the absence of a
10846 // patchFlag.
10847 if (returnType > 1 /* CAN_SKIP_PATCH */) {
10848 for (let i = 0; i < node.props.length; i++) {
10849 const p = node.props[i];
10850 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
10851 const expType = getConstantType(p.exp, context);
10852 if (expType === 0 /* NOT_CONSTANT */) {
10853 constantCache.set(node, 0 /* NOT_CONSTANT */);
10854 return 0 /* NOT_CONSTANT */;
10855 }
10856 if (expType < returnType) {
10857 returnType = expType;
10858 }
10859 }
10860 }
10861 }
10862 // only svg/foreignObject could be block here, however if they are
10863 // static then they don't need to be blocks since there will be no
10864 // nested updates.
10865 if (codegenNode.isBlock) {
10866 codegenNode.isBlock = false;
10867 context.helper(CREATE_VNODE);
10868 }
10869 constantCache.set(node, returnType);
10870 return returnType;
10871 }
10872 else {
10873 constantCache.set(node, 0 /* NOT_CONSTANT */);
10874 return 0 /* NOT_CONSTANT */;
10875 }
10876 case 2 /* TEXT */:
10877 case 3 /* COMMENT */:
10878 return 3 /* CAN_STRINGIFY */;
10879 case 9 /* IF */:
10880 case 11 /* FOR */:
10881 case 10 /* IF_BRANCH */:
10882 return 0 /* NOT_CONSTANT */;
10883 case 5 /* INTERPOLATION */:
10884 case 12 /* TEXT_CALL */:
10885 return getConstantType(node.content, context);
10886 case 4 /* SIMPLE_EXPRESSION */:
10887 return node.constType;
10888 case 8 /* COMPOUND_EXPRESSION */:
10889 let returnType = 3 /* CAN_STRINGIFY */;
10890 for (let i = 0; i < node.children.length; i++) {
10891 const child = node.children[i];
10892 if (isString(child) || isSymbol(child)) {
10893 continue;
10894 }
10895 const childType = getConstantType(child, context);
10896 if (childType === 0 /* NOT_CONSTANT */) {
10897 return 0 /* NOT_CONSTANT */;
10898 }
10899 else if (childType < returnType) {
10900 returnType = childType;
10901 }
10902 }
10903 return returnType;
10904 default:
10905 return 0 /* NOT_CONSTANT */;
10906 }
10907}
10908function getGeneratedPropsConstantType(node, context) {
10909 let returnType = 3 /* CAN_STRINGIFY */;
10910 const props = getNodeProps(node);
10911 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
10912 const { properties } = props;
10913 for (let i = 0; i < properties.length; i++) {
10914 const { key, value } = properties[i];
10915 const keyType = getConstantType(key, context);
10916 if (keyType === 0 /* NOT_CONSTANT */) {
10917 return keyType;
10918 }
10919 if (keyType < returnType) {
10920 returnType = keyType;
10921 }
10922 if (value.type !== 4 /* SIMPLE_EXPRESSION */) {
10923 return 0 /* NOT_CONSTANT */;
10924 }
10925 const valueType = getConstantType(value, context);
10926 if (valueType === 0 /* NOT_CONSTANT */) {
10927 return valueType;
10928 }
10929 if (valueType < returnType) {
10930 returnType = valueType;
10931 }
10932 }
10933 }
10934 return returnType;
10935}
10936function getNodeProps(node) {
10937 const codegenNode = node.codegenNode;
10938 if (codegenNode.type === 13 /* VNODE_CALL */) {
10939 return codegenNode.props;
10940 }
10941}
10942function getPatchFlag(node) {
10943 const flag = node.patchFlag;
10944 return flag ? parseInt(flag, 10) : undefined;
10945}
10946
10947function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, ssr = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError }) {
10948 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
10949 const context = {
10950 // options
10951 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
10952 prefixIdentifiers,
10953 hoistStatic,
10954 cacheHandlers,
10955 nodeTransforms,
10956 directiveTransforms,
10957 transformHoist,
10958 isBuiltInComponent,
10959 isCustomElement,
10960 expressionPlugins,
10961 scopeId,
10962 ssr,
10963 ssrCssVars,
10964 bindingMetadata,
10965 inline,
10966 isTS,
10967 onError,
10968 // state
10969 root,
10970 helpers: new Set(),
10971 components: new Set(),
10972 directives: new Set(),
10973 hoists: [],
10974 imports: [],
10975 constantCache: new Map(),
10976 temps: 0,
10977 cached: 0,
10978 identifiers: Object.create(null),
10979 scopes: {
10980 vFor: 0,
10981 vSlot: 0,
10982 vPre: 0,
10983 vOnce: 0
10984 },
10985 parent: null,
10986 currentNode: root,
10987 childIndex: 0,
10988 // methods
10989 helper(name) {
10990 context.helpers.add(name);
10991 return name;
10992 },
10993 helperString(name) {
10994 return `_${helperNameMap[context.helper(name)]}`;
10995 },
10996 replaceNode(node) {
10997 /* istanbul ignore if */
10998 {
10999 if (!context.currentNode) {
11000 throw new Error(`Node being replaced is already removed.`);
11001 }
11002 if (!context.parent) {
11003 throw new Error(`Cannot replace root node.`);
11004 }
11005 }
11006 context.parent.children[context.childIndex] = context.currentNode = node;
11007 },
11008 removeNode(node) {
11009 if (!context.parent) {
11010 throw new Error(`Cannot remove root node.`);
11011 }
11012 const list = context.parent.children;
11013 const removalIndex = node
11014 ? list.indexOf(node)
11015 : context.currentNode
11016 ? context.childIndex
11017 : -1;
11018 /* istanbul ignore if */
11019 if (removalIndex < 0) {
11020 throw new Error(`node being removed is not a child of current parent`);
11021 }
11022 if (!node || node === context.currentNode) {
11023 // current node removed
11024 context.currentNode = null;
11025 context.onNodeRemoved();
11026 }
11027 else {
11028 // sibling node removed
11029 if (context.childIndex > removalIndex) {
11030 context.childIndex--;
11031 context.onNodeRemoved();
11032 }
11033 }
11034 context.parent.children.splice(removalIndex, 1);
11035 },
11036 onNodeRemoved: () => { },
11037 addIdentifiers(exp) {
11038 },
11039 removeIdentifiers(exp) {
11040 },
11041 hoist(exp) {
11042 context.hoists.push(exp);
11043 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
11044 identifier.hoisted = exp;
11045 return identifier;
11046 },
11047 cache(exp, isVNode = false) {
11048 return createCacheExpression(++context.cached, exp, isVNode);
11049 }
11050 };
11051 return context;
11052}
11053function transform(root, options) {
11054 const context = createTransformContext(root, options);
11055 traverseNode(root, context);
11056 if (options.hoistStatic) {
11057 hoistStatic(root, context);
11058 }
11059 if (!options.ssr) {
11060 createRootCodegen(root, context);
11061 }
11062 // finalize meta information
11063 root.helpers = [...context.helpers];
11064 root.components = [...context.components];
11065 root.directives = [...context.directives];
11066 root.imports = context.imports;
11067 root.hoists = context.hoists;
11068 root.temps = context.temps;
11069 root.cached = context.cached;
11070}
11071function createRootCodegen(root, context) {
11072 const { helper } = context;
11073 const { children } = root;
11074 if (children.length === 1) {
11075 const child = children[0];
11076 // if the single child is an element, turn it into a block.
11077 if (isSingleElementRoot(root, child) && child.codegenNode) {
11078 // single element root is never hoisted so codegenNode will never be
11079 // SimpleExpressionNode
11080 const codegenNode = child.codegenNode;
11081 if (codegenNode.type === 13 /* VNODE_CALL */) {
11082 codegenNode.isBlock = true;
11083 helper(OPEN_BLOCK);
11084 helper(CREATE_BLOCK);
11085 }
11086 root.codegenNode = codegenNode;
11087 }
11088 else {
11089 // - single <slot/>, IfNode, ForNode: already blocks.
11090 // - single text node: always patched.
11091 // root codegen falls through via genNode()
11092 root.codegenNode = child;
11093 }
11094 }
11095 else if (children.length > 1) {
11096 // root has multiple nodes - return a fragment block.
11097 let patchFlag = 64 /* STABLE_FRAGMENT */;
11098 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
11099 // check if the fragment actually contains a single valid child with
11100 // the rest being comments
11101 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
11102 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
11103 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
11104 }
11105 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true);
11106 }
11107 else ;
11108}
11109function traverseChildren(parent, context) {
11110 let i = 0;
11111 const nodeRemoved = () => {
11112 i--;
11113 };
11114 for (; i < parent.children.length; i++) {
11115 const child = parent.children[i];
11116 if (isString(child))
11117 continue;
11118 context.parent = parent;
11119 context.childIndex = i;
11120 context.onNodeRemoved = nodeRemoved;
11121 traverseNode(child, context);
11122 }
11123}
11124function traverseNode(node, context) {
11125 context.currentNode = node;
11126 // apply transform plugins
11127 const { nodeTransforms } = context;
11128 const exitFns = [];
11129 for (let i = 0; i < nodeTransforms.length; i++) {
11130 const onExit = nodeTransforms[i](node, context);
11131 if (onExit) {
11132 if (isArray(onExit)) {
11133 exitFns.push(...onExit);
11134 }
11135 else {
11136 exitFns.push(onExit);
11137 }
11138 }
11139 if (!context.currentNode) {
11140 // node was removed
11141 return;
11142 }
11143 else {
11144 // node may have been replaced
11145 node = context.currentNode;
11146 }
11147 }
11148 switch (node.type) {
11149 case 3 /* COMMENT */:
11150 if (!context.ssr) {
11151 // inject import for the Comment symbol, which is needed for creating
11152 // comment nodes with `createVNode`
11153 context.helper(CREATE_COMMENT);
11154 }
11155 break;
11156 case 5 /* INTERPOLATION */:
11157 // no need to traverse, but we need to inject toString helper
11158 if (!context.ssr) {
11159 context.helper(TO_DISPLAY_STRING);
11160 }
11161 break;
11162 // for container types, further traverse downwards
11163 case 9 /* IF */:
11164 for (let i = 0; i < node.branches.length; i++) {
11165 traverseNode(node.branches[i], context);
11166 }
11167 break;
11168 case 10 /* IF_BRANCH */:
11169 case 11 /* FOR */:
11170 case 1 /* ELEMENT */:
11171 case 0 /* ROOT */:
11172 traverseChildren(node, context);
11173 break;
11174 }
11175 // exit transforms
11176 context.currentNode = node;
11177 let i = exitFns.length;
11178 while (i--) {
11179 exitFns[i]();
11180 }
11181}
11182function createStructuralDirectiveTransform(name, fn) {
11183 const matches = isString(name)
11184 ? (n) => n === name
11185 : (n) => name.test(n);
11186 return (node, context) => {
11187 if (node.type === 1 /* ELEMENT */) {
11188 const { props } = node;
11189 // structural directive transforms are not concerned with slots
11190 // as they are handled separately in vSlot.ts
11191 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
11192 return;
11193 }
11194 const exitFns = [];
11195 for (let i = 0; i < props.length; i++) {
11196 const prop = props[i];
11197 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
11198 // structural directives are removed to avoid infinite recursion
11199 // also we remove them *before* applying so that it can further
11200 // traverse itself in case it moves the node around
11201 props.splice(i, 1);
11202 i--;
11203 const onExit = fn(node, prop, context);
11204 if (onExit)
11205 exitFns.push(onExit);
11206 }
11207 }
11208 return exitFns;
11209 }
11210 };
11211}
11212
11213const PURE_ANNOTATION = `/*#__PURE__*/`;
11214function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false }) {
11215 const context = {
11216 mode,
11217 prefixIdentifiers,
11218 sourceMap,
11219 filename,
11220 scopeId,
11221 optimizeImports,
11222 runtimeGlobalName,
11223 runtimeModuleName,
11224 ssr,
11225 source: ast.loc.source,
11226 code: ``,
11227 column: 1,
11228 line: 1,
11229 offset: 0,
11230 indentLevel: 0,
11231 pure: false,
11232 map: undefined,
11233 helper(key) {
11234 return `_${helperNameMap[key]}`;
11235 },
11236 push(code, node) {
11237 context.code += code;
11238 },
11239 indent() {
11240 newline(++context.indentLevel);
11241 },
11242 deindent(withoutNewLine = false) {
11243 if (withoutNewLine) {
11244 --context.indentLevel;
11245 }
11246 else {
11247 newline(--context.indentLevel);
11248 }
11249 },
11250 newline() {
11251 newline(context.indentLevel);
11252 }
11253 };
11254 function newline(n) {
11255 context.push('\n' + ` `.repeat(n));
11256 }
11257 return context;
11258}
11259function generate(ast, options = {}) {
11260 const context = createCodegenContext(ast, options);
11261 if (options.onContextCreated)
11262 options.onContextCreated(context);
11263 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
11264 const hasHelpers = ast.helpers.length > 0;
11265 const useWithBlock = !prefixIdentifiers && mode !== 'module';
11266 // preambles
11267 // in setup() inline mode, the preamble is generated in a sub context
11268 // and returned separately.
11269 const preambleContext = context;
11270 {
11271 genFunctionPreamble(ast, preambleContext);
11272 }
11273 // enter render function
11274 const functionName = ssr ? `ssrRender` : `render`;
11275 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
11276 const signature = args.join(', ');
11277 {
11278 push(`function ${functionName}(${signature}) {`);
11279 }
11280 indent();
11281 if (useWithBlock) {
11282 push(`with (_ctx) {`);
11283 indent();
11284 // function mode const declarations should be inside with block
11285 // also they should be renamed to avoid collision with user properties
11286 if (hasHelpers) {
11287 push(`const { ${ast.helpers
11288 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
11289 .join(', ')} } = _Vue`);
11290 push(`\n`);
11291 newline();
11292 }
11293 }
11294 // generate asset resolution statements
11295 if (ast.components.length) {
11296 genAssets(ast.components, 'component', context);
11297 if (ast.directives.length || ast.temps > 0) {
11298 newline();
11299 }
11300 }
11301 if (ast.directives.length) {
11302 genAssets(ast.directives, 'directive', context);
11303 if (ast.temps > 0) {
11304 newline();
11305 }
11306 }
11307 if (ast.temps > 0) {
11308 push(`let `);
11309 for (let i = 0; i < ast.temps; i++) {
11310 push(`${i > 0 ? `, ` : ``}_temp${i}`);
11311 }
11312 }
11313 if (ast.components.length || ast.directives.length || ast.temps) {
11314 push(`\n`);
11315 newline();
11316 }
11317 // generate the VNode tree expression
11318 if (!ssr) {
11319 push(`return `);
11320 }
11321 if (ast.codegenNode) {
11322 genNode(ast.codegenNode, context);
11323 }
11324 else {
11325 push(`null`);
11326 }
11327 if (useWithBlock) {
11328 deindent();
11329 push(`}`);
11330 }
11331 deindent();
11332 push(`}`);
11333 return {
11334 ast,
11335 code: context.code,
11336 preamble: ``,
11337 // SourceMapGenerator does have toJSON() method but it's not in the types
11338 map: context.map ? context.map.toJSON() : undefined
11339 };
11340}
11341function genFunctionPreamble(ast, context) {
11342 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;
11343 const VueBinding = runtimeGlobalName;
11344 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
11345 // Generate const declaration for helpers
11346 // In prefix mode, we place the const declaration at top so it's done
11347 // only once; But if we not prefixing, we place the declaration inside the
11348 // with block so it doesn't incur the `in` check cost for every helper access.
11349 if (ast.helpers.length > 0) {
11350 {
11351 // "with" mode.
11352 // save Vue in a separate variable to avoid collision
11353 push(`const _Vue = ${VueBinding}\n`);
11354 // in "with" mode, helpers are declared inside the with block to avoid
11355 // has check cost, but hoists are lifted out of the function - we need
11356 // to provide the helper here.
11357 if (ast.hoists.length) {
11358 const staticHelpers = [
11359 CREATE_VNODE,
11360 CREATE_COMMENT,
11361 CREATE_TEXT,
11362 CREATE_STATIC
11363 ]
11364 .filter(helper => ast.helpers.includes(helper))
11365 .map(aliasHelper)
11366 .join(', ');
11367 push(`const { ${staticHelpers} } = _Vue\n`);
11368 }
11369 }
11370 }
11371 genHoists(ast.hoists, context);
11372 newline();
11373 push(`return `);
11374}
11375function genAssets(assets, type, { helper, push, newline }) {
11376 const resolver = helper(type === 'component' ? RESOLVE_COMPONENT : RESOLVE_DIRECTIVE);
11377 for (let i = 0; i < assets.length; i++) {
11378 const id = assets[i];
11379 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)})`);
11380 if (i < assets.length - 1) {
11381 newline();
11382 }
11383 }
11384}
11385function genHoists(hoists, context) {
11386 if (!hoists.length) {
11387 return;
11388 }
11389 context.pure = true;
11390 const { push, newline, helper, scopeId, mode } = context;
11391 newline();
11392 hoists.forEach((exp, i) => {
11393 if (exp) {
11394 push(`const _hoisted_${i + 1} = `);
11395 genNode(exp, context);
11396 newline();
11397 }
11398 });
11399 context.pure = false;
11400}
11401function isText$1(n) {
11402 return (isString(n) ||
11403 n.type === 4 /* SIMPLE_EXPRESSION */ ||
11404 n.type === 2 /* TEXT */ ||
11405 n.type === 5 /* INTERPOLATION */ ||
11406 n.type === 8 /* COMPOUND_EXPRESSION */);
11407}
11408function genNodeListAsArray(nodes, context) {
11409 const multilines = nodes.length > 3 ||
11410 (nodes.some(n => isArray(n) || !isText$1(n)));
11411 context.push(`[`);
11412 multilines && context.indent();
11413 genNodeList(nodes, context, multilines);
11414 multilines && context.deindent();
11415 context.push(`]`);
11416}
11417function genNodeList(nodes, context, multilines = false, comma = true) {
11418 const { push, newline } = context;
11419 for (let i = 0; i < nodes.length; i++) {
11420 const node = nodes[i];
11421 if (isString(node)) {
11422 push(node);
11423 }
11424 else if (isArray(node)) {
11425 genNodeListAsArray(node, context);
11426 }
11427 else {
11428 genNode(node, context);
11429 }
11430 if (i < nodes.length - 1) {
11431 if (multilines) {
11432 comma && push(',');
11433 newline();
11434 }
11435 else {
11436 comma && push(', ');
11437 }
11438 }
11439 }
11440}
11441function genNode(node, context) {
11442 if (isString(node)) {
11443 context.push(node);
11444 return;
11445 }
11446 if (isSymbol(node)) {
11447 context.push(context.helper(node));
11448 return;
11449 }
11450 switch (node.type) {
11451 case 1 /* ELEMENT */:
11452 case 9 /* IF */:
11453 case 11 /* FOR */:
11454 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
11455 `Apply appropriate transforms first.`);
11456 genNode(node.codegenNode, context);
11457 break;
11458 case 2 /* TEXT */:
11459 genText(node, context);
11460 break;
11461 case 4 /* SIMPLE_EXPRESSION */:
11462 genExpression(node, context);
11463 break;
11464 case 5 /* INTERPOLATION */:
11465 genInterpolation(node, context);
11466 break;
11467 case 12 /* TEXT_CALL */:
11468 genNode(node.codegenNode, context);
11469 break;
11470 case 8 /* COMPOUND_EXPRESSION */:
11471 genCompoundExpression(node, context);
11472 break;
11473 case 3 /* COMMENT */:
11474 genComment(node, context);
11475 break;
11476 case 13 /* VNODE_CALL */:
11477 genVNodeCall(node, context);
11478 break;
11479 case 14 /* JS_CALL_EXPRESSION */:
11480 genCallExpression(node, context);
11481 break;
11482 case 15 /* JS_OBJECT_EXPRESSION */:
11483 genObjectExpression(node, context);
11484 break;
11485 case 17 /* JS_ARRAY_EXPRESSION */:
11486 genArrayExpression(node, context);
11487 break;
11488 case 18 /* JS_FUNCTION_EXPRESSION */:
11489 genFunctionExpression(node, context);
11490 break;
11491 case 19 /* JS_CONDITIONAL_EXPRESSION */:
11492 genConditionalExpression(node, context);
11493 break;
11494 case 20 /* JS_CACHE_EXPRESSION */:
11495 genCacheExpression(node, context);
11496 break;
11497 // SSR only types
11498 case 21 /* JS_BLOCK_STATEMENT */:
11499 break;
11500 case 22 /* JS_TEMPLATE_LITERAL */:
11501 break;
11502 case 23 /* JS_IF_STATEMENT */:
11503 break;
11504 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
11505 break;
11506 case 25 /* JS_SEQUENCE_EXPRESSION */:
11507 break;
11508 case 26 /* JS_RETURN_STATEMENT */:
11509 break;
11510 /* istanbul ignore next */
11511 case 10 /* IF_BRANCH */:
11512 // noop
11513 break;
11514 default:
11515 {
11516 assert(false, `unhandled codegen node type: ${node.type}`);
11517 // make sure we exhaust all possible types
11518 const exhaustiveCheck = node;
11519 return exhaustiveCheck;
11520 }
11521 }
11522}
11523function genText(node, context) {
11524 context.push(JSON.stringify(node.content), node);
11525}
11526function genExpression(node, context) {
11527 const { content, isStatic } = node;
11528 context.push(isStatic ? JSON.stringify(content) : content, node);
11529}
11530function genInterpolation(node, context) {
11531 const { push, helper, pure } = context;
11532 if (pure)
11533 push(PURE_ANNOTATION);
11534 push(`${helper(TO_DISPLAY_STRING)}(`);
11535 genNode(node.content, context);
11536 push(`)`);
11537}
11538function genCompoundExpression(node, context) {
11539 for (let i = 0; i < node.children.length; i++) {
11540 const child = node.children[i];
11541 if (isString(child)) {
11542 context.push(child);
11543 }
11544 else {
11545 genNode(child, context);
11546 }
11547 }
11548}
11549function genExpressionAsPropertyKey(node, context) {
11550 const { push } = context;
11551 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
11552 push(`[`);
11553 genCompoundExpression(node, context);
11554 push(`]`);
11555 }
11556 else if (node.isStatic) {
11557 // only quote keys if necessary
11558 const text = isSimpleIdentifier(node.content)
11559 ? node.content
11560 : JSON.stringify(node.content);
11561 push(text, node);
11562 }
11563 else {
11564 push(`[${node.content}]`, node);
11565 }
11566}
11567function genComment(node, context) {
11568 {
11569 const { push, helper, pure } = context;
11570 if (pure) {
11571 push(PURE_ANNOTATION);
11572 }
11573 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
11574 }
11575}
11576function genVNodeCall(node, context) {
11577 const { push, helper, pure } = context;
11578 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking } = node;
11579 if (directives) {
11580 push(helper(WITH_DIRECTIVES) + `(`);
11581 }
11582 if (isBlock) {
11583 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
11584 }
11585 if (pure) {
11586 push(PURE_ANNOTATION);
11587 }
11588 push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node);
11589 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
11590 push(`)`);
11591 if (isBlock) {
11592 push(`)`);
11593 }
11594 if (directives) {
11595 push(`, `);
11596 genNode(directives, context);
11597 push(`)`);
11598 }
11599}
11600function genNullableArgs(args) {
11601 let i = args.length;
11602 while (i--) {
11603 if (args[i] != null)
11604 break;
11605 }
11606 return args.slice(0, i + 1).map(arg => arg || `null`);
11607}
11608// JavaScript
11609function genCallExpression(node, context) {
11610 const { push, helper, pure } = context;
11611 const callee = isString(node.callee) ? node.callee : helper(node.callee);
11612 if (pure) {
11613 push(PURE_ANNOTATION);
11614 }
11615 push(callee + `(`, node);
11616 genNodeList(node.arguments, context);
11617 push(`)`);
11618}
11619function genObjectExpression(node, context) {
11620 const { push, indent, deindent, newline } = context;
11621 const { properties } = node;
11622 if (!properties.length) {
11623 push(`{}`, node);
11624 return;
11625 }
11626 const multilines = properties.length > 1 ||
11627 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
11628 push(multilines ? `{` : `{ `);
11629 multilines && indent();
11630 for (let i = 0; i < properties.length; i++) {
11631 const { key, value } = properties[i];
11632 // key
11633 genExpressionAsPropertyKey(key, context);
11634 push(`: `);
11635 // value
11636 genNode(value, context);
11637 if (i < properties.length - 1) {
11638 // will only reach this if it's multilines
11639 push(`,`);
11640 newline();
11641 }
11642 }
11643 multilines && deindent();
11644 push(multilines ? `}` : ` }`);
11645}
11646function genArrayExpression(node, context) {
11647 genNodeListAsArray(node.elements, context);
11648}
11649function genFunctionExpression(node, context) {
11650 const { push, indent, deindent, scopeId, mode } = context;
11651 const { params, returns, body, newline, isSlot } = node;
11652 if (isSlot) {
11653 push(`_${helperNameMap[WITH_CTX]}(`);
11654 }
11655 push(`(`, node);
11656 if (isArray(params)) {
11657 genNodeList(params, context);
11658 }
11659 else if (params) {
11660 genNode(params, context);
11661 }
11662 push(`) => `);
11663 if (newline || body) {
11664 push(`{`);
11665 indent();
11666 }
11667 if (returns) {
11668 if (newline) {
11669 push(`return `);
11670 }
11671 if (isArray(returns)) {
11672 genNodeListAsArray(returns, context);
11673 }
11674 else {
11675 genNode(returns, context);
11676 }
11677 }
11678 else if (body) {
11679 genNode(body, context);
11680 }
11681 if (newline || body) {
11682 deindent();
11683 push(`}`);
11684 }
11685 if (isSlot) {
11686 push(`)`);
11687 }
11688}
11689function genConditionalExpression(node, context) {
11690 const { test, consequent, alternate, newline: needNewline } = node;
11691 const { push, indent, deindent, newline } = context;
11692 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
11693 const needsParens = !isSimpleIdentifier(test.content);
11694 needsParens && push(`(`);
11695 genExpression(test, context);
11696 needsParens && push(`)`);
11697 }
11698 else {
11699 push(`(`);
11700 genNode(test, context);
11701 push(`)`);
11702 }
11703 needNewline && indent();
11704 context.indentLevel++;
11705 needNewline || push(` `);
11706 push(`? `);
11707 genNode(consequent, context);
11708 context.indentLevel--;
11709 needNewline && newline();
11710 needNewline || push(` `);
11711 push(`: `);
11712 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
11713 if (!isNested) {
11714 context.indentLevel++;
11715 }
11716 genNode(alternate, context);
11717 if (!isNested) {
11718 context.indentLevel--;
11719 }
11720 needNewline && deindent(true /* without newline */);
11721}
11722function genCacheExpression(node, context) {
11723 const { push, helper, indent, deindent, newline } = context;
11724 push(`_cache[${node.index}] || (`);
11725 if (node.isVNode) {
11726 indent();
11727 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
11728 newline();
11729 }
11730 push(`_cache[${node.index}] = `);
11731 genNode(node.value, context);
11732 if (node.isVNode) {
11733 push(`,`);
11734 newline();
11735 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
11736 newline();
11737 push(`_cache[${node.index}]`);
11738 deindent();
11739 }
11740 push(`)`);
11741}
11742
11743// these keywords should not appear inside expressions, but operators like
11744// typeof, instanceof and in are allowed
11745const prohibitedKeywordRE = new RegExp('\\b' +
11746 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
11747 'super,throw,while,yield,delete,export,import,return,switch,default,' +
11748 'extends,finally,continue,debugger,function,arguments,typeof,void')
11749 .split(',')
11750 .join('\\b|\\b') +
11751 '\\b');
11752// strip strings in expressions
11753const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
11754/**
11755 * Validate a non-prefixed expression.
11756 * This is only called when using the in-browser runtime compiler since it
11757 * doesn't prefix expressions.
11758 */
11759function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
11760 const exp = node.content;
11761 // empty expressions are validated per-directive since some directives
11762 // do allow empty expressions.
11763 if (!exp.trim()) {
11764 return;
11765 }
11766 try {
11767 new Function(asRawStatements
11768 ? ` ${exp} `
11769 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
11770 }
11771 catch (e) {
11772 let message = e.message;
11773 const keywordMatch = exp
11774 .replace(stripStringRE, '')
11775 .match(prohibitedKeywordRE);
11776 if (keywordMatch) {
11777 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
11778 }
11779 context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
11780 }
11781}
11782
11783const transformExpression = (node, context) => {
11784 if (node.type === 5 /* INTERPOLATION */) {
11785 node.content = processExpression(node.content, context);
11786 }
11787 else if (node.type === 1 /* ELEMENT */) {
11788 // handle directives on element
11789 for (let i = 0; i < node.props.length; i++) {
11790 const dir = node.props[i];
11791 // do not process for v-on & v-for since they are special handled
11792 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
11793 const exp = dir.exp;
11794 const arg = dir.arg;
11795 // do not process exp if this is v-on:arg - we need special handling
11796 // for wrapping inline statements.
11797 if (exp &&
11798 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
11799 !(dir.name === 'on' && arg)) {
11800 dir.exp = processExpression(exp, context,
11801 // slot args must be processed as function params
11802 dir.name === 'slot');
11803 }
11804 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
11805 dir.arg = processExpression(arg, context);
11806 }
11807 }
11808 }
11809 }
11810};
11811// Important: since this function uses Node.js only dependencies, it should
11812// always be used with a leading !true check so that it can be
11813// tree-shaken from the browser build.
11814function processExpression(node, context,
11815// some expressions like v-slot props & v-for aliases should be parsed as
11816// function params
11817asParams = false,
11818// v-on handler values may contain multiple statements
11819asRawStatements = false) {
11820 {
11821 {
11822 // simple in-browser validation (same logic in 2.x)
11823 validateBrowserExpression(node, context, asParams, asRawStatements);
11824 }
11825 return node;
11826 }
11827}
11828
11829const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
11830 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
11831 // #1587: We need to dynamically increment the key based on the current
11832 // node's sibling nodes, since chained v-if/else branches are
11833 // rendered at the same depth
11834 const siblings = context.parent.children;
11835 let i = siblings.indexOf(ifNode);
11836 let key = 0;
11837 while (i-- >= 0) {
11838 const sibling = siblings[i];
11839 if (sibling && sibling.type === 9 /* IF */) {
11840 key += sibling.branches.length;
11841 }
11842 }
11843 // Exit callback. Complete the codegenNode when all children have been
11844 // transformed.
11845 return () => {
11846 if (isRoot) {
11847 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
11848 }
11849 else {
11850 // attach this branch's codegen node to the v-if root.
11851 const parentCondition = getParentCondition(ifNode.codegenNode);
11852 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
11853 }
11854 };
11855 });
11856});
11857// target-agnostic transform used for both Client and SSR
11858function processIf(node, dir, context, processCodegen) {
11859 if (dir.name !== 'else' &&
11860 (!dir.exp || !dir.exp.content.trim())) {
11861 const loc = dir.exp ? dir.exp.loc : node.loc;
11862 context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));
11863 dir.exp = createSimpleExpression(`true`, false, loc);
11864 }
11865 if (dir.exp) {
11866 validateBrowserExpression(dir.exp, context);
11867 }
11868 if (dir.name === 'if') {
11869 const branch = createIfBranch(node, dir);
11870 const ifNode = {
11871 type: 9 /* IF */,
11872 loc: node.loc,
11873 branches: [branch]
11874 };
11875 context.replaceNode(ifNode);
11876 if (processCodegen) {
11877 return processCodegen(ifNode, branch, true);
11878 }
11879 }
11880 else {
11881 // locate the adjacent v-if
11882 const siblings = context.parent.children;
11883 const comments = [];
11884 let i = siblings.indexOf(node);
11885 while (i-- >= -1) {
11886 const sibling = siblings[i];
11887 if (sibling && sibling.type === 3 /* COMMENT */) {
11888 context.removeNode(sibling);
11889 comments.unshift(sibling);
11890 continue;
11891 }
11892 if (sibling &&
11893 sibling.type === 2 /* TEXT */ &&
11894 !sibling.content.trim().length) {
11895 context.removeNode(sibling);
11896 continue;
11897 }
11898 if (sibling && sibling.type === 9 /* IF */) {
11899 // move the node to the if node's branches
11900 context.removeNode();
11901 const branch = createIfBranch(node, dir);
11902 if (comments.length) {
11903 branch.children = [...comments, ...branch.children];
11904 }
11905 // check if user is forcing same key on different branches
11906 {
11907 const key = branch.userKey;
11908 if (key) {
11909 sibling.branches.forEach(({ userKey }) => {
11910 if (isSameKey(userKey, key)) {
11911 context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
11912 }
11913 });
11914 }
11915 }
11916 sibling.branches.push(branch);
11917 const onExit = processCodegen && processCodegen(sibling, branch, false);
11918 // since the branch was removed, it will not be traversed.
11919 // make sure to traverse here.
11920 traverseNode(branch, context);
11921 // call on exit
11922 if (onExit)
11923 onExit();
11924 // make sure to reset currentNode after traversal to indicate this
11925 // node has been removed.
11926 context.currentNode = null;
11927 }
11928 else {
11929 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
11930 }
11931 break;
11932 }
11933 }
11934}
11935function createIfBranch(node, dir) {
11936 return {
11937 type: 10 /* IF_BRANCH */,
11938 loc: node.loc,
11939 condition: dir.name === 'else' ? undefined : dir.exp,
11940 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
11941 ? node.children
11942 : [node],
11943 userKey: findProp(node, `key`)
11944 };
11945}
11946function createCodegenNodeForBranch(branch, keyIndex, context) {
11947 if (branch.condition) {
11948 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
11949 // make sure to pass in asBlock: true so that the comment node call
11950 // closes the current block.
11951 createCallExpression(context.helper(CREATE_COMMENT), [
11952 '"v-if"' ,
11953 'true'
11954 ]));
11955 }
11956 else {
11957 return createChildrenCodegenNode(branch, keyIndex, context);
11958 }
11959}
11960function createChildrenCodegenNode(branch, keyIndex, context) {
11961 const { helper } = context;
11962 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
11963 const { children } = branch;
11964 const firstChild = children[0];
11965 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
11966 if (needFragmentWrapper) {
11967 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
11968 // optimize away nested fragments when child is a ForNode
11969 const vnodeCall = firstChild.codegenNode;
11970 injectProp(vnodeCall, keyProperty, context);
11971 return vnodeCall;
11972 }
11973 else {
11974 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, 64 /* STABLE_FRAGMENT */ +
11975 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
11976 ), undefined, undefined, true, false, branch.loc);
11977 }
11978 }
11979 else {
11980 const vnodeCall = firstChild
11981 .codegenNode;
11982 // Change createVNode to createBlock.
11983 if (vnodeCall.type === 13 /* VNODE_CALL */) {
11984 vnodeCall.isBlock = true;
11985 helper(OPEN_BLOCK);
11986 helper(CREATE_BLOCK);
11987 }
11988 // inject branch key
11989 injectProp(vnodeCall, keyProperty, context);
11990 return vnodeCall;
11991 }
11992}
11993function isSameKey(a, b) {
11994 if (!a || a.type !== b.type) {
11995 return false;
11996 }
11997 if (a.type === 6 /* ATTRIBUTE */) {
11998 if (a.value.content !== b.value.content) {
11999 return false;
12000 }
12001 }
12002 else {
12003 // directive
12004 const exp = a.exp;
12005 const branchExp = b.exp;
12006 if (exp.type !== branchExp.type) {
12007 return false;
12008 }
12009 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
12010 (exp.isStatic !== branchExp.isStatic ||
12011 exp.content !== branchExp.content)) {
12012 return false;
12013 }
12014 }
12015 return true;
12016}
12017function getParentCondition(node) {
12018 while (true) {
12019 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12020 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12021 node = node.alternate;
12022 }
12023 else {
12024 return node;
12025 }
12026 }
12027 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
12028 node = node.value;
12029 }
12030 }
12031}
12032
12033const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
12034 const { helper } = context;
12035 return processFor(node, dir, context, forNode => {
12036 // create the loop render function expression now, and add the
12037 // iterator on exit after all children have been traversed
12038 const renderExp = createCallExpression(helper(RENDER_LIST), [
12039 forNode.source
12040 ]);
12041 const keyProp = findProp(node, `key`);
12042 const keyProperty = keyProp
12043 ? createObjectProperty(`key`, keyProp.type === 6 /* ATTRIBUTE */
12044 ? createSimpleExpression(keyProp.value.content, true)
12045 : keyProp.exp)
12046 : null;
12047 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
12048 forNode.source.constType > 0 /* NOT_CONSTANT */;
12049 const fragmentFlag = isStableFragment
12050 ? 64 /* STABLE_FRAGMENT */
12051 : keyProp
12052 ? 128 /* KEYED_FRAGMENT */
12053 : 256 /* UNKEYED_FRAGMENT */;
12054 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
12055 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, node.loc);
12056 return () => {
12057 // finish the codegen now that all children have been traversed
12058 let childBlock;
12059 const isTemplate = isTemplateNode(node);
12060 const { children } = forNode;
12061 // check <template v-for> key placement
12062 if (isTemplate) {
12063 node.children.some(c => {
12064 if (c.type === 1 /* ELEMENT */) {
12065 const key = findProp(c, 'key');
12066 if (key) {
12067 context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
12068 return true;
12069 }
12070 }
12071 });
12072 }
12073 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
12074 const slotOutlet = isSlotOutlet(node)
12075 ? node
12076 : isTemplate &&
12077 node.children.length === 1 &&
12078 isSlotOutlet(node.children[0])
12079 ? node.children[0] // api-extractor somehow fails to infer this
12080 : null;
12081 if (slotOutlet) {
12082 // <slot v-for="..."> or <template v-for="..."><slot/></template>
12083 childBlock = slotOutlet.codegenNode;
12084 if (isTemplate && keyProperty) {
12085 // <template v-for="..." :key="..."><slot/></template>
12086 // we need to inject the key to the renderSlot() call.
12087 // the props for renderSlot is passed as the 3rd argument.
12088 injectProp(childBlock, keyProperty, context);
12089 }
12090 }
12091 else if (needFragmentWrapper) {
12092 // <template v-for="..."> with text or multi-elements
12093 // should generate a fragment block for each loop
12094 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
12095 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
12096 ), undefined, undefined, true);
12097 }
12098 else {
12099 // Normal element v-for. Directly use the child's codegenNode
12100 // but mark it as a block.
12101 childBlock = children[0]
12102 .codegenNode;
12103 if (isTemplate && keyProperty) {
12104 injectProp(childBlock, keyProperty, context);
12105 }
12106 childBlock.isBlock = !isStableFragment;
12107 if (childBlock.isBlock) {
12108 helper(OPEN_BLOCK);
12109 helper(CREATE_BLOCK);
12110 }
12111 else {
12112 helper(CREATE_VNODE);
12113 }
12114 }
12115 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
12116 };
12117 });
12118});
12119// target-agnostic transform used for both Client and SSR
12120function processFor(node, dir, context, processCodegen) {
12121 if (!dir.exp) {
12122 context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
12123 return;
12124 }
12125 const parseResult = parseForExpression(
12126 // can only be simple expression because vFor transform is applied
12127 // before expression transform.
12128 dir.exp, context);
12129 if (!parseResult) {
12130 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
12131 return;
12132 }
12133 const { addIdentifiers, removeIdentifiers, scopes } = context;
12134 const { source, value, key, index } = parseResult;
12135 const forNode = {
12136 type: 11 /* FOR */,
12137 loc: dir.loc,
12138 source,
12139 valueAlias: value,
12140 keyAlias: key,
12141 objectIndexAlias: index,
12142 parseResult,
12143 children: isTemplateNode(node) ? node.children : [node]
12144 };
12145 context.replaceNode(forNode);
12146 // bookkeeping
12147 scopes.vFor++;
12148 const onExit = processCodegen && processCodegen(forNode);
12149 return () => {
12150 scopes.vFor--;
12151 if (onExit)
12152 onExit();
12153 };
12154}
12155const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
12156// This regex doesn't cover the case if key or index aliases have destructuring,
12157// but those do not make sense in the first place, so this works in practice.
12158const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
12159const stripParensRE = /^\(|\)$/g;
12160function parseForExpression(input, context) {
12161 const loc = input.loc;
12162 const exp = input.content;
12163 const inMatch = exp.match(forAliasRE);
12164 if (!inMatch)
12165 return;
12166 const [, LHS, RHS] = inMatch;
12167 const result = {
12168 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
12169 value: undefined,
12170 key: undefined,
12171 index: undefined
12172 };
12173 {
12174 validateBrowserExpression(result.source, context);
12175 }
12176 let valueContent = LHS.trim()
12177 .replace(stripParensRE, '')
12178 .trim();
12179 const trimmedOffset = LHS.indexOf(valueContent);
12180 const iteratorMatch = valueContent.match(forIteratorRE);
12181 if (iteratorMatch) {
12182 valueContent = valueContent.replace(forIteratorRE, '').trim();
12183 const keyContent = iteratorMatch[1].trim();
12184 let keyOffset;
12185 if (keyContent) {
12186 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
12187 result.key = createAliasExpression(loc, keyContent, keyOffset);
12188 {
12189 validateBrowserExpression(result.key, context, true);
12190 }
12191 }
12192 if (iteratorMatch[2]) {
12193 const indexContent = iteratorMatch[2].trim();
12194 if (indexContent) {
12195 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
12196 ? keyOffset + keyContent.length
12197 : trimmedOffset + valueContent.length));
12198 {
12199 validateBrowserExpression(result.index, context, true);
12200 }
12201 }
12202 }
12203 }
12204 if (valueContent) {
12205 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
12206 {
12207 validateBrowserExpression(result.value, context, true);
12208 }
12209 }
12210 return result;
12211}
12212function createAliasExpression(range, content, offset) {
12213 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
12214}
12215function createForLoopParams({ value, key, index }) {
12216 const params = [];
12217 if (value) {
12218 params.push(value);
12219 }
12220 if (key) {
12221 if (!value) {
12222 params.push(createSimpleExpression(`_`, false));
12223 }
12224 params.push(key);
12225 }
12226 if (index) {
12227 if (!key) {
12228 if (!value) {
12229 params.push(createSimpleExpression(`_`, false));
12230 }
12231 params.push(createSimpleExpression(`__`, false));
12232 }
12233 params.push(index);
12234 }
12235 return params;
12236}
12237
12238const defaultFallback = createSimpleExpression(`undefined`, false);
12239// A NodeTransform that:
12240// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
12241// by transformExpression. This is only applied in non-browser builds with
12242// { prefixIdentifiers: true }.
12243// 2. Track v-slot depths so that we know a slot is inside another slot.
12244// Note the exit callback is executed before buildSlots() on the same node,
12245// so only nested slots see positive numbers.
12246const trackSlotScopes = (node, context) => {
12247 if (node.type === 1 /* ELEMENT */ &&
12248 (node.tagType === 1 /* COMPONENT */ ||
12249 node.tagType === 3 /* TEMPLATE */)) {
12250 // We are only checking non-empty v-slot here
12251 // since we only care about slots that introduce scope variables.
12252 const vSlot = findDir(node, 'slot');
12253 if (vSlot) {
12254 vSlot.exp;
12255 context.scopes.vSlot++;
12256 return () => {
12257 context.scopes.vSlot--;
12258 };
12259 }
12260 }
12261};
12262const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
12263// Instead of being a DirectiveTransform, v-slot processing is called during
12264// transformElement to build the slots object for a component.
12265function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
12266 context.helper(WITH_CTX);
12267 const { children, loc } = node;
12268 const slotsProperties = [];
12269 const dynamicSlots = [];
12270 const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));
12271 // If the slot is inside a v-for or another v-slot, force it to be dynamic
12272 // since it likely uses a scope variable.
12273 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
12274 // 1. Check for slot with slotProps on component itself.
12275 // <Comp v-slot="{ prop }"/>
12276 const onComponentSlot = findDir(node, 'slot', true);
12277 if (onComponentSlot) {
12278 const { arg, exp } = onComponentSlot;
12279 if (arg && !isStaticExp(arg)) {
12280 hasDynamicSlots = true;
12281 }
12282 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
12283 }
12284 // 2. Iterate through children and check for template slots
12285 // <template v-slot:foo="{ prop }">
12286 let hasTemplateSlots = false;
12287 let hasNamedDefaultSlot = false;
12288 const implicitDefaultChildren = [];
12289 const seenSlotNames = new Set();
12290 for (let i = 0; i < children.length; i++) {
12291 const slotElement = children[i];
12292 let slotDir;
12293 if (!isTemplateNode(slotElement) ||
12294 !(slotDir = findDir(slotElement, 'slot', true))) {
12295 // not a <template v-slot>, skip.
12296 if (slotElement.type !== 3 /* COMMENT */) {
12297 implicitDefaultChildren.push(slotElement);
12298 }
12299 continue;
12300 }
12301 if (onComponentSlot) {
12302 // already has on-component slot - this is incorrect usage.
12303 context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
12304 break;
12305 }
12306 hasTemplateSlots = true;
12307 const { children: slotChildren, loc: slotLoc } = slotElement;
12308 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
12309 // check if name is dynamic.
12310 let staticSlotName;
12311 if (isStaticExp(slotName)) {
12312 staticSlotName = slotName ? slotName.content : `default`;
12313 }
12314 else {
12315 hasDynamicSlots = true;
12316 }
12317 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
12318 // check if this slot is conditional (v-if/v-for)
12319 let vIf;
12320 let vElse;
12321 let vFor;
12322 if ((vIf = findDir(slotElement, 'if'))) {
12323 hasDynamicSlots = true;
12324 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
12325 }
12326 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
12327 // find adjacent v-if
12328 let j = i;
12329 let prev;
12330 while (j--) {
12331 prev = children[j];
12332 if (prev.type !== 3 /* COMMENT */) {
12333 break;
12334 }
12335 }
12336 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
12337 // remove node
12338 children.splice(i, 1);
12339 i--;
12340 // attach this slot to previous conditional
12341 let conditional = dynamicSlots[dynamicSlots.length - 1];
12342 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
12343 conditional = conditional.alternate;
12344 }
12345 conditional.alternate = vElse.exp
12346 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
12347 : buildDynamicSlot(slotName, slotFunction);
12348 }
12349 else {
12350 context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
12351 }
12352 }
12353 else if ((vFor = findDir(slotElement, 'for'))) {
12354 hasDynamicSlots = true;
12355 const parseResult = vFor.parseResult ||
12356 parseForExpression(vFor.exp, context);
12357 if (parseResult) {
12358 // Render the dynamic slots as an array and add it to the createSlot()
12359 // args. The runtime knows how to handle it appropriately.
12360 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
12361 parseResult.source,
12362 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
12363 ]));
12364 }
12365 else {
12366 context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
12367 }
12368 }
12369 else {
12370 // check duplicate static names
12371 if (staticSlotName) {
12372 if (seenSlotNames.has(staticSlotName)) {
12373 context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
12374 continue;
12375 }
12376 seenSlotNames.add(staticSlotName);
12377 if (staticSlotName === 'default') {
12378 hasNamedDefaultSlot = true;
12379 }
12380 }
12381 slotsProperties.push(createObjectProperty(slotName, slotFunction));
12382 }
12383 }
12384 if (!onComponentSlot) {
12385 if (!hasTemplateSlots) {
12386 // implicit default slot (on component)
12387 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
12388 }
12389 else if (implicitDefaultChildren.length) {
12390 // implicit default slot (mixed with named slots)
12391 if (hasNamedDefaultSlot) {
12392 context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
12393 }
12394 else {
12395 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
12396 }
12397 }
12398 }
12399 const slotFlag = hasDynamicSlots
12400 ? 2 /* DYNAMIC */
12401 : hasForwardedSlots(node.children)
12402 ? 3 /* FORWARDED */
12403 : 1 /* STABLE */;
12404 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
12405 // 2 = compiled but dynamic = can skip normalization, but must run diff
12406 // 1 = compiled and static = can skip normalization AND diff as optimized
12407 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
12408 if (dynamicSlots.length) {
12409 slots = createCallExpression(context.helper(CREATE_SLOTS), [
12410 slots,
12411 createArrayExpression(dynamicSlots)
12412 ]);
12413 }
12414 return {
12415 slots,
12416 hasDynamicSlots
12417 };
12418}
12419function buildDynamicSlot(name, fn) {
12420 return createObjectExpression([
12421 createObjectProperty(`name`, name),
12422 createObjectProperty(`fn`, fn)
12423 ]);
12424}
12425function hasForwardedSlots(children) {
12426 for (let i = 0; i < children.length; i++) {
12427 const child = children[i];
12428 if (child.type === 1 /* ELEMENT */) {
12429 if (child.tagType === 2 /* SLOT */ ||
12430 (child.tagType === 0 /* ELEMENT */ &&
12431 hasForwardedSlots(child.children))) {
12432 return true;
12433 }
12434 }
12435 }
12436 return false;
12437}
12438
12439// some directive transforms (e.g. v-model) may return a symbol for runtime
12440// import, which should be used instead of a resolveDirective call.
12441const directiveImportMap = new WeakMap();
12442// generate a JavaScript AST for this element's codegen
12443const transformElement = (node, context) => {
12444 if (!(node.type === 1 /* ELEMENT */ &&
12445 (node.tagType === 0 /* ELEMENT */ ||
12446 node.tagType === 1 /* COMPONENT */))) {
12447 return;
12448 }
12449 // perform the work on exit, after all child expressions have been
12450 // processed and merged.
12451 return function postTransformElement() {
12452 const { tag, props } = node;
12453 const isComponent = node.tagType === 1 /* COMPONENT */;
12454 // The goal of the transform is to create a codegenNode implementing the
12455 // VNodeCall interface.
12456 const vnodeTag = isComponent
12457 ? resolveComponentType(node, context)
12458 : `"${tag}"`;
12459 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
12460 let vnodeProps;
12461 let vnodeChildren;
12462 let vnodePatchFlag;
12463 let patchFlag = 0;
12464 let vnodeDynamicProps;
12465 let dynamicPropNames;
12466 let vnodeDirectives;
12467 let shouldUseBlock =
12468 // dynamic component may resolve to plain elements
12469 isDynamicComponent ||
12470 vnodeTag === TELEPORT ||
12471 vnodeTag === SUSPENSE ||
12472 (!isComponent &&
12473 // <svg> and <foreignObject> must be forced into blocks so that block
12474 // updates inside get proper isSVG flag at runtime. (#639, #643)
12475 // This is technically web-specific, but splitting the logic out of core
12476 // leads to too much unnecessary complexity.
12477 (tag === 'svg' ||
12478 tag === 'foreignObject' ||
12479 // #938: elements with dynamic keys should be forced into blocks
12480 findProp(node, 'key', true)));
12481 // props
12482 if (props.length > 0) {
12483 const propsBuildResult = buildProps(node, context);
12484 vnodeProps = propsBuildResult.props;
12485 patchFlag = propsBuildResult.patchFlag;
12486 dynamicPropNames = propsBuildResult.dynamicPropNames;
12487 const directives = propsBuildResult.directives;
12488 vnodeDirectives =
12489 directives && directives.length
12490 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
12491 : undefined;
12492 }
12493 // children
12494 if (node.children.length > 0) {
12495 if (vnodeTag === KEEP_ALIVE) {
12496 // Although a built-in component, we compile KeepAlive with raw children
12497 // instead of slot functions so that it can be used inside Transition
12498 // or other Transition-wrapping HOCs.
12499 // To ensure correct updates with block optimizations, we need to:
12500 // 1. Force keep-alive into a block. This avoids its children being
12501 // collected by a parent block.
12502 shouldUseBlock = true;
12503 // 2. Force keep-alive to always be updated, since it uses raw children.
12504 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
12505 if (node.children.length > 1) {
12506 context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
12507 start: node.children[0].loc.start,
12508 end: node.children[node.children.length - 1].loc.end,
12509 source: ''
12510 }));
12511 }
12512 }
12513 const shouldBuildAsSlots = isComponent &&
12514 // Teleport is not a real component and has dedicated runtime handling
12515 vnodeTag !== TELEPORT &&
12516 // explained above.
12517 vnodeTag !== KEEP_ALIVE;
12518 if (shouldBuildAsSlots) {
12519 const { slots, hasDynamicSlots } = buildSlots(node, context);
12520 vnodeChildren = slots;
12521 if (hasDynamicSlots) {
12522 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
12523 }
12524 }
12525 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
12526 const child = node.children[0];
12527 const type = child.type;
12528 // check for dynamic text children
12529 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
12530 type === 8 /* COMPOUND_EXPRESSION */;
12531 if (hasDynamicTextChild &&
12532 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
12533 patchFlag |= 1 /* TEXT */;
12534 }
12535 // pass directly if the only child is a text node
12536 // (plain / interpolation / expression)
12537 if (hasDynamicTextChild || type === 2 /* TEXT */) {
12538 vnodeChildren = child;
12539 }
12540 else {
12541 vnodeChildren = node.children;
12542 }
12543 }
12544 else {
12545 vnodeChildren = node.children;
12546 }
12547 }
12548 // patchFlag & dynamicPropNames
12549 if (patchFlag !== 0) {
12550 {
12551 if (patchFlag < 0) {
12552 // special flags (negative and mutually exclusive)
12553 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
12554 }
12555 else {
12556 // bitwise flags
12557 const flagNames = Object.keys(PatchFlagNames)
12558 .map(Number)
12559 .filter(n => n > 0 && patchFlag & n)
12560 .map(n => PatchFlagNames[n])
12561 .join(`, `);
12562 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
12563 }
12564 }
12565 if (dynamicPropNames && dynamicPropNames.length) {
12566 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
12567 }
12568 }
12569 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, node.loc);
12570 };
12571};
12572function resolveComponentType(node, context, ssr = false) {
12573 const { tag } = node;
12574 // 1. dynamic component
12575 const isProp = node.tag === 'component' ? findProp(node, 'is') : findDir(node, 'is');
12576 if (isProp) {
12577 const exp = isProp.type === 6 /* ATTRIBUTE */
12578 ? isProp.value && createSimpleExpression(isProp.value.content, true)
12579 : isProp.exp;
12580 if (exp) {
12581 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
12582 exp
12583 ]);
12584 }
12585 }
12586 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
12587 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
12588 if (builtIn) {
12589 // built-ins are simply fallthroughs / have special handling during ssr
12590 // so we don't need to import their runtime equivalents
12591 if (!ssr)
12592 context.helper(builtIn);
12593 return builtIn;
12594 }
12595 // 5. user component (resolve)
12596 context.helper(RESOLVE_COMPONENT);
12597 context.components.add(tag);
12598 return toValidAssetId(tag, `component`);
12599}
12600function buildProps(node, context, props = node.props, ssr = false) {
12601 const { tag, loc: elementLoc } = node;
12602 const isComponent = node.tagType === 1 /* COMPONENT */;
12603 let properties = [];
12604 const mergeArgs = [];
12605 const runtimeDirectives = [];
12606 // patchFlag analysis
12607 let patchFlag = 0;
12608 let hasRef = false;
12609 let hasClassBinding = false;
12610 let hasStyleBinding = false;
12611 let hasHydrationEventBinding = false;
12612 let hasDynamicKeys = false;
12613 let hasVnodeHook = false;
12614 const dynamicPropNames = [];
12615 const analyzePatchFlag = ({ key, value }) => {
12616 if (isStaticExp(key)) {
12617 const name = key.content;
12618 const isEventHandler = isOn(name);
12619 if (!isComponent &&
12620 isEventHandler &&
12621 // omit the flag for click handlers because hydration gives click
12622 // dedicated fast path.
12623 name.toLowerCase() !== 'onclick' &&
12624 // omit v-model handlers
12625 name !== 'onUpdate:modelValue' &&
12626 // omit onVnodeXXX hooks
12627 !isReservedProp(name)) {
12628 hasHydrationEventBinding = true;
12629 }
12630 if (isEventHandler && isReservedProp(name)) {
12631 hasVnodeHook = true;
12632 }
12633 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
12634 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
12635 value.type === 8 /* COMPOUND_EXPRESSION */) &&
12636 getConstantType(value, context) > 0)) {
12637 // skip if the prop is a cached handler or has constant value
12638 return;
12639 }
12640 if (name === 'ref') {
12641 hasRef = true;
12642 }
12643 else if (name === 'class' && !isComponent) {
12644 hasClassBinding = true;
12645 }
12646 else if (name === 'style' && !isComponent) {
12647 hasStyleBinding = true;
12648 }
12649 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
12650 dynamicPropNames.push(name);
12651 }
12652 }
12653 else {
12654 hasDynamicKeys = true;
12655 }
12656 };
12657 for (let i = 0; i < props.length; i++) {
12658 // static attribute
12659 const prop = props[i];
12660 if (prop.type === 6 /* ATTRIBUTE */) {
12661 const { loc, name, value } = prop;
12662 let isStatic = true;
12663 if (name === 'ref') {
12664 hasRef = true;
12665 }
12666 // skip :is on <component>
12667 if (name === 'is' && tag === 'component') {
12668 continue;
12669 }
12670 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
12671 }
12672 else {
12673 // directives
12674 const { name, arg, exp, loc } = prop;
12675 const isBind = name === 'bind';
12676 const isOn = name === 'on';
12677 // skip v-slot - it is handled by its dedicated transform.
12678 if (name === 'slot') {
12679 if (!isComponent) {
12680 context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));
12681 }
12682 continue;
12683 }
12684 // skip v-once - it is handled by its dedicated transform.
12685 if (name === 'once') {
12686 continue;
12687 }
12688 // skip v-is and :is on <component>
12689 if (name === 'is' ||
12690 (isBind && tag === 'component' && isBindKey(arg, 'is'))) {
12691 continue;
12692 }
12693 // skip v-on in SSR compilation
12694 if (isOn && ssr) {
12695 continue;
12696 }
12697 // special case for v-bind and v-on with no argument
12698 if (!arg && (isBind || isOn)) {
12699 hasDynamicKeys = true;
12700 if (exp) {
12701 if (properties.length) {
12702 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
12703 properties = [];
12704 }
12705 if (isBind) {
12706 mergeArgs.push(exp);
12707 }
12708 else {
12709 // v-on="obj" -> toHandlers(obj)
12710 mergeArgs.push({
12711 type: 14 /* JS_CALL_EXPRESSION */,
12712 loc,
12713 callee: context.helper(TO_HANDLERS),
12714 arguments: [exp]
12715 });
12716 }
12717 }
12718 else {
12719 context.onError(createCompilerError(isBind
12720 ? 33 /* X_V_BIND_NO_EXPRESSION */
12721 : 34 /* X_V_ON_NO_EXPRESSION */, loc));
12722 }
12723 continue;
12724 }
12725 const directiveTransform = context.directiveTransforms[name];
12726 if (directiveTransform) {
12727 // has built-in directive transform.
12728 const { props, needRuntime } = directiveTransform(prop, node, context);
12729 !ssr && props.forEach(analyzePatchFlag);
12730 properties.push(...props);
12731 if (needRuntime) {
12732 runtimeDirectives.push(prop);
12733 if (isSymbol(needRuntime)) {
12734 directiveImportMap.set(prop, needRuntime);
12735 }
12736 }
12737 }
12738 else {
12739 // no built-in transform, this is a user custom directive.
12740 runtimeDirectives.push(prop);
12741 }
12742 }
12743 }
12744 let propsExpression = undefined;
12745 // has v-bind="object" or v-on="object", wrap with mergeProps
12746 if (mergeArgs.length) {
12747 if (properties.length) {
12748 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
12749 }
12750 if (mergeArgs.length > 1) {
12751 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
12752 }
12753 else {
12754 // single v-bind with nothing else - no need for a mergeProps call
12755 propsExpression = mergeArgs[0];
12756 }
12757 }
12758 else if (properties.length) {
12759 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
12760 }
12761 // patchFlag analysis
12762 if (hasDynamicKeys) {
12763 patchFlag |= 16 /* FULL_PROPS */;
12764 }
12765 else {
12766 if (hasClassBinding) {
12767 patchFlag |= 2 /* CLASS */;
12768 }
12769 if (hasStyleBinding) {
12770 patchFlag |= 4 /* STYLE */;
12771 }
12772 if (dynamicPropNames.length) {
12773 patchFlag |= 8 /* PROPS */;
12774 }
12775 if (hasHydrationEventBinding) {
12776 patchFlag |= 32 /* HYDRATE_EVENTS */;
12777 }
12778 }
12779 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
12780 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
12781 patchFlag |= 512 /* NEED_PATCH */;
12782 }
12783 return {
12784 props: propsExpression,
12785 directives: runtimeDirectives,
12786 patchFlag,
12787 dynamicPropNames
12788 };
12789}
12790// Dedupe props in an object literal.
12791// Literal duplicated attributes would have been warned during the parse phase,
12792// however, it's possible to encounter duplicated `onXXX` handlers with different
12793// modifiers. We also need to merge static and dynamic class / style attributes.
12794// - onXXX handlers / style: merge into array
12795// - class: merge into single expression with concatenation
12796function dedupeProperties(properties) {
12797 const knownProps = new Map();
12798 const deduped = [];
12799 for (let i = 0; i < properties.length; i++) {
12800 const prop = properties[i];
12801 // dynamic keys are always allowed
12802 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
12803 deduped.push(prop);
12804 continue;
12805 }
12806 const name = prop.key.content;
12807 const existing = knownProps.get(name);
12808 if (existing) {
12809 if (name === 'style' || name === 'class' || name.startsWith('on')) {
12810 mergeAsArray(existing, prop);
12811 }
12812 // unexpected duplicate, should have emitted error during parse
12813 }
12814 else {
12815 knownProps.set(name, prop);
12816 deduped.push(prop);
12817 }
12818 }
12819 return deduped;
12820}
12821function mergeAsArray(existing, incoming) {
12822 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
12823 existing.value.elements.push(incoming.value);
12824 }
12825 else {
12826 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
12827 }
12828}
12829function buildDirectiveArgs(dir, context) {
12830 const dirArgs = [];
12831 const runtime = directiveImportMap.get(dir);
12832 if (runtime) {
12833 // built-in directive with runtime
12834 dirArgs.push(context.helperString(runtime));
12835 }
12836 else {
12837 {
12838 // inject statement for resolving directive
12839 context.helper(RESOLVE_DIRECTIVE);
12840 context.directives.add(dir.name);
12841 dirArgs.push(toValidAssetId(dir.name, `directive`));
12842 }
12843 }
12844 const { loc } = dir;
12845 if (dir.exp)
12846 dirArgs.push(dir.exp);
12847 if (dir.arg) {
12848 if (!dir.exp) {
12849 dirArgs.push(`void 0`);
12850 }
12851 dirArgs.push(dir.arg);
12852 }
12853 if (Object.keys(dir.modifiers).length) {
12854 if (!dir.arg) {
12855 if (!dir.exp) {
12856 dirArgs.push(`void 0`);
12857 }
12858 dirArgs.push(`void 0`);
12859 }
12860 const trueExpression = createSimpleExpression(`true`, false, loc);
12861 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
12862 }
12863 return createArrayExpression(dirArgs, dir.loc);
12864}
12865function stringifyDynamicPropNames(props) {
12866 let propsNamesString = `[`;
12867 for (let i = 0, l = props.length; i < l; i++) {
12868 propsNamesString += JSON.stringify(props[i]);
12869 if (i < l - 1)
12870 propsNamesString += ', ';
12871 }
12872 return propsNamesString + `]`;
12873}
12874
12875const transformSlotOutlet = (node, context) => {
12876 if (isSlotOutlet(node)) {
12877 const { children, loc } = node;
12878 const { slotName, slotProps } = processSlotOutlet(node, context);
12879 const slotArgs = [
12880 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
12881 slotName
12882 ];
12883 if (slotProps) {
12884 slotArgs.push(slotProps);
12885 }
12886 if (children.length) {
12887 if (!slotProps) {
12888 slotArgs.push(`{}`);
12889 }
12890 slotArgs.push(createFunctionExpression([], children, false, false, loc));
12891 }
12892 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
12893 }
12894};
12895function processSlotOutlet(node, context) {
12896 let slotName = `"default"`;
12897 let slotProps = undefined;
12898 const nonNameProps = [];
12899 for (let i = 0; i < node.props.length; i++) {
12900 const p = node.props[i];
12901 if (p.type === 6 /* ATTRIBUTE */) {
12902 if (p.value) {
12903 if (p.name === 'name') {
12904 slotName = JSON.stringify(p.value.content);
12905 }
12906 else {
12907 p.name = camelize(p.name);
12908 nonNameProps.push(p);
12909 }
12910 }
12911 }
12912 else {
12913 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
12914 if (p.exp)
12915 slotName = p.exp;
12916 }
12917 else {
12918 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
12919 p.arg.content = camelize(p.arg.content);
12920 }
12921 nonNameProps.push(p);
12922 }
12923 }
12924 }
12925 if (nonNameProps.length > 0) {
12926 const { props, directives } = buildProps(node, context, nonNameProps);
12927 slotProps = props;
12928 if (directives.length) {
12929 context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
12930 }
12931 }
12932 return {
12933 slotName,
12934 slotProps
12935 };
12936}
12937
12938const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;
12939const transformOn = (dir, node, context, augmentor) => {
12940 const { loc, modifiers, arg } = dir;
12941 if (!dir.exp && !modifiers.length) {
12942 context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));
12943 }
12944 let eventName;
12945 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
12946 if (arg.isStatic) {
12947 const rawName = arg.content;
12948 // for all event listeners, auto convert it to camelCase. See issue #2249
12949 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
12950 }
12951 else {
12952 // #2388
12953 eventName = createCompoundExpression([
12954 `${context.helperString(TO_HANDLER_KEY)}(`,
12955 arg,
12956 `)`
12957 ]);
12958 }
12959 }
12960 else {
12961 // already a compound expression.
12962 eventName = arg;
12963 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
12964 eventName.children.push(`)`);
12965 }
12966 // handler processing
12967 let exp = dir.exp;
12968 if (exp && !exp.content.trim()) {
12969 exp = undefined;
12970 }
12971 let shouldCache = context.cacheHandlers && !exp;
12972 if (exp) {
12973 const isMemberExp = isMemberExpression(exp.content);
12974 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
12975 const hasMultipleStatements = exp.content.includes(`;`);
12976 {
12977 validateBrowserExpression(exp, context, false, hasMultipleStatements);
12978 }
12979 if (isInlineStatement || (shouldCache && isMemberExp)) {
12980 // wrap inline statement in a function expression
12981 exp = createCompoundExpression([
12982 `${isInlineStatement
12983 ? `$event`
12984 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
12985 exp,
12986 hasMultipleStatements ? `}` : `)`
12987 ]);
12988 }
12989 }
12990 let ret = {
12991 props: [
12992 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
12993 ]
12994 };
12995 // apply extended compiler augmentor
12996 if (augmentor) {
12997 ret = augmentor(ret);
12998 }
12999 if (shouldCache) {
13000 // cache handlers so that it's always the same handler being passed down.
13001 // this avoids unnecessary re-renders when users use inline handlers on
13002 // components.
13003 ret.props[0].value = context.cache(ret.props[0].value);
13004 }
13005 return ret;
13006};
13007
13008// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
13009// codegen for the entire props object. This transform here is only for v-bind
13010// *with* args.
13011const transformBind = (dir, node, context) => {
13012 const { exp, modifiers, loc } = dir;
13013 const arg = dir.arg;
13014 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
13015 arg.children.unshift(`(`);
13016 arg.children.push(`) || ""`);
13017 }
13018 else if (!arg.isStatic) {
13019 arg.content = `${arg.content} || ""`;
13020 }
13021 // .prop is no longer necessary due to new patch behavior
13022 // .sync is replaced by v-model:arg
13023 if (modifiers.includes('camel')) {
13024 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
13025 if (arg.isStatic) {
13026 arg.content = camelize(arg.content);
13027 }
13028 else {
13029 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
13030 }
13031 }
13032 else {
13033 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
13034 arg.children.push(`)`);
13035 }
13036 }
13037 if (!exp ||
13038 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
13039 context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));
13040 return {
13041 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
13042 };
13043 }
13044 return {
13045 props: [createObjectProperty(arg, exp)]
13046 };
13047};
13048
13049// Merge adjacent text nodes and expressions into a single expression
13050// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
13051const transformText = (node, context) => {
13052 if (node.type === 0 /* ROOT */ ||
13053 node.type === 1 /* ELEMENT */ ||
13054 node.type === 11 /* FOR */ ||
13055 node.type === 10 /* IF_BRANCH */) {
13056 // perform the transform on node exit so that all expressions have already
13057 // been processed.
13058 return () => {
13059 const children = node.children;
13060 let currentContainer = undefined;
13061 let hasText = false;
13062 for (let i = 0; i < children.length; i++) {
13063 const child = children[i];
13064 if (isText(child)) {
13065 hasText = true;
13066 for (let j = i + 1; j < children.length; j++) {
13067 const next = children[j];
13068 if (isText(next)) {
13069 if (!currentContainer) {
13070 currentContainer = children[i] = {
13071 type: 8 /* COMPOUND_EXPRESSION */,
13072 loc: child.loc,
13073 children: [child]
13074 };
13075 }
13076 // merge adjacent text node into current
13077 currentContainer.children.push(` + `, next);
13078 children.splice(j, 1);
13079 j--;
13080 }
13081 else {
13082 currentContainer = undefined;
13083 break;
13084 }
13085 }
13086 }
13087 }
13088 if (!hasText ||
13089 // if this is a plain element with a single text child, leave it
13090 // as-is since the runtime has dedicated fast path for this by directly
13091 // setting textContent of the element.
13092 // for component root it's always normalized anyway.
13093 (children.length === 1 &&
13094 (node.type === 0 /* ROOT */ ||
13095 (node.type === 1 /* ELEMENT */ &&
13096 node.tagType === 0 /* ELEMENT */)))) {
13097 return;
13098 }
13099 // pre-convert text nodes into createTextVNode(text) calls to avoid
13100 // runtime normalization.
13101 for (let i = 0; i < children.length; i++) {
13102 const child = children[i];
13103 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
13104 const callArgs = [];
13105 // createTextVNode defaults to single whitespace, so if it is a
13106 // single space the code could be an empty call to save bytes.
13107 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
13108 callArgs.push(child);
13109 }
13110 // mark dynamic text with flag so it gets patched inside a block
13111 if (!context.ssr &&
13112 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
13113 callArgs.push(1 /* TEXT */ +
13114 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
13115 }
13116 children[i] = {
13117 type: 12 /* TEXT_CALL */,
13118 content: child,
13119 loc: child.loc,
13120 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
13121 };
13122 }
13123 }
13124 };
13125 }
13126};
13127
13128const seen = new WeakSet();
13129const transformOnce = (node, context) => {
13130 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
13131 if (seen.has(node)) {
13132 return;
13133 }
13134 seen.add(node);
13135 context.helper(SET_BLOCK_TRACKING);
13136 return () => {
13137 const cur = context.currentNode;
13138 if (cur.codegenNode) {
13139 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
13140 }
13141 };
13142 }
13143};
13144
13145const transformModel = (dir, node, context) => {
13146 const { exp, arg } = dir;
13147 if (!exp) {
13148 context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
13149 return createTransformProps();
13150 }
13151 const rawExp = exp.loc.source;
13152 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
13153 // im SFC <script setup> inline mode, the exp may have been transformed into
13154 // _unref(exp)
13155 context.bindingMetadata[rawExp];
13156 const maybeRef = !true /* SETUP_CONST */;
13157 if (!isMemberExpression(expString) && !maybeRef) {
13158 context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
13159 return createTransformProps();
13160 }
13161 const propName = arg ? arg : createSimpleExpression('modelValue', true);
13162 const eventName = arg
13163 ? isStaticExp(arg)
13164 ? `onUpdate:${arg.content}`
13165 : createCompoundExpression(['"onUpdate:" + ', arg])
13166 : `onUpdate:modelValue`;
13167 let assignmentExp;
13168 const eventArg = context.isTS ? `($event: any)` : `$event`;
13169 {
13170 assignmentExp = createCompoundExpression([
13171 `${eventArg} => (`,
13172 exp,
13173 ` = $event)`
13174 ]);
13175 }
13176 const props = [
13177 // modelValue: foo
13178 createObjectProperty(propName, dir.exp),
13179 // "onUpdate:modelValue": $event => (foo = $event)
13180 createObjectProperty(eventName, assignmentExp)
13181 ];
13182 // modelModifiers: { foo: true, "bar-baz": true }
13183 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
13184 const modifiers = dir.modifiers
13185 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
13186 .join(`, `);
13187 const modifiersKey = arg
13188 ? isStaticExp(arg)
13189 ? `${arg.content}Modifiers`
13190 : createCompoundExpression([arg, ' + "Modifiers"'])
13191 : `modelModifiers`;
13192 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
13193 }
13194 return createTransformProps(props);
13195};
13196function createTransformProps(props = []) {
13197 return { props };
13198}
13199
13200function getBaseTransformPreset(prefixIdentifiers) {
13201 return [
13202 [
13203 transformOnce,
13204 transformIf,
13205 transformFor,
13206 ...([transformExpression]
13207 ),
13208 transformSlotOutlet,
13209 transformElement,
13210 trackSlotScopes,
13211 transformText
13212 ],
13213 {
13214 on: transformOn,
13215 bind: transformBind,
13216 model: transformModel
13217 }
13218 ];
13219}
13220// we name it `baseCompile` so that higher order compilers like
13221// @vue/compiler-dom can export `compile` while re-exporting everything else.
13222function baseCompile(template, options = {}) {
13223 const onError = options.onError || defaultOnError;
13224 const isModuleMode = options.mode === 'module';
13225 /* istanbul ignore if */
13226 {
13227 if (options.prefixIdentifiers === true) {
13228 onError(createCompilerError(45 /* X_PREFIX_ID_NOT_SUPPORTED */));
13229 }
13230 else if (isModuleMode) {
13231 onError(createCompilerError(46 /* X_MODULE_MODE_NOT_SUPPORTED */));
13232 }
13233 }
13234 const prefixIdentifiers = !true ;
13235 if (options.cacheHandlers) {
13236 onError(createCompilerError(47 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
13237 }
13238 if (options.scopeId && !isModuleMode) {
13239 onError(createCompilerError(48 /* X_SCOPE_ID_NOT_SUPPORTED */));
13240 }
13241 const ast = isString(template) ? baseParse(template, options) : template;
13242 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
13243 transform(ast, extend({}, options, {
13244 prefixIdentifiers,
13245 nodeTransforms: [
13246 ...nodeTransforms,
13247 ...(options.nodeTransforms || []) // user transforms
13248 ],
13249 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
13250 )
13251 }));
13252 return generate(ast, extend({}, options, {
13253 prefixIdentifiers
13254 }));
13255}
13256
13257const noopDirectiveTransform = () => ({ props: [] });
13258
13259const V_MODEL_RADIO = Symbol(`vModelRadio` );
13260const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
13261const V_MODEL_TEXT = Symbol(`vModelText` );
13262const V_MODEL_SELECT = Symbol(`vModelSelect` );
13263const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
13264const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
13265const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
13266const V_SHOW = Symbol(`vShow` );
13267const TRANSITION$1 = Symbol(`Transition` );
13268const TRANSITION_GROUP = Symbol(`TransitionGroup` );
13269registerRuntimeHelpers({
13270 [V_MODEL_RADIO]: `vModelRadio`,
13271 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
13272 [V_MODEL_TEXT]: `vModelText`,
13273 [V_MODEL_SELECT]: `vModelSelect`,
13274 [V_MODEL_DYNAMIC]: `vModelDynamic`,
13275 [V_ON_WITH_MODIFIERS]: `withModifiers`,
13276 [V_ON_WITH_KEYS]: `withKeys`,
13277 [V_SHOW]: `vShow`,
13278 [TRANSITION$1]: `Transition`,
13279 [TRANSITION_GROUP]: `TransitionGroup`
13280});
13281
13282/* eslint-disable no-restricted-globals */
13283let decoder;
13284function decodeHtmlBrowser(raw) {
13285 (decoder || (decoder = document.createElement('div'))).innerHTML = raw;
13286 return decoder.textContent;
13287}
13288
13289const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
13290const parserOptions = {
13291 isVoidTag,
13292 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
13293 isPreTag: tag => tag === 'pre',
13294 decodeEntities: decodeHtmlBrowser ,
13295 isBuiltInComponent: (tag) => {
13296 if (isBuiltInType(tag, `Transition`)) {
13297 return TRANSITION$1;
13298 }
13299 else if (isBuiltInType(tag, `TransitionGroup`)) {
13300 return TRANSITION_GROUP;
13301 }
13302 },
13303 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
13304 getNamespace(tag, parent) {
13305 let ns = parent ? parent.ns : 0 /* HTML */;
13306 if (parent && ns === 2 /* MATH_ML */) {
13307 if (parent.tag === 'annotation-xml') {
13308 if (tag === 'svg') {
13309 return 1 /* SVG */;
13310 }
13311 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
13312 a.name === 'encoding' &&
13313 a.value != null &&
13314 (a.value.content === 'text/html' ||
13315 a.value.content === 'application/xhtml+xml'))) {
13316 ns = 0 /* HTML */;
13317 }
13318 }
13319 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
13320 tag !== 'mglyph' &&
13321 tag !== 'malignmark') {
13322 ns = 0 /* HTML */;
13323 }
13324 }
13325 else if (parent && ns === 1 /* SVG */) {
13326 if (parent.tag === 'foreignObject' ||
13327 parent.tag === 'desc' ||
13328 parent.tag === 'title') {
13329 ns = 0 /* HTML */;
13330 }
13331 }
13332 if (ns === 0 /* HTML */) {
13333 if (tag === 'svg') {
13334 return 1 /* SVG */;
13335 }
13336 if (tag === 'math') {
13337 return 2 /* MATH_ML */;
13338 }
13339 }
13340 return ns;
13341 },
13342 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
13343 getTextMode({ tag, ns }) {
13344 if (ns === 0 /* HTML */) {
13345 if (tag === 'textarea' || tag === 'title') {
13346 return 1 /* RCDATA */;
13347 }
13348 if (isRawTextContainer(tag)) {
13349 return 2 /* RAWTEXT */;
13350 }
13351 }
13352 return 0 /* DATA */;
13353 }
13354};
13355
13356// Parse inline CSS strings for static style attributes into an object.
13357// This is a NodeTransform since it works on the static `style` attribute and
13358// converts it into a dynamic equivalent:
13359// style="color: red" -> :style='{ "color": "red" }'
13360// It is then processed by `transformElement` and included in the generated
13361// props.
13362const transformStyle = node => {
13363 if (node.type === 1 /* ELEMENT */) {
13364 node.props.forEach((p, i) => {
13365 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
13366 // replace p with an expression node
13367 node.props[i] = {
13368 type: 7 /* DIRECTIVE */,
13369 name: `bind`,
13370 arg: createSimpleExpression(`style`, true, p.loc),
13371 exp: parseInlineCSS(p.value.content, p.loc),
13372 modifiers: [],
13373 loc: p.loc
13374 };
13375 }
13376 });
13377 }
13378};
13379const parseInlineCSS = (cssText, loc) => {
13380 const normalized = parseStringStyle(cssText);
13381 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
13382};
13383
13384function createDOMCompilerError(code, loc) {
13385 return createCompilerError(code, loc, DOMErrorMessages );
13386}
13387const DOMErrorMessages = {
13388 [49 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
13389 [50 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
13390 [51 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
13391 [52 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
13392 [53 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
13393 [54 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
13394 [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.`,
13395 [56 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
13396 [57 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
13397 [58 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
13398 [59 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
13399};
13400
13401const transformVHtml = (dir, node, context) => {
13402 const { exp, loc } = dir;
13403 if (!exp) {
13404 context.onError(createDOMCompilerError(49 /* X_V_HTML_NO_EXPRESSION */, loc));
13405 }
13406 if (node.children.length) {
13407 context.onError(createDOMCompilerError(50 /* X_V_HTML_WITH_CHILDREN */, loc));
13408 node.children.length = 0;
13409 }
13410 return {
13411 props: [
13412 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
13413 ]
13414 };
13415};
13416
13417const transformVText = (dir, node, context) => {
13418 const { exp, loc } = dir;
13419 if (!exp) {
13420 context.onError(createDOMCompilerError(51 /* X_V_TEXT_NO_EXPRESSION */, loc));
13421 }
13422 if (node.children.length) {
13423 context.onError(createDOMCompilerError(52 /* X_V_TEXT_WITH_CHILDREN */, loc));
13424 node.children.length = 0;
13425 }
13426 return {
13427 props: [
13428 createObjectProperty(createSimpleExpression(`textContent`, true), exp
13429 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
13430 : createSimpleExpression('', true))
13431 ]
13432 };
13433};
13434
13435const transformModel$1 = (dir, node, context) => {
13436 const baseResult = transformModel(dir, node, context);
13437 // base transform has errors OR component v-model (only need props)
13438 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
13439 return baseResult;
13440 }
13441 if (dir.arg) {
13442 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
13443 }
13444 function checkDuplicatedValue() {
13445 const value = findProp(node, 'value');
13446 if (value) {
13447 context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
13448 }
13449 }
13450 const { tag } = node;
13451 const isCustomElement = context.isCustomElement(tag);
13452 if (tag === 'input' ||
13453 tag === 'textarea' ||
13454 tag === 'select' ||
13455 isCustomElement) {
13456 let directiveToUse = V_MODEL_TEXT;
13457 let isInvalidType = false;
13458 if (tag === 'input' || isCustomElement) {
13459 const type = findProp(node, `type`);
13460 if (type) {
13461 if (type.type === 7 /* DIRECTIVE */) {
13462 // :type="foo"
13463 directiveToUse = V_MODEL_DYNAMIC;
13464 }
13465 else if (type.value) {
13466 switch (type.value.content) {
13467 case 'radio':
13468 directiveToUse = V_MODEL_RADIO;
13469 break;
13470 case 'checkbox':
13471 directiveToUse = V_MODEL_CHECKBOX;
13472 break;
13473 case 'file':
13474 isInvalidType = true;
13475 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
13476 break;
13477 default:
13478 // text type
13479 checkDuplicatedValue();
13480 break;
13481 }
13482 }
13483 }
13484 else if (hasDynamicKeyVBind(node)) {
13485 // element has bindings with dynamic keys, which can possibly contain
13486 // "type".
13487 directiveToUse = V_MODEL_DYNAMIC;
13488 }
13489 else {
13490 // text type
13491 checkDuplicatedValue();
13492 }
13493 }
13494 else if (tag === 'select') {
13495 directiveToUse = V_MODEL_SELECT;
13496 }
13497 else {
13498 // textarea
13499 checkDuplicatedValue();
13500 }
13501 // inject runtime directive
13502 // by returning the helper symbol via needRuntime
13503 // the import will replaced a resolveDirective call.
13504 if (!isInvalidType) {
13505 baseResult.needRuntime = context.helper(directiveToUse);
13506 }
13507 }
13508 else {
13509 context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
13510 }
13511 // native vmodel doesn't need the `modelValue` props since they are also
13512 // passed to the runtime as `binding.value`. removing it reduces code size.
13513 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
13514 p.key.content === 'modelValue'));
13515 return baseResult;
13516};
13517
13518const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
13519const isNonKeyModifier = /*#__PURE__*/ makeMap(
13520// event propagation management
13521`stop,prevent,self,` +
13522 // system modifiers + exact
13523 `ctrl,shift,alt,meta,exact,` +
13524 // mouse
13525 `middle`);
13526// left & right could be mouse or key modifiers based on event type
13527const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
13528const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
13529const resolveModifiers = (key, modifiers) => {
13530 const keyModifiers = [];
13531 const nonKeyModifiers = [];
13532 const eventOptionModifiers = [];
13533 for (let i = 0; i < modifiers.length; i++) {
13534 const modifier = modifiers[i];
13535 if (isEventOptionModifier(modifier)) {
13536 // eventOptionModifiers: modifiers for addEventListener() options,
13537 // e.g. .passive & .capture
13538 eventOptionModifiers.push(modifier);
13539 }
13540 else {
13541 // runtimeModifiers: modifiers that needs runtime guards
13542 if (maybeKeyModifier(modifier)) {
13543 if (isStaticExp(key)) {
13544 if (isKeyboardEvent(key.content)) {
13545 keyModifiers.push(modifier);
13546 }
13547 else {
13548 nonKeyModifiers.push(modifier);
13549 }
13550 }
13551 else {
13552 keyModifiers.push(modifier);
13553 nonKeyModifiers.push(modifier);
13554 }
13555 }
13556 else {
13557 if (isNonKeyModifier(modifier)) {
13558 nonKeyModifiers.push(modifier);
13559 }
13560 else {
13561 keyModifiers.push(modifier);
13562 }
13563 }
13564 }
13565 }
13566 return {
13567 keyModifiers,
13568 nonKeyModifiers,
13569 eventOptionModifiers
13570 };
13571};
13572const transformClick = (key, event) => {
13573 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
13574 return isStaticClick
13575 ? createSimpleExpression(event, true)
13576 : key.type !== 4 /* SIMPLE_EXPRESSION */
13577 ? createCompoundExpression([
13578 `(`,
13579 key,
13580 `) === "onClick" ? "${event}" : (`,
13581 key,
13582 `)`
13583 ])
13584 : key;
13585};
13586const transformOn$1 = (dir, node, context) => {
13587 return transformOn(dir, node, context, baseResult => {
13588 const { modifiers } = dir;
13589 if (!modifiers.length)
13590 return baseResult;
13591 let { key, value: handlerExp } = baseResult.props[0];
13592 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers);
13593 // normalize click.right and click.middle since they don't actually fire
13594 if (nonKeyModifiers.includes('right')) {
13595 key = transformClick(key, `onContextmenu`);
13596 }
13597 if (nonKeyModifiers.includes('middle')) {
13598 key = transformClick(key, `onMouseup`);
13599 }
13600 if (nonKeyModifiers.length) {
13601 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
13602 handlerExp,
13603 JSON.stringify(nonKeyModifiers)
13604 ]);
13605 }
13606 if (keyModifiers.length &&
13607 // if event name is dynamic, always wrap with keys guard
13608 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
13609 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
13610 handlerExp,
13611 JSON.stringify(keyModifiers)
13612 ]);
13613 }
13614 if (eventOptionModifiers.length) {
13615 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
13616 key = isStaticExp(key)
13617 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
13618 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
13619 }
13620 return {
13621 props: [createObjectProperty(key, handlerExp)]
13622 };
13623 });
13624};
13625
13626const transformShow = (dir, node, context) => {
13627 const { exp, loc } = dir;
13628 if (!exp) {
13629 context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */, loc));
13630 }
13631 return {
13632 props: [],
13633 needRuntime: context.helper(V_SHOW)
13634 };
13635};
13636
13637const warnTransitionChildren = (node, context) => {
13638 if (node.type === 1 /* ELEMENT */ &&
13639 node.tagType === 1 /* COMPONENT */) {
13640 const component = context.isBuiltInComponent(node.tag);
13641 if (component === TRANSITION$1) {
13642 return () => {
13643 if (node.children.length && hasMultipleChildren(node)) {
13644 context.onError(createDOMCompilerError(58 /* X_TRANSITION_INVALID_CHILDREN */, {
13645 start: node.children[0].loc.start,
13646 end: node.children[node.children.length - 1].loc.end,
13647 source: ''
13648 }));
13649 }
13650 };
13651 }
13652 }
13653};
13654function hasMultipleChildren(node) {
13655 // #1352 filter out potential comment nodes.
13656 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */));
13657 const child = children[0];
13658 return (children.length !== 1 ||
13659 child.type === 11 /* FOR */ ||
13660 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
13661}
13662
13663const ignoreSideEffectTags = (node, context) => {
13664 if (node.type === 1 /* ELEMENT */ &&
13665 node.tagType === 0 /* ELEMENT */ &&
13666 (node.tag === 'script' || node.tag === 'style')) {
13667 context.onError(createDOMCompilerError(59 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
13668 context.removeNode();
13669 }
13670};
13671
13672const DOMNodeTransforms = [
13673 transformStyle,
13674 ...([warnTransitionChildren] )
13675];
13676const DOMDirectiveTransforms = {
13677 cloak: noopDirectiveTransform,
13678 html: transformVHtml,
13679 text: transformVText,
13680 model: transformModel$1,
13681 on: transformOn$1,
13682 show: transformShow
13683};
13684function compile$1(template, options = {}) {
13685 return baseCompile(template, extend({}, parserOptions, options, {
13686 nodeTransforms: [
13687 // ignore <script> and <tag>
13688 // this is not put inside DOMNodeTransforms because that list is used
13689 // by compiler-ssr to generate vnode fallback branches
13690 ignoreSideEffectTags,
13691 ...DOMNodeTransforms,
13692 ...(options.nodeTransforms || [])
13693 ],
13694 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
13695 transformHoist: null
13696 }));
13697}
13698
13699// This entry is the "full-build" that includes both the runtime
13700{
13701 initDev();
13702}
13703const compileCache = Object.create(null);
13704function compileToFunction(template, options) {
13705 if (!isString(template)) {
13706 if (template.nodeType) {
13707 template = template.innerHTML;
13708 }
13709 else {
13710 warn(`invalid template option: `, template);
13711 return NOOP;
13712 }
13713 }
13714 const key = template;
13715 const cached = compileCache[key];
13716 if (cached) {
13717 return cached;
13718 }
13719 if (template[0] === '#') {
13720 const el = document.querySelector(template);
13721 if (!el) {
13722 warn(`Template element not found or is empty: ${template}`);
13723 }
13724 // __UNSAFE__
13725 // Reason: potential execution of JS expressions in in-DOM template.
13726 // The user must make sure the in-DOM template is trusted. If it's rendered
13727 // by the server, the template should not contain any user data.
13728 template = el ? el.innerHTML : ``;
13729 }
13730 const { code } = compile$1(template, extend({
13731 hoistStatic: true,
13732 onError(err) {
13733 {
13734 const message = `Template compilation error: ${err.message}`;
13735 const codeFrame = err.loc &&
13736 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
13737 warn(codeFrame ? `${message}\n${codeFrame}` : message);
13738 }
13739 }
13740 }, options));
13741 // The wildcard import results in a huge object with every export
13742 // with keys that cannot be mangled, and can be quite heavy size-wise.
13743 // In the global build we know `Vue` is available globally so we can avoid
13744 // the wildcard object.
13745 const render = (new Function('Vue', code)(runtimeDom));
13746 render._rc = true;
13747 return (compileCache[key] = render);
13748}
13749registerRuntimeCompiler(compileToFunction);
13750
13751export { 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 };