UNPKG

596 kBJavaScriptView Raw
1/**
2 * Make a map and return a function for checking if a key
3 * is in that map.
4 * IMPORTANT: all calls of this function must be prefixed with
5 * \/\*#\_\_PURE\_\_\*\/
6 * So that rollup can tree-shake them if necessary.
7 */
8function makeMap(str, expectsLowerCase) {
9 const map = Object.create(null);
10 const list = str.split(',');
11 for (let i = 0; i < list.length; i++) {
12 map[list[i]] = true;
13 }
14 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
15}
16
17/**
18 * dev only flag -> name mapping
19 */
20const PatchFlagNames = {
21 [1 /* TEXT */]: `TEXT`,
22 [2 /* CLASS */]: `CLASS`,
23 [4 /* STYLE */]: `STYLE`,
24 [8 /* PROPS */]: `PROPS`,
25 [16 /* FULL_PROPS */]: `FULL_PROPS`,
26 [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
27 [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
28 [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
29 [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
30 [512 /* NEED_PATCH */]: `NEED_PATCH`,
31 [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
32 [2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
33 [-1 /* HOISTED */]: `HOISTED`,
34 [-2 /* BAIL */]: `BAIL`
35};
36
37/**
38 * Dev only
39 */
40const slotFlagsText = {
41 [1 /* STABLE */]: 'STABLE',
42 [2 /* DYNAMIC */]: 'DYNAMIC',
43 [3 /* FORWARDED */]: 'FORWARDED'
44};
45
46const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
47 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
48 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
49const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
50
51const range = 2;
52function generateCodeFrame(source, start = 0, end = source.length) {
53 // Split the content into individual lines but capture the newline sequence
54 // that separated each line. This is important because the actual sequence is
55 // needed to properly take into account the full line length for offset
56 // comparison
57 let lines = source.split(/(\r?\n)/);
58 // Separate the lines and newline sequences into separate arrays for easier referencing
59 const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
60 lines = lines.filter((_, idx) => idx % 2 === 0);
61 let count = 0;
62 const res = [];
63 for (let i = 0; i < lines.length; i++) {
64 count +=
65 lines[i].length +
66 ((newlineSequences[i] && newlineSequences[i].length) || 0);
67 if (count >= start) {
68 for (let j = i - range; j <= i + range || end > count; j++) {
69 if (j < 0 || j >= lines.length)
70 continue;
71 const line = j + 1;
72 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
73 const lineLength = lines[j].length;
74 const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
75 if (j === i) {
76 // push underline
77 const pad = start - (count - (lineLength + newLineSeqLength));
78 const length = Math.max(1, end > count ? lineLength - pad : end - start);
79 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
80 }
81 else if (j > i) {
82 if (end > count) {
83 const length = Math.max(Math.min(end - count, lineLength), 1);
84 res.push(` | ` + '^'.repeat(length));
85 }
86 count += lineLength + newLineSeqLength;
87 }
88 }
89 break;
90 }
91 }
92 return res.join('\n');
93}
94
95/**
96 * On the client we only need to offer special cases for boolean attributes that
97 * have different names from their corresponding dom properties:
98 * - itemscope -> N/A
99 * - allowfullscreen -> allowFullscreen
100 * - formnovalidate -> formNoValidate
101 * - ismap -> isMap
102 * - nomodule -> noModule
103 * - novalidate -> noValidate
104 * - readonly -> readOnly
105 */
106const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
107const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
108/**
109 * Boolean attributes should be included if the value is truthy or ''.
110 * e.g. <select multiple> compiles to { multiple: '' }
111 */
112function includeBooleanAttr(value) {
113 return !!value || value === '';
114}
115
116function normalizeStyle(value) {
117 if (isArray(value)) {
118 const res = {};
119 for (let i = 0; i < value.length; i++) {
120 const item = value[i];
121 const normalized = isString(item)
122 ? parseStringStyle(item)
123 : normalizeStyle(item);
124 if (normalized) {
125 for (const key in normalized) {
126 res[key] = normalized[key];
127 }
128 }
129 }
130 return res;
131 }
132 else if (isString(value)) {
133 return value;
134 }
135 else if (isObject(value)) {
136 return value;
137 }
138}
139const listDelimiterRE = /;(?![^(]*\))/g;
140const propertyDelimiterRE = /:(.+)/;
141function parseStringStyle(cssText) {
142 const ret = {};
143 cssText.split(listDelimiterRE).forEach(item => {
144 if (item) {
145 const tmp = item.split(propertyDelimiterRE);
146 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
147 }
148 });
149 return ret;
150}
151function normalizeClass(value) {
152 let res = '';
153 if (isString(value)) {
154 res = value;
155 }
156 else if (isArray(value)) {
157 for (let i = 0; i < value.length; i++) {
158 const normalized = normalizeClass(value[i]);
159 if (normalized) {
160 res += normalized + ' ';
161 }
162 }
163 }
164 else if (isObject(value)) {
165 for (const name in value) {
166 if (value[name]) {
167 res += name + ' ';
168 }
169 }
170 }
171 return res.trim();
172}
173function normalizeProps(props) {
174 if (!props)
175 return null;
176 let { class: klass, style } = props;
177 if (klass && !isString(klass)) {
178 props.class = normalizeClass(klass);
179 }
180 if (style) {
181 props.style = normalizeStyle(style);
182 }
183 return props;
184}
185
186// These tag configs are shared between compiler-dom and runtime-dom, so they
187// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
188const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
189 'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
190 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
191 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
192 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
193 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
194 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
195 'option,output,progress,select,textarea,details,dialog,menu,' +
196 'summary,template,blockquote,iframe,tfoot';
197// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
198const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
199 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
200 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
201 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
202 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
203 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
204 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
205 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
206 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
207 'text,textPath,title,tspan,unknown,use,view';
208const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
209const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
210const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
211const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
212
213function looseCompareArrays(a, b) {
214 if (a.length !== b.length)
215 return false;
216 let equal = true;
217 for (let i = 0; equal && i < a.length; i++) {
218 equal = looseEqual(a[i], b[i]);
219 }
220 return equal;
221}
222function looseEqual(a, b) {
223 if (a === b)
224 return true;
225 let aValidType = isDate(a);
226 let bValidType = isDate(b);
227 if (aValidType || bValidType) {
228 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
229 }
230 aValidType = isArray(a);
231 bValidType = isArray(b);
232 if (aValidType || bValidType) {
233 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
234 }
235 aValidType = isObject(a);
236 bValidType = isObject(b);
237 if (aValidType || bValidType) {
238 /* istanbul ignore if: this if will probably never be called */
239 if (!aValidType || !bValidType) {
240 return false;
241 }
242 const aKeysCount = Object.keys(a).length;
243 const bKeysCount = Object.keys(b).length;
244 if (aKeysCount !== bKeysCount) {
245 return false;
246 }
247 for (const key in a) {
248 const aHasKey = a.hasOwnProperty(key);
249 const bHasKey = b.hasOwnProperty(key);
250 if ((aHasKey && !bHasKey) ||
251 (!aHasKey && bHasKey) ||
252 !looseEqual(a[key], b[key])) {
253 return false;
254 }
255 }
256 }
257 return String(a) === String(b);
258}
259function looseIndexOf(arr, val) {
260 return arr.findIndex(item => looseEqual(item, val));
261}
262
263/**
264 * For converting {{ interpolation }} values to displayed strings.
265 * @private
266 */
267const toDisplayString = (val) => {
268 return val == null
269 ? ''
270 : isArray(val) ||
271 (isObject(val) &&
272 (val.toString === objectToString || !isFunction(val.toString)))
273 ? JSON.stringify(val, replacer, 2)
274 : String(val);
275};
276const replacer = (_key, val) => {
277 // can't use isRef here since @vue/shared has no deps
278 if (val && val.__v_isRef) {
279 return replacer(_key, val.value);
280 }
281 else if (isMap(val)) {
282 return {
283 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
284 entries[`${key} =>`] = val;
285 return entries;
286 }, {})
287 };
288 }
289 else if (isSet(val)) {
290 return {
291 [`Set(${val.size})`]: [...val.values()]
292 };
293 }
294 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
295 return String(val);
296 }
297 return val;
298};
299
300const EMPTY_OBJ = Object.freeze({})
301 ;
302const EMPTY_ARR = Object.freeze([]) ;
303const NOOP = () => { };
304/**
305 * Always return false.
306 */
307const NO = () => false;
308const onRE = /^on[^a-z]/;
309const isOn = (key) => onRE.test(key);
310const isModelListener = (key) => key.startsWith('onUpdate:');
311const extend = Object.assign;
312const remove = (arr, el) => {
313 const i = arr.indexOf(el);
314 if (i > -1) {
315 arr.splice(i, 1);
316 }
317};
318const hasOwnProperty = Object.prototype.hasOwnProperty;
319const hasOwn = (val, key) => hasOwnProperty.call(val, key);
320const isArray = Array.isArray;
321const isMap = (val) => toTypeString(val) === '[object Map]';
322const isSet = (val) => toTypeString(val) === '[object Set]';
323const isDate = (val) => val instanceof Date;
324const isFunction = (val) => typeof val === 'function';
325const isString = (val) => typeof val === 'string';
326const isSymbol = (val) => typeof val === 'symbol';
327const isObject = (val) => val !== null && typeof val === 'object';
328const isPromise = (val) => {
329 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
330};
331const objectToString = Object.prototype.toString;
332const toTypeString = (value) => objectToString.call(value);
333const toRawType = (value) => {
334 // extract "RawType" from strings like "[object RawType]"
335 return toTypeString(value).slice(8, -1);
336};
337const isPlainObject = (val) => toTypeString(val) === '[object Object]';
338const isIntegerKey = (key) => isString(key) &&
339 key !== 'NaN' &&
340 key[0] !== '-' &&
341 '' + parseInt(key, 10) === key;
342const isReservedProp = /*#__PURE__*/ makeMap(
343// the leading comma is intentional so empty string "" is also included
344',key,ref,' +
345 'onVnodeBeforeMount,onVnodeMounted,' +
346 'onVnodeBeforeUpdate,onVnodeUpdated,' +
347 'onVnodeBeforeUnmount,onVnodeUnmounted');
348const cacheStringFunction = (fn) => {
349 const cache = Object.create(null);
350 return ((str) => {
351 const hit = cache[str];
352 return hit || (cache[str] = fn(str));
353 });
354};
355const camelizeRE = /-(\w)/g;
356/**
357 * @private
358 */
359const camelize = cacheStringFunction((str) => {
360 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
361});
362const hyphenateRE = /\B([A-Z])/g;
363/**
364 * @private
365 */
366const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
367/**
368 * @private
369 */
370const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
371/**
372 * @private
373 */
374const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
375// compare whether a value has changed, accounting for NaN.
376const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
377const invokeArrayFns = (fns, arg) => {
378 for (let i = 0; i < fns.length; i++) {
379 fns[i](arg);
380 }
381};
382const def = (obj, key, value) => {
383 Object.defineProperty(obj, key, {
384 configurable: true,
385 enumerable: false,
386 value
387 });
388};
389const toNumber = (val) => {
390 const n = parseFloat(val);
391 return isNaN(n) ? val : n;
392};
393let _globalThis;
394const getGlobalThis = () => {
395 return (_globalThis ||
396 (_globalThis =
397 typeof globalThis !== 'undefined'
398 ? globalThis
399 : typeof self !== 'undefined'
400 ? self
401 : typeof window !== 'undefined'
402 ? window
403 : typeof global !== 'undefined'
404 ? global
405 : {}));
406};
407
408function warn(msg, ...args) {
409 console.warn(`[Vue warn] ${msg}`, ...args);
410}
411
412let activeEffectScope;
413const effectScopeStack = [];
414class EffectScope {
415 constructor(detached = false) {
416 this.active = true;
417 this.effects = [];
418 this.cleanups = [];
419 if (!detached && activeEffectScope) {
420 this.parent = activeEffectScope;
421 this.index =
422 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
423 }
424 }
425 run(fn) {
426 if (this.active) {
427 try {
428 this.on();
429 return fn();
430 }
431 finally {
432 this.off();
433 }
434 }
435 else {
436 warn(`cannot run an inactive effect scope.`);
437 }
438 }
439 on() {
440 if (this.active) {
441 effectScopeStack.push(this);
442 activeEffectScope = this;
443 }
444 }
445 off() {
446 if (this.active) {
447 effectScopeStack.pop();
448 activeEffectScope = effectScopeStack[effectScopeStack.length - 1];
449 }
450 }
451 stop(fromParent) {
452 if (this.active) {
453 this.effects.forEach(e => e.stop());
454 this.cleanups.forEach(cleanup => cleanup());
455 if (this.scopes) {
456 this.scopes.forEach(e => e.stop(true));
457 }
458 // nested scope, dereference from parent to avoid memory leaks
459 if (this.parent && !fromParent) {
460 // optimized O(1) removal
461 const last = this.parent.scopes.pop();
462 if (last && last !== this) {
463 this.parent.scopes[this.index] = last;
464 last.index = this.index;
465 }
466 }
467 this.active = false;
468 }
469 }
470}
471function effectScope(detached) {
472 return new EffectScope(detached);
473}
474function recordEffectScope(effect, scope) {
475 scope = scope || activeEffectScope;
476 if (scope && scope.active) {
477 scope.effects.push(effect);
478 }
479}
480function getCurrentScope() {
481 return activeEffectScope;
482}
483function onScopeDispose(fn) {
484 if (activeEffectScope) {
485 activeEffectScope.cleanups.push(fn);
486 }
487 else {
488 warn(`onScopeDispose() is called when there is no active effect scope` +
489 ` to be associated with.`);
490 }
491}
492
493const createDep = (effects) => {
494 const dep = new Set(effects);
495 dep.w = 0;
496 dep.n = 0;
497 return dep;
498};
499const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
500const newTracked = (dep) => (dep.n & trackOpBit) > 0;
501const initDepMarkers = ({ deps }) => {
502 if (deps.length) {
503 for (let i = 0; i < deps.length; i++) {
504 deps[i].w |= trackOpBit; // set was tracked
505 }
506 }
507};
508const finalizeDepMarkers = (effect) => {
509 const { deps } = effect;
510 if (deps.length) {
511 let ptr = 0;
512 for (let i = 0; i < deps.length; i++) {
513 const dep = deps[i];
514 if (wasTracked(dep) && !newTracked(dep)) {
515 dep.delete(effect);
516 }
517 else {
518 deps[ptr++] = dep;
519 }
520 // clear bits
521 dep.w &= ~trackOpBit;
522 dep.n &= ~trackOpBit;
523 }
524 deps.length = ptr;
525 }
526};
527
528const targetMap = new WeakMap();
529// The number of effects currently being tracked recursively.
530let effectTrackDepth = 0;
531let trackOpBit = 1;
532/**
533 * The bitwise track markers support at most 30 levels op recursion.
534 * This value is chosen to enable modern JS engines to use a SMI on all platforms.
535 * When recursion depth is greater, fall back to using a full cleanup.
536 */
537const maxMarkerBits = 30;
538const effectStack = [];
539let activeEffect;
540const ITERATE_KEY = Symbol('iterate' );
541const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
542class ReactiveEffect {
543 constructor(fn, scheduler = null, scope) {
544 this.fn = fn;
545 this.scheduler = scheduler;
546 this.active = true;
547 this.deps = [];
548 recordEffectScope(this, scope);
549 }
550 run() {
551 if (!this.active) {
552 return this.fn();
553 }
554 if (!effectStack.includes(this)) {
555 try {
556 effectStack.push((activeEffect = this));
557 enableTracking();
558 trackOpBit = 1 << ++effectTrackDepth;
559 if (effectTrackDepth <= maxMarkerBits) {
560 initDepMarkers(this);
561 }
562 else {
563 cleanupEffect(this);
564 }
565 return this.fn();
566 }
567 finally {
568 if (effectTrackDepth <= maxMarkerBits) {
569 finalizeDepMarkers(this);
570 }
571 trackOpBit = 1 << --effectTrackDepth;
572 resetTracking();
573 effectStack.pop();
574 const n = effectStack.length;
575 activeEffect = n > 0 ? effectStack[n - 1] : undefined;
576 }
577 }
578 }
579 stop() {
580 if (this.active) {
581 cleanupEffect(this);
582 if (this.onStop) {
583 this.onStop();
584 }
585 this.active = false;
586 }
587 }
588}
589function cleanupEffect(effect) {
590 const { deps } = effect;
591 if (deps.length) {
592 for (let i = 0; i < deps.length; i++) {
593 deps[i].delete(effect);
594 }
595 deps.length = 0;
596 }
597}
598function effect(fn, options) {
599 if (fn.effect) {
600 fn = fn.effect.fn;
601 }
602 const _effect = new ReactiveEffect(fn);
603 if (options) {
604 extend(_effect, options);
605 if (options.scope)
606 recordEffectScope(_effect, options.scope);
607 }
608 if (!options || !options.lazy) {
609 _effect.run();
610 }
611 const runner = _effect.run.bind(_effect);
612 runner.effect = _effect;
613 return runner;
614}
615function stop(runner) {
616 runner.effect.stop();
617}
618let shouldTrack = true;
619const trackStack = [];
620function pauseTracking() {
621 trackStack.push(shouldTrack);
622 shouldTrack = false;
623}
624function enableTracking() {
625 trackStack.push(shouldTrack);
626 shouldTrack = true;
627}
628function resetTracking() {
629 const last = trackStack.pop();
630 shouldTrack = last === undefined ? true : last;
631}
632function track(target, type, key) {
633 if (!isTracking()) {
634 return;
635 }
636 let depsMap = targetMap.get(target);
637 if (!depsMap) {
638 targetMap.set(target, (depsMap = new Map()));
639 }
640 let dep = depsMap.get(key);
641 if (!dep) {
642 depsMap.set(key, (dep = createDep()));
643 }
644 const eventInfo = { effect: activeEffect, target, type, key }
645 ;
646 trackEffects(dep, eventInfo);
647}
648function isTracking() {
649 return shouldTrack && activeEffect !== undefined;
650}
651function trackEffects(dep, debuggerEventExtraInfo) {
652 let shouldTrack = false;
653 if (effectTrackDepth <= maxMarkerBits) {
654 if (!newTracked(dep)) {
655 dep.n |= trackOpBit; // set newly tracked
656 shouldTrack = !wasTracked(dep);
657 }
658 }
659 else {
660 // Full cleanup mode.
661 shouldTrack = !dep.has(activeEffect);
662 }
663 if (shouldTrack) {
664 dep.add(activeEffect);
665 activeEffect.deps.push(dep);
666 if (activeEffect.onTrack) {
667 activeEffect.onTrack(Object.assign({
668 effect: activeEffect
669 }, debuggerEventExtraInfo));
670 }
671 }
672}
673function trigger(target, type, key, newValue, oldValue, oldTarget) {
674 const depsMap = targetMap.get(target);
675 if (!depsMap) {
676 // never been tracked
677 return;
678 }
679 let deps = [];
680 if (type === "clear" /* CLEAR */) {
681 // collection being cleared
682 // trigger all effects for target
683 deps = [...depsMap.values()];
684 }
685 else if (key === 'length' && isArray(target)) {
686 depsMap.forEach((dep, key) => {
687 if (key === 'length' || key >= newValue) {
688 deps.push(dep);
689 }
690 });
691 }
692 else {
693 // schedule runs for SET | ADD | DELETE
694 if (key !== void 0) {
695 deps.push(depsMap.get(key));
696 }
697 // also run for iteration key on ADD | DELETE | Map.SET
698 switch (type) {
699 case "add" /* ADD */:
700 if (!isArray(target)) {
701 deps.push(depsMap.get(ITERATE_KEY));
702 if (isMap(target)) {
703 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
704 }
705 }
706 else if (isIntegerKey(key)) {
707 // new index added to array -> length changes
708 deps.push(depsMap.get('length'));
709 }
710 break;
711 case "delete" /* DELETE */:
712 if (!isArray(target)) {
713 deps.push(depsMap.get(ITERATE_KEY));
714 if (isMap(target)) {
715 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
716 }
717 }
718 break;
719 case "set" /* SET */:
720 if (isMap(target)) {
721 deps.push(depsMap.get(ITERATE_KEY));
722 }
723 break;
724 }
725 }
726 const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
727 ;
728 if (deps.length === 1) {
729 if (deps[0]) {
730 {
731 triggerEffects(deps[0], eventInfo);
732 }
733 }
734 }
735 else {
736 const effects = [];
737 for (const dep of deps) {
738 if (dep) {
739 effects.push(...dep);
740 }
741 }
742 {
743 triggerEffects(createDep(effects), eventInfo);
744 }
745 }
746}
747function triggerEffects(dep, debuggerEventExtraInfo) {
748 // spread into array for stabilization
749 for (const effect of isArray(dep) ? dep : [...dep]) {
750 if (effect !== activeEffect || effect.allowRecurse) {
751 if (effect.onTrigger) {
752 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
753 }
754 if (effect.scheduler) {
755 effect.scheduler();
756 }
757 else {
758 effect.run();
759 }
760 }
761 }
762}
763
764const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
765const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
766 .map(key => Symbol[key])
767 .filter(isSymbol));
768const get = /*#__PURE__*/ createGetter();
769const shallowGet = /*#__PURE__*/ createGetter(false, true);
770const readonlyGet = /*#__PURE__*/ createGetter(true);
771const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
772const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
773function createArrayInstrumentations() {
774 const instrumentations = {};
775 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
776 instrumentations[key] = function (...args) {
777 const arr = toRaw(this);
778 for (let i = 0, l = this.length; i < l; i++) {
779 track(arr, "get" /* GET */, i + '');
780 }
781 // we run the method using the original args first (which may be reactive)
782 const res = arr[key](...args);
783 if (res === -1 || res === false) {
784 // if that didn't work, run it again using raw values.
785 return arr[key](...args.map(toRaw));
786 }
787 else {
788 return res;
789 }
790 };
791 });
792 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
793 instrumentations[key] = function (...args) {
794 pauseTracking();
795 const res = toRaw(this)[key].apply(this, args);
796 resetTracking();
797 return res;
798 };
799 });
800 return instrumentations;
801}
802function createGetter(isReadonly = false, shallow = false) {
803 return function get(target, key, receiver) {
804 if (key === "__v_isReactive" /* IS_REACTIVE */) {
805 return !isReadonly;
806 }
807 else if (key === "__v_isReadonly" /* IS_READONLY */) {
808 return isReadonly;
809 }
810 else if (key === "__v_raw" /* RAW */ &&
811 receiver ===
812 (isReadonly
813 ? shallow
814 ? shallowReadonlyMap
815 : readonlyMap
816 : shallow
817 ? shallowReactiveMap
818 : reactiveMap).get(target)) {
819 return target;
820 }
821 const targetIsArray = isArray(target);
822 if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
823 return Reflect.get(arrayInstrumentations, key, receiver);
824 }
825 const res = Reflect.get(target, key, receiver);
826 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
827 return res;
828 }
829 if (!isReadonly) {
830 track(target, "get" /* GET */, key);
831 }
832 if (shallow) {
833 return res;
834 }
835 if (isRef(res)) {
836 // ref unwrapping - does not apply for Array + integer key.
837 const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
838 return shouldUnwrap ? res.value : res;
839 }
840 if (isObject(res)) {
841 // Convert returned value into a proxy as well. we do the isObject check
842 // here to avoid invalid value warning. Also need to lazy access readonly
843 // and reactive here to avoid circular dependency.
844 return isReadonly ? readonly(res) : reactive(res);
845 }
846 return res;
847 };
848}
849const set = /*#__PURE__*/ createSetter();
850const shallowSet = /*#__PURE__*/ createSetter(true);
851function createSetter(shallow = false) {
852 return function set(target, key, value, receiver) {
853 let oldValue = target[key];
854 if (!shallow) {
855 value = toRaw(value);
856 oldValue = toRaw(oldValue);
857 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
858 oldValue.value = value;
859 return true;
860 }
861 }
862 const hadKey = isArray(target) && isIntegerKey(key)
863 ? Number(key) < target.length
864 : hasOwn(target, key);
865 const result = Reflect.set(target, key, value, receiver);
866 // don't trigger if target is something up in the prototype chain of original
867 if (target === toRaw(receiver)) {
868 if (!hadKey) {
869 trigger(target, "add" /* ADD */, key, value);
870 }
871 else if (hasChanged(value, oldValue)) {
872 trigger(target, "set" /* SET */, key, value, oldValue);
873 }
874 }
875 return result;
876 };
877}
878function deleteProperty(target, key) {
879 const hadKey = hasOwn(target, key);
880 const oldValue = target[key];
881 const result = Reflect.deleteProperty(target, key);
882 if (result && hadKey) {
883 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
884 }
885 return result;
886}
887function has(target, key) {
888 const result = Reflect.has(target, key);
889 if (!isSymbol(key) || !builtInSymbols.has(key)) {
890 track(target, "has" /* HAS */, key);
891 }
892 return result;
893}
894function ownKeys(target) {
895 track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
896 return Reflect.ownKeys(target);
897}
898const mutableHandlers = {
899 get,
900 set,
901 deleteProperty,
902 has,
903 ownKeys
904};
905const readonlyHandlers = {
906 get: readonlyGet,
907 set(target, key) {
908 {
909 console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
910 }
911 return true;
912 },
913 deleteProperty(target, key) {
914 {
915 console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
916 }
917 return true;
918 }
919};
920const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
921 get: shallowGet,
922 set: shallowSet
923});
924// Props handlers are special in the sense that it should not unwrap top-level
925// refs (in order to allow refs to be explicitly passed down), but should
926// retain the reactivity of the normal readonly object.
927const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
928 get: shallowReadonlyGet
929});
930
931const toShallow = (value) => value;
932const getProto = (v) => Reflect.getPrototypeOf(v);
933function get$1(target, key, isReadonly = false, isShallow = false) {
934 // #1772: readonly(reactive(Map)) should return readonly + reactive version
935 // of the value
936 target = target["__v_raw" /* RAW */];
937 const rawTarget = toRaw(target);
938 const rawKey = toRaw(key);
939 if (key !== rawKey) {
940 !isReadonly && track(rawTarget, "get" /* GET */, key);
941 }
942 !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
943 const { has } = getProto(rawTarget);
944 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
945 if (has.call(rawTarget, key)) {
946 return wrap(target.get(key));
947 }
948 else if (has.call(rawTarget, rawKey)) {
949 return wrap(target.get(rawKey));
950 }
951 else if (target !== rawTarget) {
952 // #3602 readonly(reactive(Map))
953 // ensure that the nested reactive `Map` can do tracking for itself
954 target.get(key);
955 }
956}
957function has$1(key, isReadonly = false) {
958 const target = this["__v_raw" /* RAW */];
959 const rawTarget = toRaw(target);
960 const rawKey = toRaw(key);
961 if (key !== rawKey) {
962 !isReadonly && track(rawTarget, "has" /* HAS */, key);
963 }
964 !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
965 return key === rawKey
966 ? target.has(key)
967 : target.has(key) || target.has(rawKey);
968}
969function size(target, isReadonly = false) {
970 target = target["__v_raw" /* RAW */];
971 !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
972 return Reflect.get(target, 'size', target);
973}
974function add(value) {
975 value = toRaw(value);
976 const target = toRaw(this);
977 const proto = getProto(target);
978 const hadKey = proto.has.call(target, value);
979 if (!hadKey) {
980 target.add(value);
981 trigger(target, "add" /* ADD */, value, value);
982 }
983 return this;
984}
985function set$1(key, value) {
986 value = toRaw(value);
987 const target = toRaw(this);
988 const { has, get } = getProto(target);
989 let hadKey = has.call(target, key);
990 if (!hadKey) {
991 key = toRaw(key);
992 hadKey = has.call(target, key);
993 }
994 else {
995 checkIdentityKeys(target, has, key);
996 }
997 const oldValue = get.call(target, key);
998 target.set(key, value);
999 if (!hadKey) {
1000 trigger(target, "add" /* ADD */, key, value);
1001 }
1002 else if (hasChanged(value, oldValue)) {
1003 trigger(target, "set" /* SET */, key, value, oldValue);
1004 }
1005 return this;
1006}
1007function deleteEntry(key) {
1008 const target = toRaw(this);
1009 const { has, get } = getProto(target);
1010 let hadKey = has.call(target, key);
1011 if (!hadKey) {
1012 key = toRaw(key);
1013 hadKey = has.call(target, key);
1014 }
1015 else {
1016 checkIdentityKeys(target, has, key);
1017 }
1018 const oldValue = get ? get.call(target, key) : undefined;
1019 // forward the operation before queueing reactions
1020 const result = target.delete(key);
1021 if (hadKey) {
1022 trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
1023 }
1024 return result;
1025}
1026function clear() {
1027 const target = toRaw(this);
1028 const hadItems = target.size !== 0;
1029 const oldTarget = isMap(target)
1030 ? new Map(target)
1031 : new Set(target)
1032 ;
1033 // forward the operation before queueing reactions
1034 const result = target.clear();
1035 if (hadItems) {
1036 trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
1037 }
1038 return result;
1039}
1040function createForEach(isReadonly, isShallow) {
1041 return function forEach(callback, thisArg) {
1042 const observed = this;
1043 const target = observed["__v_raw" /* RAW */];
1044 const rawTarget = toRaw(target);
1045 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1046 !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
1047 return target.forEach((value, key) => {
1048 // important: make sure the callback is
1049 // 1. invoked with the reactive map as `this` and 3rd arg
1050 // 2. the value received should be a corresponding reactive/readonly.
1051 return callback.call(thisArg, wrap(value), wrap(key), observed);
1052 });
1053 };
1054}
1055function createIterableMethod(method, isReadonly, isShallow) {
1056 return function (...args) {
1057 const target = this["__v_raw" /* RAW */];
1058 const rawTarget = toRaw(target);
1059 const targetIsMap = isMap(rawTarget);
1060 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
1061 const isKeyOnly = method === 'keys' && targetIsMap;
1062 const innerIterator = target[method](...args);
1063 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1064 !isReadonly &&
1065 track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
1066 // return a wrapped iterator which returns observed versions of the
1067 // values emitted from the real iterator
1068 return {
1069 // iterator protocol
1070 next() {
1071 const { value, done } = innerIterator.next();
1072 return done
1073 ? { value, done }
1074 : {
1075 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1076 done
1077 };
1078 },
1079 // iterable protocol
1080 [Symbol.iterator]() {
1081 return this;
1082 }
1083 };
1084 };
1085}
1086function createReadonlyMethod(type) {
1087 return function (...args) {
1088 {
1089 const key = args[0] ? `on key "${args[0]}" ` : ``;
1090 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
1091 }
1092 return type === "delete" /* DELETE */ ? false : this;
1093 };
1094}
1095function createInstrumentations() {
1096 const mutableInstrumentations = {
1097 get(key) {
1098 return get$1(this, key);
1099 },
1100 get size() {
1101 return size(this);
1102 },
1103 has: has$1,
1104 add,
1105 set: set$1,
1106 delete: deleteEntry,
1107 clear,
1108 forEach: createForEach(false, false)
1109 };
1110 const shallowInstrumentations = {
1111 get(key) {
1112 return get$1(this, key, false, true);
1113 },
1114 get size() {
1115 return size(this);
1116 },
1117 has: has$1,
1118 add,
1119 set: set$1,
1120 delete: deleteEntry,
1121 clear,
1122 forEach: createForEach(false, true)
1123 };
1124 const readonlyInstrumentations = {
1125 get(key) {
1126 return get$1(this, key, true);
1127 },
1128 get size() {
1129 return size(this, true);
1130 },
1131 has(key) {
1132 return has$1.call(this, key, true);
1133 },
1134 add: createReadonlyMethod("add" /* ADD */),
1135 set: createReadonlyMethod("set" /* SET */),
1136 delete: createReadonlyMethod("delete" /* DELETE */),
1137 clear: createReadonlyMethod("clear" /* CLEAR */),
1138 forEach: createForEach(true, false)
1139 };
1140 const shallowReadonlyInstrumentations = {
1141 get(key) {
1142 return get$1(this, key, true, true);
1143 },
1144 get size() {
1145 return size(this, true);
1146 },
1147 has(key) {
1148 return has$1.call(this, key, true);
1149 },
1150 add: createReadonlyMethod("add" /* ADD */),
1151 set: createReadonlyMethod("set" /* SET */),
1152 delete: createReadonlyMethod("delete" /* DELETE */),
1153 clear: createReadonlyMethod("clear" /* CLEAR */),
1154 forEach: createForEach(true, true)
1155 };
1156 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
1157 iteratorMethods.forEach(method => {
1158 mutableInstrumentations[method] = createIterableMethod(method, false, false);
1159 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
1160 shallowInstrumentations[method] = createIterableMethod(method, false, true);
1161 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
1162 });
1163 return [
1164 mutableInstrumentations,
1165 readonlyInstrumentations,
1166 shallowInstrumentations,
1167 shallowReadonlyInstrumentations
1168 ];
1169}
1170const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
1171function createInstrumentationGetter(isReadonly, shallow) {
1172 const instrumentations = shallow
1173 ? isReadonly
1174 ? shallowReadonlyInstrumentations
1175 : shallowInstrumentations
1176 : isReadonly
1177 ? readonlyInstrumentations
1178 : mutableInstrumentations;
1179 return (target, key, receiver) => {
1180 if (key === "__v_isReactive" /* IS_REACTIVE */) {
1181 return !isReadonly;
1182 }
1183 else if (key === "__v_isReadonly" /* IS_READONLY */) {
1184 return isReadonly;
1185 }
1186 else if (key === "__v_raw" /* RAW */) {
1187 return target;
1188 }
1189 return Reflect.get(hasOwn(instrumentations, key) && key in target
1190 ? instrumentations
1191 : target, key, receiver);
1192 };
1193}
1194const mutableCollectionHandlers = {
1195 get: /*#__PURE__*/ createInstrumentationGetter(false, false)
1196};
1197const shallowCollectionHandlers = {
1198 get: /*#__PURE__*/ createInstrumentationGetter(false, true)
1199};
1200const readonlyCollectionHandlers = {
1201 get: /*#__PURE__*/ createInstrumentationGetter(true, false)
1202};
1203const shallowReadonlyCollectionHandlers = {
1204 get: /*#__PURE__*/ createInstrumentationGetter(true, true)
1205};
1206function checkIdentityKeys(target, has, key) {
1207 const rawKey = toRaw(key);
1208 if (rawKey !== key && has.call(target, rawKey)) {
1209 const type = toRawType(target);
1210 console.warn(`Reactive ${type} contains both the raw and reactive ` +
1211 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
1212 `which can lead to inconsistencies. ` +
1213 `Avoid differentiating between the raw and reactive versions ` +
1214 `of an object and only use the reactive version if possible.`);
1215 }
1216}
1217
1218const reactiveMap = new WeakMap();
1219const shallowReactiveMap = new WeakMap();
1220const readonlyMap = new WeakMap();
1221const shallowReadonlyMap = new WeakMap();
1222function targetTypeMap(rawType) {
1223 switch (rawType) {
1224 case 'Object':
1225 case 'Array':
1226 return 1 /* COMMON */;
1227 case 'Map':
1228 case 'Set':
1229 case 'WeakMap':
1230 case 'WeakSet':
1231 return 2 /* COLLECTION */;
1232 default:
1233 return 0 /* INVALID */;
1234 }
1235}
1236function getTargetType(value) {
1237 return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
1238 ? 0 /* INVALID */
1239 : targetTypeMap(toRawType(value));
1240}
1241function reactive(target) {
1242 // if trying to observe a readonly proxy, return the readonly version.
1243 if (target && target["__v_isReadonly" /* IS_READONLY */]) {
1244 return target;
1245 }
1246 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1247}
1248/**
1249 * Return a shallowly-reactive copy of the original object, where only the root
1250 * level properties are reactive. It also does not auto-unwrap refs (even at the
1251 * root level).
1252 */
1253function shallowReactive(target) {
1254 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1255}
1256/**
1257 * Creates a readonly copy of the original object. Note the returned copy is not
1258 * made reactive, but `readonly` can be called on an already reactive object.
1259 */
1260function readonly(target) {
1261 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1262}
1263/**
1264 * Returns a reactive-copy of the original object, where only the root level
1265 * properties are readonly, and does NOT unwrap refs nor recursively convert
1266 * returned properties.
1267 * This is used for creating the props proxy object for stateful components.
1268 */
1269function shallowReadonly(target) {
1270 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1271}
1272function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1273 if (!isObject(target)) {
1274 {
1275 console.warn(`value cannot be made reactive: ${String(target)}`);
1276 }
1277 return target;
1278 }
1279 // target is already a Proxy, return it.
1280 // exception: calling readonly() on a reactive object
1281 if (target["__v_raw" /* RAW */] &&
1282 !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
1283 return target;
1284 }
1285 // target already has corresponding Proxy
1286 const existingProxy = proxyMap.get(target);
1287 if (existingProxy) {
1288 return existingProxy;
1289 }
1290 // only a whitelist of value types can be observed.
1291 const targetType = getTargetType(target);
1292 if (targetType === 0 /* INVALID */) {
1293 return target;
1294 }
1295 const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
1296 proxyMap.set(target, proxy);
1297 return proxy;
1298}
1299function isReactive(value) {
1300 if (isReadonly(value)) {
1301 return isReactive(value["__v_raw" /* RAW */]);
1302 }
1303 return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
1304}
1305function isReadonly(value) {
1306 return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1307}
1308function isProxy(value) {
1309 return isReactive(value) || isReadonly(value);
1310}
1311function toRaw(observed) {
1312 const raw = observed && observed["__v_raw" /* RAW */];
1313 return raw ? toRaw(raw) : observed;
1314}
1315function markRaw(value) {
1316 def(value, "__v_skip" /* SKIP */, true);
1317 return value;
1318}
1319const toReactive = (value) => isObject(value) ? reactive(value) : value;
1320const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1321
1322function trackRefValue(ref) {
1323 if (isTracking()) {
1324 ref = toRaw(ref);
1325 if (!ref.dep) {
1326 ref.dep = createDep();
1327 }
1328 {
1329 trackEffects(ref.dep, {
1330 target: ref,
1331 type: "get" /* GET */,
1332 key: 'value'
1333 });
1334 }
1335 }
1336}
1337function triggerRefValue(ref, newVal) {
1338 ref = toRaw(ref);
1339 if (ref.dep) {
1340 {
1341 triggerEffects(ref.dep, {
1342 target: ref,
1343 type: "set" /* SET */,
1344 key: 'value',
1345 newValue: newVal
1346 });
1347 }
1348 }
1349}
1350function isRef(r) {
1351 return Boolean(r && r.__v_isRef === true);
1352}
1353function ref(value) {
1354 return createRef(value, false);
1355}
1356function shallowRef(value) {
1357 return createRef(value, true);
1358}
1359function createRef(rawValue, shallow) {
1360 if (isRef(rawValue)) {
1361 return rawValue;
1362 }
1363 return new RefImpl(rawValue, shallow);
1364}
1365class RefImpl {
1366 constructor(value, _shallow) {
1367 this._shallow = _shallow;
1368 this.dep = undefined;
1369 this.__v_isRef = true;
1370 this._rawValue = _shallow ? value : toRaw(value);
1371 this._value = _shallow ? value : toReactive(value);
1372 }
1373 get value() {
1374 trackRefValue(this);
1375 return this._value;
1376 }
1377 set value(newVal) {
1378 newVal = this._shallow ? newVal : toRaw(newVal);
1379 if (hasChanged(newVal, this._rawValue)) {
1380 this._rawValue = newVal;
1381 this._value = this._shallow ? newVal : toReactive(newVal);
1382 triggerRefValue(this, newVal);
1383 }
1384 }
1385}
1386function triggerRef(ref) {
1387 triggerRefValue(ref, ref.value );
1388}
1389function unref(ref) {
1390 return isRef(ref) ? ref.value : ref;
1391}
1392const shallowUnwrapHandlers = {
1393 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1394 set: (target, key, value, receiver) => {
1395 const oldValue = target[key];
1396 if (isRef(oldValue) && !isRef(value)) {
1397 oldValue.value = value;
1398 return true;
1399 }
1400 else {
1401 return Reflect.set(target, key, value, receiver);
1402 }
1403 }
1404};
1405function proxyRefs(objectWithRefs) {
1406 return isReactive(objectWithRefs)
1407 ? objectWithRefs
1408 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1409}
1410class CustomRefImpl {
1411 constructor(factory) {
1412 this.dep = undefined;
1413 this.__v_isRef = true;
1414 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
1415 this._get = get;
1416 this._set = set;
1417 }
1418 get value() {
1419 return this._get();
1420 }
1421 set value(newVal) {
1422 this._set(newVal);
1423 }
1424}
1425function customRef(factory) {
1426 return new CustomRefImpl(factory);
1427}
1428function toRefs(object) {
1429 if (!isProxy(object)) {
1430 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1431 }
1432 const ret = isArray(object) ? new Array(object.length) : {};
1433 for (const key in object) {
1434 ret[key] = toRef(object, key);
1435 }
1436 return ret;
1437}
1438class ObjectRefImpl {
1439 constructor(_object, _key) {
1440 this._object = _object;
1441 this._key = _key;
1442 this.__v_isRef = true;
1443 }
1444 get value() {
1445 return this._object[this._key];
1446 }
1447 set value(newVal) {
1448 this._object[this._key] = newVal;
1449 }
1450}
1451function toRef(object, key) {
1452 const val = object[key];
1453 return isRef(val) ? val : new ObjectRefImpl(object, key);
1454}
1455
1456class ComputedRefImpl {
1457 constructor(getter, _setter, isReadonly) {
1458 this._setter = _setter;
1459 this.dep = undefined;
1460 this._dirty = true;
1461 this.__v_isRef = true;
1462 this.effect = new ReactiveEffect(getter, () => {
1463 if (!this._dirty) {
1464 this._dirty = true;
1465 triggerRefValue(this);
1466 }
1467 });
1468 this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1469 }
1470 get value() {
1471 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1472 const self = toRaw(this);
1473 trackRefValue(self);
1474 if (self._dirty) {
1475 self._dirty = false;
1476 self._value = self.effect.run();
1477 }
1478 return self._value;
1479 }
1480 set value(newValue) {
1481 this._setter(newValue);
1482 }
1483}
1484function computed(getterOrOptions, debugOptions) {
1485 let getter;
1486 let setter;
1487 const onlyGetter = isFunction(getterOrOptions);
1488 if (onlyGetter) {
1489 getter = getterOrOptions;
1490 setter = () => {
1491 console.warn('Write operation failed: computed value is readonly');
1492 }
1493 ;
1494 }
1495 else {
1496 getter = getterOrOptions.get;
1497 setter = getterOrOptions.set;
1498 }
1499 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter);
1500 if (debugOptions) {
1501 cRef.effect.onTrack = debugOptions.onTrack;
1502 cRef.effect.onTrigger = debugOptions.onTrigger;
1503 }
1504 return cRef;
1505}
1506
1507/* eslint-disable no-restricted-globals */
1508let isHmrUpdating = false;
1509const hmrDirtyComponents = new Set();
1510// Expose the HMR runtime on the global object
1511// This makes it entirely tree-shakable without polluting the exports and makes
1512// it easier to be used in toolings like vue-loader
1513// Note: for a component to be eligible for HMR it also needs the __hmrId option
1514// to be set so that its instances can be registered / removed.
1515{
1516 getGlobalThis().__VUE_HMR_RUNTIME__ = {
1517 createRecord: tryWrap(createRecord),
1518 rerender: tryWrap(rerender),
1519 reload: tryWrap(reload)
1520 };
1521}
1522const map = new Map();
1523function registerHMR(instance) {
1524 const id = instance.type.__hmrId;
1525 let record = map.get(id);
1526 if (!record) {
1527 createRecord(id);
1528 record = map.get(id);
1529 }
1530 record.add(instance);
1531}
1532function unregisterHMR(instance) {
1533 map.get(instance.type.__hmrId).delete(instance);
1534}
1535function createRecord(id) {
1536 if (map.has(id)) {
1537 return false;
1538 }
1539 map.set(id, new Set());
1540 return true;
1541}
1542function normalizeClassComponent(component) {
1543 return isClassComponent(component) ? component.__vccOpts : component;
1544}
1545function rerender(id, newRender) {
1546 const record = map.get(id);
1547 if (!record) {
1548 return;
1549 }
1550 [...record].forEach(instance => {
1551 if (newRender) {
1552 instance.render = newRender;
1553 normalizeClassComponent(instance.type).render = newRender;
1554 }
1555 instance.renderCache = [];
1556 // this flag forces child components with slot content to update
1557 isHmrUpdating = true;
1558 instance.update();
1559 isHmrUpdating = false;
1560 });
1561}
1562function reload(id, newComp) {
1563 const record = map.get(id);
1564 if (!record)
1565 return;
1566 newComp = normalizeClassComponent(newComp);
1567 // create a snapshot which avoids the set being mutated during updates
1568 const instances = [...record];
1569 for (const instance of instances) {
1570 const oldComp = normalizeClassComponent(instance.type);
1571 if (!hmrDirtyComponents.has(oldComp)) {
1572 // 1. Update existing comp definition to match new one
1573 extend(oldComp, newComp);
1574 for (const key in oldComp) {
1575 if (key !== '__file' && !(key in newComp)) {
1576 delete oldComp[key];
1577 }
1578 }
1579 // 2. mark definition dirty. This forces the renderer to replace the
1580 // component on patch.
1581 hmrDirtyComponents.add(oldComp);
1582 }
1583 // 3. invalidate options resolution cache
1584 instance.appContext.optionsCache.delete(instance.type);
1585 // 4. actually update
1586 if (instance.ceReload) {
1587 // custom element
1588 hmrDirtyComponents.add(oldComp);
1589 instance.ceReload(newComp.styles);
1590 hmrDirtyComponents.delete(oldComp);
1591 }
1592 else if (instance.parent) {
1593 // 4. Force the parent instance to re-render. This will cause all updated
1594 // components to be unmounted and re-mounted. Queue the update so that we
1595 // don't end up forcing the same parent to re-render multiple times.
1596 queueJob(instance.parent.update);
1597 // instance is the inner component of an async custom element
1598 // invoke to reset styles
1599 if (instance.parent.type.__asyncLoader &&
1600 instance.parent.ceReload) {
1601 instance.parent.ceReload(newComp.styles);
1602 }
1603 }
1604 else if (instance.appContext.reload) {
1605 // root instance mounted via createApp() has a reload method
1606 instance.appContext.reload();
1607 }
1608 else if (typeof window !== 'undefined') {
1609 // root instance inside tree created via raw render(). Force reload.
1610 window.location.reload();
1611 }
1612 else {
1613 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
1614 }
1615 }
1616 // 5. make sure to cleanup dirty hmr components after update
1617 queuePostFlushCb(() => {
1618 for (const instance of instances) {
1619 hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
1620 }
1621 });
1622}
1623function tryWrap(fn) {
1624 return (id, arg) => {
1625 try {
1626 return fn(id, arg);
1627 }
1628 catch (e) {
1629 console.error(e);
1630 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
1631 `Full reload required.`);
1632 }
1633 };
1634}
1635
1636let devtools;
1637let buffer = [];
1638function emit(event, ...args) {
1639 if (devtools) {
1640 devtools.emit(event, ...args);
1641 }
1642 else {
1643 buffer.push({ event, args });
1644 }
1645}
1646function setDevtoolsHook(hook, target) {
1647 devtools = hook;
1648 if (devtools) {
1649 devtools.enabled = true;
1650 buffer.forEach(({ event, args }) => devtools.emit(event, ...args));
1651 buffer = [];
1652 }
1653 else {
1654 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
1655 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
1656 replay.push((newHook) => {
1657 setDevtoolsHook(newHook, target);
1658 });
1659 }
1660}
1661function devtoolsInitApp(app, version) {
1662 emit("app:init" /* APP_INIT */, app, version, {
1663 Fragment,
1664 Text,
1665 Comment,
1666 Static
1667 });
1668}
1669function devtoolsUnmountApp(app) {
1670 emit("app:unmount" /* APP_UNMOUNT */, app);
1671}
1672const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
1673const devtoolsComponentUpdated =
1674/*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
1675const devtoolsComponentRemoved =
1676/*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
1677function createDevtoolsComponentHook(hook) {
1678 return (component) => {
1679 emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
1680 };
1681}
1682const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
1683const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
1684function createDevtoolsPerformanceHook(hook) {
1685 return (component, type, time) => {
1686 emit(hook, component.appContext.app, component.uid, component, type, time);
1687 };
1688}
1689function devtoolsComponentEmit(component, event, params) {
1690 emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
1691}
1692
1693function emit$1(instance, event, ...rawArgs) {
1694 const props = instance.vnode.props || EMPTY_OBJ;
1695 {
1696 const { emitsOptions, propsOptions: [propsOptions] } = instance;
1697 if (emitsOptions) {
1698 if (!(event in emitsOptions) &&
1699 !(false )) {
1700 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
1701 warn$1(`Component emitted event "${event}" but it is neither declared in ` +
1702 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
1703 }
1704 }
1705 else {
1706 const validator = emitsOptions[event];
1707 if (isFunction(validator)) {
1708 const isValid = validator(...rawArgs);
1709 if (!isValid) {
1710 warn$1(`Invalid event arguments: event validation failed for event "${event}".`);
1711 }
1712 }
1713 }
1714 }
1715 }
1716 let args = rawArgs;
1717 const isModelListener = event.startsWith('update:');
1718 // for v-model update:xxx events, apply modifiers on args
1719 const modelArg = isModelListener && event.slice(7);
1720 if (modelArg && modelArg in props) {
1721 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
1722 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
1723 if (trim) {
1724 args = rawArgs.map(a => a.trim());
1725 }
1726 else if (number) {
1727 args = rawArgs.map(toNumber);
1728 }
1729 }
1730 {
1731 devtoolsComponentEmit(instance, event, args);
1732 }
1733 {
1734 const lowerCaseEvent = event.toLowerCase();
1735 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
1736 warn$1(`Event "${lowerCaseEvent}" is emitted in component ` +
1737 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
1738 `Note that HTML attributes are case-insensitive and you cannot use ` +
1739 `v-on to listen to camelCase events when using in-DOM templates. ` +
1740 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
1741 }
1742 }
1743 let handlerName;
1744 let handler = props[(handlerName = toHandlerKey(event))] ||
1745 // also try camelCase event handler (#2249)
1746 props[(handlerName = toHandlerKey(camelize(event)))];
1747 // for v-model update:xxx events, also trigger kebab-case equivalent
1748 // for props passed via kebab-case
1749 if (!handler && isModelListener) {
1750 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
1751 }
1752 if (handler) {
1753 callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1754 }
1755 const onceHandler = props[handlerName + `Once`];
1756 if (onceHandler) {
1757 if (!instance.emitted) {
1758 instance.emitted = {};
1759 }
1760 else if (instance.emitted[handlerName]) {
1761 return;
1762 }
1763 instance.emitted[handlerName] = true;
1764 callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
1765 }
1766}
1767function normalizeEmitsOptions(comp, appContext, asMixin = false) {
1768 const cache = appContext.emitsCache;
1769 const cached = cache.get(comp);
1770 if (cached !== undefined) {
1771 return cached;
1772 }
1773 const raw = comp.emits;
1774 let normalized = {};
1775 // apply mixin/extends props
1776 let hasExtends = false;
1777 if (!isFunction(comp)) {
1778 const extendEmits = (raw) => {
1779 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
1780 if (normalizedFromExtend) {
1781 hasExtends = true;
1782 extend(normalized, normalizedFromExtend);
1783 }
1784 };
1785 if (!asMixin && appContext.mixins.length) {
1786 appContext.mixins.forEach(extendEmits);
1787 }
1788 if (comp.extends) {
1789 extendEmits(comp.extends);
1790 }
1791 if (comp.mixins) {
1792 comp.mixins.forEach(extendEmits);
1793 }
1794 }
1795 if (!raw && !hasExtends) {
1796 cache.set(comp, null);
1797 return null;
1798 }
1799 if (isArray(raw)) {
1800 raw.forEach(key => (normalized[key] = null));
1801 }
1802 else {
1803 extend(normalized, raw);
1804 }
1805 cache.set(comp, normalized);
1806 return normalized;
1807}
1808// Check if an incoming prop key is a declared emit event listener.
1809// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
1810// both considered matched listeners.
1811function isEmitListener(options, key) {
1812 if (!options || !isOn(key)) {
1813 return false;
1814 }
1815 key = key.slice(2).replace(/Once$/, '');
1816 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
1817 hasOwn(options, hyphenate(key)) ||
1818 hasOwn(options, key));
1819}
1820
1821/**
1822 * mark the current rendering instance for asset resolution (e.g.
1823 * resolveComponent, resolveDirective) during render
1824 */
1825let currentRenderingInstance = null;
1826let currentScopeId = null;
1827/**
1828 * Note: rendering calls maybe nested. The function returns the parent rendering
1829 * instance if present, which should be restored after the render is done:
1830 *
1831 * ```js
1832 * const prev = setCurrentRenderingInstance(i)
1833 * // ...render
1834 * setCurrentRenderingInstance(prev)
1835 * ```
1836 */
1837function setCurrentRenderingInstance(instance) {
1838 const prev = currentRenderingInstance;
1839 currentRenderingInstance = instance;
1840 currentScopeId = (instance && instance.type.__scopeId) || null;
1841 return prev;
1842}
1843/**
1844 * Set scope id when creating hoisted vnodes.
1845 * @private compiler helper
1846 */
1847function pushScopeId(id) {
1848 currentScopeId = id;
1849}
1850/**
1851 * Technically we no longer need this after 3.0.8 but we need to keep the same
1852 * API for backwards compat w/ code generated by compilers.
1853 * @private
1854 */
1855function popScopeId() {
1856 currentScopeId = null;
1857}
1858/**
1859 * Only for backwards compat
1860 * @private
1861 */
1862const withScopeId = (_id) => withCtx;
1863/**
1864 * Wrap a slot function to memoize current rendering instance
1865 * @private compiler helper
1866 */
1867function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
1868) {
1869 if (!ctx)
1870 return fn;
1871 // already normalized
1872 if (fn._n) {
1873 return fn;
1874 }
1875 const renderFnWithContext = (...args) => {
1876 // If a user calls a compiled slot inside a template expression (#1745), it
1877 // can mess up block tracking, so by default we disable block tracking and
1878 // force bail out when invoking a compiled slot (indicated by the ._d flag).
1879 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
1880 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
1881 if (renderFnWithContext._d) {
1882 setBlockTracking(-1);
1883 }
1884 const prevInstance = setCurrentRenderingInstance(ctx);
1885 const res = fn(...args);
1886 setCurrentRenderingInstance(prevInstance);
1887 if (renderFnWithContext._d) {
1888 setBlockTracking(1);
1889 }
1890 {
1891 devtoolsComponentUpdated(ctx);
1892 }
1893 return res;
1894 };
1895 // mark normalized to avoid duplicated wrapping
1896 renderFnWithContext._n = true;
1897 // mark this as compiled by default
1898 // this is used in vnode.ts -> normalizeChildren() to set the slot
1899 // rendering flag.
1900 renderFnWithContext._c = true;
1901 // disable block tracking by default
1902 renderFnWithContext._d = true;
1903 return renderFnWithContext;
1904}
1905
1906/**
1907 * dev only flag to track whether $attrs was used during render.
1908 * If $attrs was used during render then the warning for failed attrs
1909 * fallthrough can be suppressed.
1910 */
1911let accessedAttrs = false;
1912function markAttrsAccessed() {
1913 accessedAttrs = true;
1914}
1915function renderComponentRoot(instance) {
1916 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
1917 let result;
1918 let fallthroughAttrs;
1919 const prev = setCurrentRenderingInstance(instance);
1920 {
1921 accessedAttrs = false;
1922 }
1923 try {
1924 if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
1925 // withProxy is a proxy with a different `has` trap only for
1926 // runtime-compiled render functions using `with` block.
1927 const proxyToUse = withProxy || proxy;
1928 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
1929 fallthroughAttrs = attrs;
1930 }
1931 else {
1932 // functional
1933 const render = Component;
1934 // in dev, mark attrs accessed if optional props (attrs === props)
1935 if (true && attrs === props) {
1936 markAttrsAccessed();
1937 }
1938 result = normalizeVNode(render.length > 1
1939 ? render(props, true
1940 ? {
1941 get attrs() {
1942 markAttrsAccessed();
1943 return attrs;
1944 },
1945 slots,
1946 emit
1947 }
1948 : { attrs, slots, emit })
1949 : render(props, null /* we know it doesn't need it */));
1950 fallthroughAttrs = Component.props
1951 ? attrs
1952 : getFunctionalFallthrough(attrs);
1953 }
1954 }
1955 catch (err) {
1956 blockStack.length = 0;
1957 handleError(err, instance, 1 /* RENDER_FUNCTION */);
1958 result = createVNode(Comment);
1959 }
1960 // attr merging
1961 // in dev mode, comments are preserved, and it's possible for a template
1962 // to have comments along side the root element which makes it a fragment
1963 let root = result;
1964 let setRoot = undefined;
1965 if (result.patchFlag > 0 &&
1966 result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
1967 [root, setRoot] = getChildRoot(result);
1968 }
1969 if (fallthroughAttrs && inheritAttrs !== false) {
1970 const keys = Object.keys(fallthroughAttrs);
1971 const { shapeFlag } = root;
1972 if (keys.length) {
1973 if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) {
1974 if (propsOptions && keys.some(isModelListener)) {
1975 // If a v-model listener (onUpdate:xxx) has a corresponding declared
1976 // prop, it indicates this component expects to handle v-model and
1977 // it should not fallthrough.
1978 // related: #1543, #1643, #1989
1979 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
1980 }
1981 root = cloneVNode(root, fallthroughAttrs);
1982 }
1983 else if (!accessedAttrs && root.type !== Comment) {
1984 const allAttrs = Object.keys(attrs);
1985 const eventAttrs = [];
1986 const extraAttrs = [];
1987 for (let i = 0, l = allAttrs.length; i < l; i++) {
1988 const key = allAttrs[i];
1989 if (isOn(key)) {
1990 // ignore v-model handlers when they fail to fallthrough
1991 if (!isModelListener(key)) {
1992 // remove `on`, lowercase first letter to reflect event casing
1993 // accurately
1994 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
1995 }
1996 }
1997 else {
1998 extraAttrs.push(key);
1999 }
2000 }
2001 if (extraAttrs.length) {
2002 warn$1(`Extraneous non-props attributes (` +
2003 `${extraAttrs.join(', ')}) ` +
2004 `were passed to component but could not be automatically inherited ` +
2005 `because component renders fragment or text root nodes.`);
2006 }
2007 if (eventAttrs.length) {
2008 warn$1(`Extraneous non-emits event listeners (` +
2009 `${eventAttrs.join(', ')}) ` +
2010 `were passed to component but could not be automatically inherited ` +
2011 `because component renders fragment or text root nodes. ` +
2012 `If the listener is intended to be a component custom event listener only, ` +
2013 `declare it using the "emits" option.`);
2014 }
2015 }
2016 }
2017 }
2018 // inherit directives
2019 if (vnode.dirs) {
2020 if (!isElementRoot(root)) {
2021 warn$1(`Runtime directive used on component with non-element root node. ` +
2022 `The directives will not function as intended.`);
2023 }
2024 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2025 }
2026 // inherit transition data
2027 if (vnode.transition) {
2028 if (!isElementRoot(root)) {
2029 warn$1(`Component inside <Transition> renders non-element root node ` +
2030 `that cannot be animated.`);
2031 }
2032 root.transition = vnode.transition;
2033 }
2034 if (setRoot) {
2035 setRoot(root);
2036 }
2037 else {
2038 result = root;
2039 }
2040 setCurrentRenderingInstance(prev);
2041 return result;
2042}
2043/**
2044 * dev only
2045 * In dev mode, template root level comments are rendered, which turns the
2046 * template into a fragment root, but we need to locate the single element
2047 * root for attrs and scope id processing.
2048 */
2049const getChildRoot = (vnode) => {
2050 const rawChildren = vnode.children;
2051 const dynamicChildren = vnode.dynamicChildren;
2052 const childRoot = filterSingleRoot(rawChildren);
2053 if (!childRoot) {
2054 return [vnode, undefined];
2055 }
2056 const index = rawChildren.indexOf(childRoot);
2057 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2058 const setRoot = (updatedRoot) => {
2059 rawChildren[index] = updatedRoot;
2060 if (dynamicChildren) {
2061 if (dynamicIndex > -1) {
2062 dynamicChildren[dynamicIndex] = updatedRoot;
2063 }
2064 else if (updatedRoot.patchFlag > 0) {
2065 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2066 }
2067 }
2068 };
2069 return [normalizeVNode(childRoot), setRoot];
2070};
2071function filterSingleRoot(children) {
2072 let singleRoot;
2073 for (let i = 0; i < children.length; i++) {
2074 const child = children[i];
2075 if (isVNode(child)) {
2076 // ignore user comment
2077 if (child.type !== Comment || child.children === 'v-if') {
2078 if (singleRoot) {
2079 // has more than 1 non-comment child, return now
2080 return;
2081 }
2082 else {
2083 singleRoot = child;
2084 }
2085 }
2086 }
2087 else {
2088 return;
2089 }
2090 }
2091 return singleRoot;
2092}
2093const getFunctionalFallthrough = (attrs) => {
2094 let res;
2095 for (const key in attrs) {
2096 if (key === 'class' || key === 'style' || isOn(key)) {
2097 (res || (res = {}))[key] = attrs[key];
2098 }
2099 }
2100 return res;
2101};
2102const filterModelListeners = (attrs, props) => {
2103 const res = {};
2104 for (const key in attrs) {
2105 if (!isModelListener(key) || !(key.slice(9) in props)) {
2106 res[key] = attrs[key];
2107 }
2108 }
2109 return res;
2110};
2111const isElementRoot = (vnode) => {
2112 return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) ||
2113 vnode.type === Comment // potential v-if branch switch
2114 );
2115};
2116function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2117 const { props: prevProps, children: prevChildren, component } = prevVNode;
2118 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2119 const emits = component.emitsOptions;
2120 // Parent component's render function was hot-updated. Since this may have
2121 // caused the child component's slots content to have changed, we need to
2122 // force the child to update as well.
2123 if ((prevChildren || nextChildren) && isHmrUpdating) {
2124 return true;
2125 }
2126 // force child update for runtime directive or transition on component vnode.
2127 if (nextVNode.dirs || nextVNode.transition) {
2128 return true;
2129 }
2130 if (optimized && patchFlag >= 0) {
2131 if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
2132 // slot content that references values that might have changed,
2133 // e.g. in a v-for
2134 return true;
2135 }
2136 if (patchFlag & 16 /* FULL_PROPS */) {
2137 if (!prevProps) {
2138 return !!nextProps;
2139 }
2140 // presence of this flag indicates props are always non-null
2141 return hasPropsChanged(prevProps, nextProps, emits);
2142 }
2143 else if (patchFlag & 8 /* PROPS */) {
2144 const dynamicProps = nextVNode.dynamicProps;
2145 for (let i = 0; i < dynamicProps.length; i++) {
2146 const key = dynamicProps[i];
2147 if (nextProps[key] !== prevProps[key] &&
2148 !isEmitListener(emits, key)) {
2149 return true;
2150 }
2151 }
2152 }
2153 }
2154 else {
2155 // this path is only taken by manually written render functions
2156 // so presence of any children leads to a forced update
2157 if (prevChildren || nextChildren) {
2158 if (!nextChildren || !nextChildren.$stable) {
2159 return true;
2160 }
2161 }
2162 if (prevProps === nextProps) {
2163 return false;
2164 }
2165 if (!prevProps) {
2166 return !!nextProps;
2167 }
2168 if (!nextProps) {
2169 return true;
2170 }
2171 return hasPropsChanged(prevProps, nextProps, emits);
2172 }
2173 return false;
2174}
2175function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2176 const nextKeys = Object.keys(nextProps);
2177 if (nextKeys.length !== Object.keys(prevProps).length) {
2178 return true;
2179 }
2180 for (let i = 0; i < nextKeys.length; i++) {
2181 const key = nextKeys[i];
2182 if (nextProps[key] !== prevProps[key] &&
2183 !isEmitListener(emitsOptions, key)) {
2184 return true;
2185 }
2186 }
2187 return false;
2188}
2189function updateHOCHostEl({ vnode, parent }, el // HostNode
2190) {
2191 while (parent && parent.subTree === vnode) {
2192 (vnode = parent.vnode).el = el;
2193 parent = parent.parent;
2194 }
2195}
2196
2197const isSuspense = (type) => type.__isSuspense;
2198// Suspense exposes a component-like API, and is treated like a component
2199// in the compiler, but internally it's a special built-in type that hooks
2200// directly into the renderer.
2201const SuspenseImpl = {
2202 name: 'Suspense',
2203 // In order to make Suspense tree-shakable, we need to avoid importing it
2204 // directly in the renderer. The renderer checks for the __isSuspense flag
2205 // on a vnode's type and calls the `process` method, passing in renderer
2206 // internals.
2207 __isSuspense: true,
2208 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2209 // platform-specific impl passed from renderer
2210 rendererInternals) {
2211 if (n1 == null) {
2212 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2213 }
2214 else {
2215 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2216 }
2217 },
2218 hydrate: hydrateSuspense,
2219 create: createSuspenseBoundary,
2220 normalize: normalizeSuspenseChildren
2221};
2222// Force-casted public typing for h and TSX props inference
2223const Suspense = (SuspenseImpl );
2224function triggerEvent(vnode, name) {
2225 const eventListener = vnode.props && vnode.props[name];
2226 if (isFunction(eventListener)) {
2227 eventListener();
2228 }
2229}
2230function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2231 const { p: patch, o: { createElement } } = rendererInternals;
2232 const hiddenContainer = createElement('div');
2233 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2234 // start mounting the content subtree in an off-dom container
2235 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2236 // now check if we have encountered any async deps
2237 if (suspense.deps > 0) {
2238 // has async
2239 // invoke @fallback event
2240 triggerEvent(vnode, 'onPending');
2241 triggerEvent(vnode, 'onFallback');
2242 // mount the fallback tree
2243 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2244 isSVG, slotScopeIds);
2245 setActiveBranch(suspense, vnode.ssFallback);
2246 }
2247 else {
2248 // Suspense has no async deps. Just resolve.
2249 suspense.resolve();
2250 }
2251}
2252function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2253 const suspense = (n2.suspense = n1.suspense);
2254 suspense.vnode = n2;
2255 n2.el = n1.el;
2256 const newBranch = n2.ssContent;
2257 const newFallback = n2.ssFallback;
2258 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2259 if (pendingBranch) {
2260 suspense.pendingBranch = newBranch;
2261 if (isSameVNodeType(newBranch, pendingBranch)) {
2262 // same root type but content may have changed.
2263 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2264 if (suspense.deps <= 0) {
2265 suspense.resolve();
2266 }
2267 else if (isInFallback) {
2268 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2269 isSVG, slotScopeIds, optimized);
2270 setActiveBranch(suspense, newFallback);
2271 }
2272 }
2273 else {
2274 // toggled before pending tree is resolved
2275 suspense.pendingId++;
2276 if (isHydrating) {
2277 // if toggled before hydration is finished, the current DOM tree is
2278 // no longer valid. set it as the active branch so it will be unmounted
2279 // when resolved
2280 suspense.isHydrating = false;
2281 suspense.activeBranch = pendingBranch;
2282 }
2283 else {
2284 unmount(pendingBranch, parentComponent, suspense);
2285 }
2286 // increment pending ID. this is used to invalidate async callbacks
2287 // reset suspense state
2288 suspense.deps = 0;
2289 // discard effects from pending branch
2290 suspense.effects.length = 0;
2291 // discard previous container
2292 suspense.hiddenContainer = createElement('div');
2293 if (isInFallback) {
2294 // already in fallback state
2295 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2296 if (suspense.deps <= 0) {
2297 suspense.resolve();
2298 }
2299 else {
2300 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2301 isSVG, slotScopeIds, optimized);
2302 setActiveBranch(suspense, newFallback);
2303 }
2304 }
2305 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2306 // toggled "back" to current active branch
2307 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2308 // force resolve
2309 suspense.resolve(true);
2310 }
2311 else {
2312 // switched to a 3rd branch
2313 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2314 if (suspense.deps <= 0) {
2315 suspense.resolve();
2316 }
2317 }
2318 }
2319 }
2320 else {
2321 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2322 // root did not change, just normal patch
2323 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2324 setActiveBranch(suspense, newBranch);
2325 }
2326 else {
2327 // root node toggled
2328 // invoke @pending event
2329 triggerEvent(n2, 'onPending');
2330 // mount pending branch in off-dom container
2331 suspense.pendingBranch = newBranch;
2332 suspense.pendingId++;
2333 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2334 if (suspense.deps <= 0) {
2335 // incoming branch has no async deps, resolve now.
2336 suspense.resolve();
2337 }
2338 else {
2339 const { timeout, pendingId } = suspense;
2340 if (timeout > 0) {
2341 setTimeout(() => {
2342 if (suspense.pendingId === pendingId) {
2343 suspense.fallback(newFallback);
2344 }
2345 }, timeout);
2346 }
2347 else if (timeout === 0) {
2348 suspense.fallback(newFallback);
2349 }
2350 }
2351 }
2352 }
2353}
2354let hasWarned = false;
2355function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2356 /* istanbul ignore if */
2357 if (!hasWarned) {
2358 hasWarned = true;
2359 // @ts-ignore `console.info` cannot be null error
2360 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2361 }
2362 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2363 const timeout = toNumber(vnode.props && vnode.props.timeout);
2364 const suspense = {
2365 vnode,
2366 parent,
2367 parentComponent,
2368 isSVG,
2369 container,
2370 hiddenContainer,
2371 anchor,
2372 deps: 0,
2373 pendingId: 0,
2374 timeout: typeof timeout === 'number' ? timeout : -1,
2375 activeBranch: null,
2376 pendingBranch: null,
2377 isInFallback: true,
2378 isHydrating,
2379 isUnmounted: false,
2380 effects: [],
2381 resolve(resume = false) {
2382 {
2383 if (!resume && !suspense.pendingBranch) {
2384 throw new Error(`suspense.resolve() is called without a pending branch.`);
2385 }
2386 if (suspense.isUnmounted) {
2387 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2388 }
2389 }
2390 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2391 if (suspense.isHydrating) {
2392 suspense.isHydrating = false;
2393 }
2394 else if (!resume) {
2395 const delayEnter = activeBranch &&
2396 pendingBranch.transition &&
2397 pendingBranch.transition.mode === 'out-in';
2398 if (delayEnter) {
2399 activeBranch.transition.afterLeave = () => {
2400 if (pendingId === suspense.pendingId) {
2401 move(pendingBranch, container, anchor, 0 /* ENTER */);
2402 }
2403 };
2404 }
2405 // this is initial anchor on mount
2406 let { anchor } = suspense;
2407 // unmount current active tree
2408 if (activeBranch) {
2409 // if the fallback tree was mounted, it may have been moved
2410 // as part of a parent suspense. get the latest anchor for insertion
2411 anchor = next(activeBranch);
2412 unmount(activeBranch, parentComponent, suspense, true);
2413 }
2414 if (!delayEnter) {
2415 // move content from off-dom container to actual container
2416 move(pendingBranch, container, anchor, 0 /* ENTER */);
2417 }
2418 }
2419 setActiveBranch(suspense, pendingBranch);
2420 suspense.pendingBranch = null;
2421 suspense.isInFallback = false;
2422 // flush buffered effects
2423 // check if there is a pending parent suspense
2424 let parent = suspense.parent;
2425 let hasUnresolvedAncestor = false;
2426 while (parent) {
2427 if (parent.pendingBranch) {
2428 // found a pending parent suspense, merge buffered post jobs
2429 // into that parent
2430 parent.effects.push(...effects);
2431 hasUnresolvedAncestor = true;
2432 break;
2433 }
2434 parent = parent.parent;
2435 }
2436 // no pending parent suspense, flush all jobs
2437 if (!hasUnresolvedAncestor) {
2438 queuePostFlushCb(effects);
2439 }
2440 suspense.effects = [];
2441 // invoke @resolve event
2442 triggerEvent(vnode, 'onResolve');
2443 },
2444 fallback(fallbackVNode) {
2445 if (!suspense.pendingBranch) {
2446 return;
2447 }
2448 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
2449 // invoke @fallback event
2450 triggerEvent(vnode, 'onFallback');
2451 const anchor = next(activeBranch);
2452 const mountFallback = () => {
2453 if (!suspense.isInFallback) {
2454 return;
2455 }
2456 // mount the fallback tree
2457 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2458 isSVG, slotScopeIds, optimized);
2459 setActiveBranch(suspense, fallbackVNode);
2460 };
2461 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
2462 if (delayEnter) {
2463 activeBranch.transition.afterLeave = mountFallback;
2464 }
2465 suspense.isInFallback = true;
2466 // unmount current active branch
2467 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
2468 true // shouldRemove
2469 );
2470 if (!delayEnter) {
2471 mountFallback();
2472 }
2473 },
2474 move(container, anchor, type) {
2475 suspense.activeBranch &&
2476 move(suspense.activeBranch, container, anchor, type);
2477 suspense.container = container;
2478 },
2479 next() {
2480 return suspense.activeBranch && next(suspense.activeBranch);
2481 },
2482 registerDep(instance, setupRenderEffect) {
2483 const isInPendingSuspense = !!suspense.pendingBranch;
2484 if (isInPendingSuspense) {
2485 suspense.deps++;
2486 }
2487 const hydratedEl = instance.vnode.el;
2488 instance
2489 .asyncDep.catch(err => {
2490 handleError(err, instance, 0 /* SETUP_FUNCTION */);
2491 })
2492 .then(asyncSetupResult => {
2493 // retry when the setup() promise resolves.
2494 // component may have been unmounted before resolve.
2495 if (instance.isUnmounted ||
2496 suspense.isUnmounted ||
2497 suspense.pendingId !== instance.suspenseId) {
2498 return;
2499 }
2500 // retry from this component
2501 instance.asyncResolved = true;
2502 const { vnode } = instance;
2503 {
2504 pushWarningContext(vnode);
2505 }
2506 handleSetupResult(instance, asyncSetupResult, false);
2507 if (hydratedEl) {
2508 // vnode may have been replaced if an update happened before the
2509 // async dep is resolved.
2510 vnode.el = hydratedEl;
2511 }
2512 const placeholder = !hydratedEl && instance.subTree.el;
2513 setupRenderEffect(instance, vnode,
2514 // component may have been moved before resolve.
2515 // if this is not a hydration, instance.subTree will be the comment
2516 // placeholder.
2517 parentNode(hydratedEl || instance.subTree.el),
2518 // anchor will not be used if this is hydration, so only need to
2519 // consider the comment placeholder case.
2520 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
2521 if (placeholder) {
2522 remove(placeholder);
2523 }
2524 updateHOCHostEl(instance, vnode.el);
2525 {
2526 popWarningContext();
2527 }
2528 // only decrease deps count if suspense is not already resolved
2529 if (isInPendingSuspense && --suspense.deps === 0) {
2530 suspense.resolve();
2531 }
2532 });
2533 },
2534 unmount(parentSuspense, doRemove) {
2535 suspense.isUnmounted = true;
2536 if (suspense.activeBranch) {
2537 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
2538 }
2539 if (suspense.pendingBranch) {
2540 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
2541 }
2542 }
2543 };
2544 return suspense;
2545}
2546function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
2547 /* eslint-disable no-restricted-globals */
2548 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
2549 // there are two possible scenarios for server-rendered suspense:
2550 // - success: ssr content should be fully resolved
2551 // - failure: ssr content should be the fallback branch.
2552 // however, on the client we don't really know if it has failed or not
2553 // attempt to hydrate the DOM assuming it has succeeded, but we still
2554 // need to construct a suspense boundary first
2555 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
2556 if (suspense.deps === 0) {
2557 suspense.resolve();
2558 }
2559 return result;
2560 /* eslint-enable no-restricted-globals */
2561}
2562function normalizeSuspenseChildren(vnode) {
2563 const { shapeFlag, children } = vnode;
2564 const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
2565 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
2566 vnode.ssFallback = isSlotChildren
2567 ? normalizeSuspenseSlot(children.fallback)
2568 : createVNode(Comment);
2569}
2570function normalizeSuspenseSlot(s) {
2571 let block;
2572 if (isFunction(s)) {
2573 const trackBlock = isBlockTreeEnabled && s._c;
2574 if (trackBlock) {
2575 // disableTracking: false
2576 // allow block tracking for compiled slots
2577 // (see ./componentRenderContext.ts)
2578 s._d = false;
2579 openBlock();
2580 }
2581 s = s();
2582 if (trackBlock) {
2583 s._d = true;
2584 block = currentBlock;
2585 closeBlock();
2586 }
2587 }
2588 if (isArray(s)) {
2589 const singleChild = filterSingleRoot(s);
2590 if (!singleChild) {
2591 warn$1(`<Suspense> slots expect a single root node.`);
2592 }
2593 s = singleChild;
2594 }
2595 s = normalizeVNode(s);
2596 if (block && !s.dynamicChildren) {
2597 s.dynamicChildren = block.filter(c => c !== s);
2598 }
2599 return s;
2600}
2601function queueEffectWithSuspense(fn, suspense) {
2602 if (suspense && suspense.pendingBranch) {
2603 if (isArray(fn)) {
2604 suspense.effects.push(...fn);
2605 }
2606 else {
2607 suspense.effects.push(fn);
2608 }
2609 }
2610 else {
2611 queuePostFlushCb(fn);
2612 }
2613}
2614function setActiveBranch(suspense, branch) {
2615 suspense.activeBranch = branch;
2616 const { vnode, parentComponent } = suspense;
2617 const el = (vnode.el = branch.el);
2618 // in case suspense is the root node of a component,
2619 // recursively update the HOC el
2620 if (parentComponent && parentComponent.subTree === vnode) {
2621 parentComponent.vnode.el = el;
2622 updateHOCHostEl(parentComponent, el);
2623 }
2624}
2625
2626function provide(key, value) {
2627 if (!currentInstance) {
2628 {
2629 warn$1(`provide() can only be used inside setup().`);
2630 }
2631 }
2632 else {
2633 let provides = currentInstance.provides;
2634 // by default an instance inherits its parent's provides object
2635 // but when it needs to provide values of its own, it creates its
2636 // own provides object using parent provides object as prototype.
2637 // this way in `inject` we can simply look up injections from direct
2638 // parent and let the prototype chain do the work.
2639 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
2640 if (parentProvides === provides) {
2641 provides = currentInstance.provides = Object.create(parentProvides);
2642 }
2643 // TS doesn't allow symbol as index type
2644 provides[key] = value;
2645 }
2646}
2647function inject(key, defaultValue, treatDefaultAsFactory = false) {
2648 // fallback to `currentRenderingInstance` so that this can be called in
2649 // a functional component
2650 const instance = currentInstance || currentRenderingInstance;
2651 if (instance) {
2652 // #2400
2653 // to support `app.use` plugins,
2654 // fallback to appContext's `provides` if the intance is at root
2655 const provides = instance.parent == null
2656 ? instance.vnode.appContext && instance.vnode.appContext.provides
2657 : instance.parent.provides;
2658 if (provides && key in provides) {
2659 // TS doesn't allow symbol as index type
2660 return provides[key];
2661 }
2662 else if (arguments.length > 1) {
2663 return treatDefaultAsFactory && isFunction(defaultValue)
2664 ? defaultValue.call(instance.proxy)
2665 : defaultValue;
2666 }
2667 else {
2668 warn$1(`injection "${String(key)}" not found.`);
2669 }
2670 }
2671 else {
2672 warn$1(`inject() can only be used inside setup() or functional components.`);
2673 }
2674}
2675
2676function useTransitionState() {
2677 const state = {
2678 isMounted: false,
2679 isLeaving: false,
2680 isUnmounting: false,
2681 leavingVNodes: new Map()
2682 };
2683 onMounted(() => {
2684 state.isMounted = true;
2685 });
2686 onBeforeUnmount(() => {
2687 state.isUnmounting = true;
2688 });
2689 return state;
2690}
2691const TransitionHookValidator = [Function, Array];
2692const BaseTransitionImpl = {
2693 name: `BaseTransition`,
2694 props: {
2695 mode: String,
2696 appear: Boolean,
2697 persisted: Boolean,
2698 // enter
2699 onBeforeEnter: TransitionHookValidator,
2700 onEnter: TransitionHookValidator,
2701 onAfterEnter: TransitionHookValidator,
2702 onEnterCancelled: TransitionHookValidator,
2703 // leave
2704 onBeforeLeave: TransitionHookValidator,
2705 onLeave: TransitionHookValidator,
2706 onAfterLeave: TransitionHookValidator,
2707 onLeaveCancelled: TransitionHookValidator,
2708 // appear
2709 onBeforeAppear: TransitionHookValidator,
2710 onAppear: TransitionHookValidator,
2711 onAfterAppear: TransitionHookValidator,
2712 onAppearCancelled: TransitionHookValidator
2713 },
2714 setup(props, { slots }) {
2715 const instance = getCurrentInstance();
2716 const state = useTransitionState();
2717 let prevTransitionKey;
2718 return () => {
2719 const children = slots.default && getTransitionRawChildren(slots.default(), true);
2720 if (!children || !children.length) {
2721 return;
2722 }
2723 // warn multiple elements
2724 if (children.length > 1) {
2725 warn$1('<transition> can only be used on a single element or component. Use ' +
2726 '<transition-group> for lists.');
2727 }
2728 // there's no need to track reactivity for these props so use the raw
2729 // props for a bit better perf
2730 const rawProps = toRaw(props);
2731 const { mode } = rawProps;
2732 // check mode
2733 if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
2734 warn$1(`invalid <transition> mode: ${mode}`);
2735 }
2736 // at this point children has a guaranteed length of 1.
2737 const child = children[0];
2738 if (state.isLeaving) {
2739 return emptyPlaceholder(child);
2740 }
2741 // in the case of <transition><keep-alive/></transition>, we need to
2742 // compare the type of the kept-alive children.
2743 const innerChild = getKeepAliveChild(child);
2744 if (!innerChild) {
2745 return emptyPlaceholder(child);
2746 }
2747 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
2748 setTransitionHooks(innerChild, enterHooks);
2749 const oldChild = instance.subTree;
2750 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
2751 let transitionKeyChanged = false;
2752 const { getTransitionKey } = innerChild.type;
2753 if (getTransitionKey) {
2754 const key = getTransitionKey();
2755 if (prevTransitionKey === undefined) {
2756 prevTransitionKey = key;
2757 }
2758 else if (key !== prevTransitionKey) {
2759 prevTransitionKey = key;
2760 transitionKeyChanged = true;
2761 }
2762 }
2763 // handle mode
2764 if (oldInnerChild &&
2765 oldInnerChild.type !== Comment &&
2766 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
2767 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
2768 // update old tree's hooks in case of dynamic transition
2769 setTransitionHooks(oldInnerChild, leavingHooks);
2770 // switching between different views
2771 if (mode === 'out-in') {
2772 state.isLeaving = true;
2773 // return placeholder node and queue update when leave finishes
2774 leavingHooks.afterLeave = () => {
2775 state.isLeaving = false;
2776 instance.update();
2777 };
2778 return emptyPlaceholder(child);
2779 }
2780 else if (mode === 'in-out' && innerChild.type !== Comment) {
2781 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
2782 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
2783 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
2784 // early removal callback
2785 el._leaveCb = () => {
2786 earlyRemove();
2787 el._leaveCb = undefined;
2788 delete enterHooks.delayedLeave;
2789 };
2790 enterHooks.delayedLeave = delayedLeave;
2791 };
2792 }
2793 }
2794 return child;
2795 };
2796 }
2797};
2798// export the public type for h/tsx inference
2799// also to avoid inline import() in generated d.ts files
2800const BaseTransition = BaseTransitionImpl;
2801function getLeavingNodesForType(state, vnode) {
2802 const { leavingVNodes } = state;
2803 let leavingVNodesCache = leavingVNodes.get(vnode.type);
2804 if (!leavingVNodesCache) {
2805 leavingVNodesCache = Object.create(null);
2806 leavingVNodes.set(vnode.type, leavingVNodesCache);
2807 }
2808 return leavingVNodesCache;
2809}
2810// The transition hooks are attached to the vnode as vnode.transition
2811// and will be called at appropriate timing in the renderer.
2812function resolveTransitionHooks(vnode, props, state, instance) {
2813 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
2814 const key = String(vnode.key);
2815 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
2816 const callHook = (hook, args) => {
2817 hook &&
2818 callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
2819 };
2820 const hooks = {
2821 mode,
2822 persisted,
2823 beforeEnter(el) {
2824 let hook = onBeforeEnter;
2825 if (!state.isMounted) {
2826 if (appear) {
2827 hook = onBeforeAppear || onBeforeEnter;
2828 }
2829 else {
2830 return;
2831 }
2832 }
2833 // for same element (v-show)
2834 if (el._leaveCb) {
2835 el._leaveCb(true /* cancelled */);
2836 }
2837 // for toggled element with same key (v-if)
2838 const leavingVNode = leavingVNodesCache[key];
2839 if (leavingVNode &&
2840 isSameVNodeType(vnode, leavingVNode) &&
2841 leavingVNode.el._leaveCb) {
2842 // force early removal (not cancelled)
2843 leavingVNode.el._leaveCb();
2844 }
2845 callHook(hook, [el]);
2846 },
2847 enter(el) {
2848 let hook = onEnter;
2849 let afterHook = onAfterEnter;
2850 let cancelHook = onEnterCancelled;
2851 if (!state.isMounted) {
2852 if (appear) {
2853 hook = onAppear || onEnter;
2854 afterHook = onAfterAppear || onAfterEnter;
2855 cancelHook = onAppearCancelled || onEnterCancelled;
2856 }
2857 else {
2858 return;
2859 }
2860 }
2861 let called = false;
2862 const done = (el._enterCb = (cancelled) => {
2863 if (called)
2864 return;
2865 called = true;
2866 if (cancelled) {
2867 callHook(cancelHook, [el]);
2868 }
2869 else {
2870 callHook(afterHook, [el]);
2871 }
2872 if (hooks.delayedLeave) {
2873 hooks.delayedLeave();
2874 }
2875 el._enterCb = undefined;
2876 });
2877 if (hook) {
2878 hook(el, done);
2879 if (hook.length <= 1) {
2880 done();
2881 }
2882 }
2883 else {
2884 done();
2885 }
2886 },
2887 leave(el, remove) {
2888 const key = String(vnode.key);
2889 if (el._enterCb) {
2890 el._enterCb(true /* cancelled */);
2891 }
2892 if (state.isUnmounting) {
2893 return remove();
2894 }
2895 callHook(onBeforeLeave, [el]);
2896 let called = false;
2897 const done = (el._leaveCb = (cancelled) => {
2898 if (called)
2899 return;
2900 called = true;
2901 remove();
2902 if (cancelled) {
2903 callHook(onLeaveCancelled, [el]);
2904 }
2905 else {
2906 callHook(onAfterLeave, [el]);
2907 }
2908 el._leaveCb = undefined;
2909 if (leavingVNodesCache[key] === vnode) {
2910 delete leavingVNodesCache[key];
2911 }
2912 });
2913 leavingVNodesCache[key] = vnode;
2914 if (onLeave) {
2915 onLeave(el, done);
2916 if (onLeave.length <= 1) {
2917 done();
2918 }
2919 }
2920 else {
2921 done();
2922 }
2923 },
2924 clone(vnode) {
2925 return resolveTransitionHooks(vnode, props, state, instance);
2926 }
2927 };
2928 return hooks;
2929}
2930// the placeholder really only handles one special case: KeepAlive
2931// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
2932// placeholder with empty content to avoid the KeepAlive instance from being
2933// unmounted.
2934function emptyPlaceholder(vnode) {
2935 if (isKeepAlive(vnode)) {
2936 vnode = cloneVNode(vnode);
2937 vnode.children = null;
2938 return vnode;
2939 }
2940}
2941function getKeepAliveChild(vnode) {
2942 return isKeepAlive(vnode)
2943 ? vnode.children
2944 ? vnode.children[0]
2945 : undefined
2946 : vnode;
2947}
2948function setTransitionHooks(vnode, hooks) {
2949 if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
2950 setTransitionHooks(vnode.component.subTree, hooks);
2951 }
2952 else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
2953 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
2954 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
2955 }
2956 else {
2957 vnode.transition = hooks;
2958 }
2959}
2960function getTransitionRawChildren(children, keepComment = false) {
2961 let ret = [];
2962 let keyedFragmentCount = 0;
2963 for (let i = 0; i < children.length; i++) {
2964 const child = children[i];
2965 // handle fragment children case, e.g. v-for
2966 if (child.type === Fragment) {
2967 if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
2968 keyedFragmentCount++;
2969 ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
2970 }
2971 // comment placeholders should be skipped, e.g. v-if
2972 else if (keepComment || child.type !== Comment) {
2973 ret.push(child);
2974 }
2975 }
2976 // #1126 if a transition children list contains multiple sub fragments, these
2977 // fragments will be merged into a flat children array. Since each v-for
2978 // fragment may contain different static bindings inside, we need to de-op
2979 // these children to force full diffs to ensure correct behavior.
2980 if (keyedFragmentCount > 1) {
2981 for (let i = 0; i < ret.length; i++) {
2982 ret[i].patchFlag = -2 /* BAIL */;
2983 }
2984 }
2985 return ret;
2986}
2987
2988// implementation, close to no-op
2989function defineComponent(options) {
2990 return isFunction(options) ? { setup: options, name: options.name } : options;
2991}
2992
2993const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
2994function defineAsyncComponent(source) {
2995 if (isFunction(source)) {
2996 source = { loader: source };
2997 }
2998 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
2999 suspensible = true, onError: userOnError } = source;
3000 let pendingRequest = null;
3001 let resolvedComp;
3002 let retries = 0;
3003 const retry = () => {
3004 retries++;
3005 pendingRequest = null;
3006 return load();
3007 };
3008 const load = () => {
3009 let thisRequest;
3010 return (pendingRequest ||
3011 (thisRequest = pendingRequest =
3012 loader()
3013 .catch(err => {
3014 err = err instanceof Error ? err : new Error(String(err));
3015 if (userOnError) {
3016 return new Promise((resolve, reject) => {
3017 const userRetry = () => resolve(retry());
3018 const userFail = () => reject(err);
3019 userOnError(err, userRetry, userFail, retries + 1);
3020 });
3021 }
3022 else {
3023 throw err;
3024 }
3025 })
3026 .then((comp) => {
3027 if (thisRequest !== pendingRequest && pendingRequest) {
3028 return pendingRequest;
3029 }
3030 if (!comp) {
3031 warn$1(`Async component loader resolved to undefined. ` +
3032 `If you are using retry(), make sure to return its return value.`);
3033 }
3034 // interop module default
3035 if (comp &&
3036 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3037 comp = comp.default;
3038 }
3039 if (comp && !isObject(comp) && !isFunction(comp)) {
3040 throw new Error(`Invalid async component load result: ${comp}`);
3041 }
3042 resolvedComp = comp;
3043 return comp;
3044 })));
3045 };
3046 return defineComponent({
3047 name: 'AsyncComponentWrapper',
3048 __asyncLoader: load,
3049 get __asyncResolved() {
3050 return resolvedComp;
3051 },
3052 setup() {
3053 const instance = currentInstance;
3054 // already resolved
3055 if (resolvedComp) {
3056 return () => createInnerComp(resolvedComp, instance);
3057 }
3058 const onError = (err) => {
3059 pendingRequest = null;
3060 handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3061 };
3062 // suspense-controlled or SSR.
3063 if ((suspensible && instance.suspense) ||
3064 (false )) {
3065 return load()
3066 .then(comp => {
3067 return () => createInnerComp(comp, instance);
3068 })
3069 .catch(err => {
3070 onError(err);
3071 return () => errorComponent
3072 ? createVNode(errorComponent, {
3073 error: err
3074 })
3075 : null;
3076 });
3077 }
3078 const loaded = ref(false);
3079 const error = ref();
3080 const delayed = ref(!!delay);
3081 if (delay) {
3082 setTimeout(() => {
3083 delayed.value = false;
3084 }, delay);
3085 }
3086 if (timeout != null) {
3087 setTimeout(() => {
3088 if (!loaded.value && !error.value) {
3089 const err = new Error(`Async component timed out after ${timeout}ms.`);
3090 onError(err);
3091 error.value = err;
3092 }
3093 }, timeout);
3094 }
3095 load()
3096 .then(() => {
3097 loaded.value = true;
3098 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3099 // parent is keep-alive, force update so the loaded component's
3100 // name is taken into account
3101 queueJob(instance.parent.update);
3102 }
3103 })
3104 .catch(err => {
3105 onError(err);
3106 error.value = err;
3107 });
3108 return () => {
3109 if (loaded.value && resolvedComp) {
3110 return createInnerComp(resolvedComp, instance);
3111 }
3112 else if (error.value && errorComponent) {
3113 return createVNode(errorComponent, {
3114 error: error.value
3115 });
3116 }
3117 else if (loadingComponent && !delayed.value) {
3118 return createVNode(loadingComponent);
3119 }
3120 };
3121 }
3122 });
3123}
3124function createInnerComp(comp, { vnode: { ref, props, children } }) {
3125 const vnode = createVNode(comp, props, children);
3126 // ensure inner component inherits the async wrapper's ref owner
3127 vnode.ref = ref;
3128 return vnode;
3129}
3130
3131const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
3132const KeepAliveImpl = {
3133 name: `KeepAlive`,
3134 // Marker for special handling inside the renderer. We are not using a ===
3135 // check directly on KeepAlive in the renderer, because importing it directly
3136 // would prevent it from being tree-shaken.
3137 __isKeepAlive: true,
3138 props: {
3139 include: [String, RegExp, Array],
3140 exclude: [String, RegExp, Array],
3141 max: [String, Number]
3142 },
3143 setup(props, { slots }) {
3144 const instance = getCurrentInstance();
3145 // KeepAlive communicates with the instantiated renderer via the
3146 // ctx where the renderer passes in its internals,
3147 // and the KeepAlive instance exposes activate/deactivate implementations.
3148 // The whole point of this is to avoid importing KeepAlive directly in the
3149 // renderer to facilitate tree-shaking.
3150 const sharedContext = instance.ctx;
3151 // if the internal renderer is not registered, it indicates that this is server-side rendering,
3152 // for KeepAlive, we just need to render its children
3153 if (!sharedContext.renderer) {
3154 return slots.default;
3155 }
3156 const cache = new Map();
3157 const keys = new Set();
3158 let current = null;
3159 {
3160 instance.__v_cache = cache;
3161 }
3162 const parentSuspense = instance.suspense;
3163 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
3164 const storageContainer = createElement('div');
3165 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
3166 const instance = vnode.component;
3167 move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
3168 // in case props have changed
3169 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
3170 queuePostRenderEffect(() => {
3171 instance.isDeactivated = false;
3172 if (instance.a) {
3173 invokeArrayFns(instance.a);
3174 }
3175 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
3176 if (vnodeHook) {
3177 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3178 }
3179 }, parentSuspense);
3180 {
3181 // Update components tree
3182 devtoolsComponentAdded(instance);
3183 }
3184 };
3185 sharedContext.deactivate = (vnode) => {
3186 const instance = vnode.component;
3187 move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
3188 queuePostRenderEffect(() => {
3189 if (instance.da) {
3190 invokeArrayFns(instance.da);
3191 }
3192 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
3193 if (vnodeHook) {
3194 invokeVNodeHook(vnodeHook, instance.parent, vnode);
3195 }
3196 instance.isDeactivated = true;
3197 }, parentSuspense);
3198 {
3199 // Update components tree
3200 devtoolsComponentAdded(instance);
3201 }
3202 };
3203 function unmount(vnode) {
3204 // reset the shapeFlag so it can be properly unmounted
3205 resetShapeFlag(vnode);
3206 _unmount(vnode, instance, parentSuspense);
3207 }
3208 function pruneCache(filter) {
3209 cache.forEach((vnode, key) => {
3210 const name = getComponentName(vnode.type);
3211 if (name && (!filter || !filter(name))) {
3212 pruneCacheEntry(key);
3213 }
3214 });
3215 }
3216 function pruneCacheEntry(key) {
3217 const cached = cache.get(key);
3218 if (!current || cached.type !== current.type) {
3219 unmount(cached);
3220 }
3221 else if (current) {
3222 // current active instance should no longer be kept-alive.
3223 // we can't unmount it now but it might be later, so reset its flag now.
3224 resetShapeFlag(current);
3225 }
3226 cache.delete(key);
3227 keys.delete(key);
3228 }
3229 // prune cache on include/exclude prop change
3230 watch(() => [props.include, props.exclude], ([include, exclude]) => {
3231 include && pruneCache(name => matches(include, name));
3232 exclude && pruneCache(name => !matches(exclude, name));
3233 },
3234 // prune post-render after `current` has been updated
3235 { flush: 'post', deep: true });
3236 // cache sub tree after render
3237 let pendingCacheKey = null;
3238 const cacheSubtree = () => {
3239 // fix #1621, the pendingCacheKey could be 0
3240 if (pendingCacheKey != null) {
3241 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
3242 }
3243 };
3244 onMounted(cacheSubtree);
3245 onUpdated(cacheSubtree);
3246 onBeforeUnmount(() => {
3247 cache.forEach(cached => {
3248 const { subTree, suspense } = instance;
3249 const vnode = getInnerChild(subTree);
3250 if (cached.type === vnode.type) {
3251 // current instance will be unmounted as part of keep-alive's unmount
3252 resetShapeFlag(vnode);
3253 // but invoke its deactivated hook here
3254 const da = vnode.component.da;
3255 da && queuePostRenderEffect(da, suspense);
3256 return;
3257 }
3258 unmount(cached);
3259 });
3260 });
3261 return () => {
3262 pendingCacheKey = null;
3263 if (!slots.default) {
3264 return null;
3265 }
3266 const children = slots.default();
3267 const rawVNode = children[0];
3268 if (children.length > 1) {
3269 {
3270 warn$1(`KeepAlive should contain exactly one component child.`);
3271 }
3272 current = null;
3273 return children;
3274 }
3275 else if (!isVNode(rawVNode) ||
3276 (!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
3277 !(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
3278 current = null;
3279 return rawVNode;
3280 }
3281 let vnode = getInnerChild(rawVNode);
3282 const comp = vnode.type;
3283 // for async components, name check should be based in its loaded
3284 // inner component if available
3285 const name = getComponentName(isAsyncWrapper(vnode)
3286 ? vnode.type.__asyncResolved || {}
3287 : comp);
3288 const { include, exclude, max } = props;
3289 if ((include && (!name || !matches(include, name))) ||
3290 (exclude && name && matches(exclude, name))) {
3291 current = vnode;
3292 return rawVNode;
3293 }
3294 const key = vnode.key == null ? comp : vnode.key;
3295 const cachedVNode = cache.get(key);
3296 // clone vnode if it's reused because we are going to mutate it
3297 if (vnode.el) {
3298 vnode = cloneVNode(vnode);
3299 if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
3300 rawVNode.ssContent = vnode;
3301 }
3302 }
3303 // #1513 it's possible for the returned vnode to be cloned due to attr
3304 // fallthrough or scopeId, so the vnode here may not be the final vnode
3305 // that is mounted. Instead of caching it directly, we store the pending
3306 // key and cache `instance.subTree` (the normalized vnode) in
3307 // beforeMount/beforeUpdate hooks.
3308 pendingCacheKey = key;
3309 if (cachedVNode) {
3310 // copy over mounted state
3311 vnode.el = cachedVNode.el;
3312 vnode.component = cachedVNode.component;
3313 if (vnode.transition) {
3314 // recursively update transition hooks on subTree
3315 setTransitionHooks(vnode, vnode.transition);
3316 }
3317 // avoid vnode being mounted as fresh
3318 vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
3319 // make this key the freshest
3320 keys.delete(key);
3321 keys.add(key);
3322 }
3323 else {
3324 keys.add(key);
3325 // prune oldest entry
3326 if (max && keys.size > parseInt(max, 10)) {
3327 pruneCacheEntry(keys.values().next().value);
3328 }
3329 }
3330 // avoid vnode being unmounted
3331 vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
3332 current = vnode;
3333 return rawVNode;
3334 };
3335 }
3336};
3337// export the public type for h/tsx inference
3338// also to avoid inline import() in generated d.ts files
3339const KeepAlive = KeepAliveImpl;
3340function matches(pattern, name) {
3341 if (isArray(pattern)) {
3342 return pattern.some((p) => matches(p, name));
3343 }
3344 else if (isString(pattern)) {
3345 return pattern.split(',').indexOf(name) > -1;
3346 }
3347 else if (pattern.test) {
3348 return pattern.test(name);
3349 }
3350 /* istanbul ignore next */
3351 return false;
3352}
3353function onActivated(hook, target) {
3354 registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
3355}
3356function onDeactivated(hook, target) {
3357 registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
3358}
3359function registerKeepAliveHook(hook, type, target = currentInstance) {
3360 // cache the deactivate branch check wrapper for injected hooks so the same
3361 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
3362 // deactivation check".
3363 const wrappedHook = hook.__wdc ||
3364 (hook.__wdc = () => {
3365 // only fire the hook if the target instance is NOT in a deactivated branch.
3366 let current = target;
3367 while (current) {
3368 if (current.isDeactivated) {
3369 return;
3370 }
3371 current = current.parent;
3372 }
3373 hook();
3374 });
3375 injectHook(type, wrappedHook, target);
3376 // In addition to registering it on the target instance, we walk up the parent
3377 // chain and register it on all ancestor instances that are keep-alive roots.
3378 // This avoids the need to walk the entire component tree when invoking these
3379 // hooks, and more importantly, avoids the need to track child components in
3380 // arrays.
3381 if (target) {
3382 let current = target.parent;
3383 while (current && current.parent) {
3384 if (isKeepAlive(current.parent.vnode)) {
3385 injectToKeepAliveRoot(wrappedHook, type, target, current);
3386 }
3387 current = current.parent;
3388 }
3389 }
3390}
3391function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
3392 // injectHook wraps the original for error handling, so make sure to remove
3393 // the wrapped version.
3394 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
3395 onUnmounted(() => {
3396 remove(keepAliveRoot[type], injected);
3397 }, target);
3398}
3399function resetShapeFlag(vnode) {
3400 let shapeFlag = vnode.shapeFlag;
3401 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
3402 shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
3403 }
3404 if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
3405 shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
3406 }
3407 vnode.shapeFlag = shapeFlag;
3408}
3409function getInnerChild(vnode) {
3410 return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
3411}
3412
3413function injectHook(type, hook, target = currentInstance, prepend = false) {
3414 if (target) {
3415 const hooks = target[type] || (target[type] = []);
3416 // cache the error handling wrapper for injected hooks so the same hook
3417 // can be properly deduped by the scheduler. "__weh" stands for "with error
3418 // handling".
3419 const wrappedHook = hook.__weh ||
3420 (hook.__weh = (...args) => {
3421 if (target.isUnmounted) {
3422 return;
3423 }
3424 // disable tracking inside all lifecycle hooks
3425 // since they can potentially be called inside effects.
3426 pauseTracking();
3427 // Set currentInstance during hook invocation.
3428 // This assumes the hook does not synchronously trigger other hooks, which
3429 // can only be false when the user does something really funky.
3430 setCurrentInstance(target);
3431 const res = callWithAsyncErrorHandling(hook, target, type, args);
3432 unsetCurrentInstance();
3433 resetTracking();
3434 return res;
3435 });
3436 if (prepend) {
3437 hooks.unshift(wrappedHook);
3438 }
3439 else {
3440 hooks.push(wrappedHook);
3441 }
3442 return wrappedHook;
3443 }
3444 else {
3445 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
3446 warn$1(`${apiName} is called when there is no active component instance to be ` +
3447 `associated with. ` +
3448 `Lifecycle injection APIs can only be used during execution of setup().` +
3449 (` If you are using async setup(), make sure to register lifecycle ` +
3450 `hooks before the first await statement.`
3451 ));
3452 }
3453}
3454const createHook = (lifecycle) => (hook, target = currentInstance) =>
3455// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
3456(!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
3457 injectHook(lifecycle, hook, target);
3458const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
3459const onMounted = createHook("m" /* MOUNTED */);
3460const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
3461const onUpdated = createHook("u" /* UPDATED */);
3462const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
3463const onUnmounted = createHook("um" /* UNMOUNTED */);
3464const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
3465const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
3466const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
3467function onErrorCaptured(hook, target = currentInstance) {
3468 injectHook("ec" /* ERROR_CAPTURED */, hook, target);
3469}
3470
3471function createDuplicateChecker() {
3472 const cache = Object.create(null);
3473 return (type, key) => {
3474 if (cache[key]) {
3475 warn$1(`${type} property "${key}" is already defined in ${cache[key]}.`);
3476 }
3477 else {
3478 cache[key] = type;
3479 }
3480 };
3481}
3482let shouldCacheAccess = true;
3483function applyOptions(instance) {
3484 const options = resolveMergedOptions(instance);
3485 const publicThis = instance.proxy;
3486 const ctx = instance.ctx;
3487 // do not cache property access on public proxy during state initialization
3488 shouldCacheAccess = false;
3489 // call beforeCreate first before accessing other options since
3490 // the hook may mutate resolved options (#2791)
3491 if (options.beforeCreate) {
3492 callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
3493 }
3494 const {
3495 // state
3496 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
3497 // lifecycle
3498 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
3499 // public API
3500 expose, inheritAttrs,
3501 // assets
3502 components, directives, filters } = options;
3503 const checkDuplicateProperties = createDuplicateChecker() ;
3504 {
3505 const [propsOptions] = instance.propsOptions;
3506 if (propsOptions) {
3507 for (const key in propsOptions) {
3508 checkDuplicateProperties("Props" /* PROPS */, key);
3509 }
3510 }
3511 }
3512 // options initialization order (to be consistent with Vue 2):
3513 // - props (already done outside of this function)
3514 // - inject
3515 // - methods
3516 // - data (deferred since it relies on `this` access)
3517 // - computed
3518 // - watch (deferred since it relies on `this` access)
3519 if (injectOptions) {
3520 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
3521 }
3522 if (methods) {
3523 for (const key in methods) {
3524 const methodHandler = methods[key];
3525 if (isFunction(methodHandler)) {
3526 // In dev mode, we use the `createRenderContext` function to define
3527 // methods to the proxy target, and those are read-only but
3528 // reconfigurable, so it needs to be redefined here
3529 {
3530 Object.defineProperty(ctx, key, {
3531 value: methodHandler.bind(publicThis),
3532 configurable: true,
3533 enumerable: true,
3534 writable: true
3535 });
3536 }
3537 {
3538 checkDuplicateProperties("Methods" /* METHODS */, key);
3539 }
3540 }
3541 else {
3542 warn$1(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
3543 `Did you reference the function correctly?`);
3544 }
3545 }
3546 }
3547 if (dataOptions) {
3548 if (!isFunction(dataOptions)) {
3549 warn$1(`The data option must be a function. ` +
3550 `Plain object usage is no longer supported.`);
3551 }
3552 const data = dataOptions.call(publicThis, publicThis);
3553 if (isPromise(data)) {
3554 warn$1(`data() returned a Promise - note data() cannot be async; If you ` +
3555 `intend to perform data fetching before component renders, use ` +
3556 `async setup() + <Suspense>.`);
3557 }
3558 if (!isObject(data)) {
3559 warn$1(`data() should return an object.`);
3560 }
3561 else {
3562 instance.data = reactive(data);
3563 {
3564 for (const key in data) {
3565 checkDuplicateProperties("Data" /* DATA */, key);
3566 // expose data on ctx during dev
3567 if (key[0] !== '$' && key[0] !== '_') {
3568 Object.defineProperty(ctx, key, {
3569 configurable: true,
3570 enumerable: true,
3571 get: () => data[key],
3572 set: NOOP
3573 });
3574 }
3575 }
3576 }
3577 }
3578 }
3579 // state initialization complete at this point - start caching access
3580 shouldCacheAccess = true;
3581 if (computedOptions) {
3582 for (const key in computedOptions) {
3583 const opt = computedOptions[key];
3584 const get = isFunction(opt)
3585 ? opt.bind(publicThis, publicThis)
3586 : isFunction(opt.get)
3587 ? opt.get.bind(publicThis, publicThis)
3588 : NOOP;
3589 if (get === NOOP) {
3590 warn$1(`Computed property "${key}" has no getter.`);
3591 }
3592 const set = !isFunction(opt) && isFunction(opt.set)
3593 ? opt.set.bind(publicThis)
3594 : () => {
3595 warn$1(`Write operation failed: computed property "${key}" is readonly.`);
3596 }
3597 ;
3598 const c = computed({
3599 get,
3600 set
3601 });
3602 Object.defineProperty(ctx, key, {
3603 enumerable: true,
3604 configurable: true,
3605 get: () => c.value,
3606 set: v => (c.value = v)
3607 });
3608 {
3609 checkDuplicateProperties("Computed" /* COMPUTED */, key);
3610 }
3611 }
3612 }
3613 if (watchOptions) {
3614 for (const key in watchOptions) {
3615 createWatcher(watchOptions[key], ctx, publicThis, key);
3616 }
3617 }
3618 if (provideOptions) {
3619 const provides = isFunction(provideOptions)
3620 ? provideOptions.call(publicThis)
3621 : provideOptions;
3622 Reflect.ownKeys(provides).forEach(key => {
3623 provide(key, provides[key]);
3624 });
3625 }
3626 if (created) {
3627 callHook(created, instance, "c" /* CREATED */);
3628 }
3629 function registerLifecycleHook(register, hook) {
3630 if (isArray(hook)) {
3631 hook.forEach(_hook => register(_hook.bind(publicThis)));
3632 }
3633 else if (hook) {
3634 register(hook.bind(publicThis));
3635 }
3636 }
3637 registerLifecycleHook(onBeforeMount, beforeMount);
3638 registerLifecycleHook(onMounted, mounted);
3639 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
3640 registerLifecycleHook(onUpdated, updated);
3641 registerLifecycleHook(onActivated, activated);
3642 registerLifecycleHook(onDeactivated, deactivated);
3643 registerLifecycleHook(onErrorCaptured, errorCaptured);
3644 registerLifecycleHook(onRenderTracked, renderTracked);
3645 registerLifecycleHook(onRenderTriggered, renderTriggered);
3646 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
3647 registerLifecycleHook(onUnmounted, unmounted);
3648 registerLifecycleHook(onServerPrefetch, serverPrefetch);
3649 if (isArray(expose)) {
3650 if (expose.length) {
3651 const exposed = instance.exposed || (instance.exposed = {});
3652 expose.forEach(key => {
3653 Object.defineProperty(exposed, key, {
3654 get: () => publicThis[key],
3655 set: val => (publicThis[key] = val)
3656 });
3657 });
3658 }
3659 else if (!instance.exposed) {
3660 instance.exposed = {};
3661 }
3662 }
3663 // options that are handled when creating the instance but also need to be
3664 // applied from mixins
3665 if (render && instance.render === NOOP) {
3666 instance.render = render;
3667 }
3668 if (inheritAttrs != null) {
3669 instance.inheritAttrs = inheritAttrs;
3670 }
3671 // asset options.
3672 if (components)
3673 instance.components = components;
3674 if (directives)
3675 instance.directives = directives;
3676}
3677function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
3678 if (isArray(injectOptions)) {
3679 injectOptions = normalizeInject(injectOptions);
3680 }
3681 for (const key in injectOptions) {
3682 const opt = injectOptions[key];
3683 let injected;
3684 if (isObject(opt)) {
3685 if ('default' in opt) {
3686 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
3687 }
3688 else {
3689 injected = inject(opt.from || key);
3690 }
3691 }
3692 else {
3693 injected = inject(opt);
3694 }
3695 if (isRef(injected)) {
3696 // TODO remove the check in 3.3
3697 if (unwrapRef) {
3698 Object.defineProperty(ctx, key, {
3699 enumerable: true,
3700 configurable: true,
3701 get: () => injected.value,
3702 set: v => (injected.value = v)
3703 });
3704 }
3705 else {
3706 {
3707 warn$1(`injected property "${key}" is a ref and will be auto-unwrapped ` +
3708 `and no longer needs \`.value\` in the next minor release. ` +
3709 `To opt-in to the new behavior now, ` +
3710 `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
3711 `temporary and will not be needed in the future.)`);
3712 }
3713 ctx[key] = injected;
3714 }
3715 }
3716 else {
3717 ctx[key] = injected;
3718 }
3719 {
3720 checkDuplicateProperties("Inject" /* INJECT */, key);
3721 }
3722 }
3723}
3724function callHook(hook, instance, type) {
3725 callWithAsyncErrorHandling(isArray(hook)
3726 ? hook.map(h => h.bind(instance.proxy))
3727 : hook.bind(instance.proxy), instance, type);
3728}
3729function createWatcher(raw, ctx, publicThis, key) {
3730 const getter = key.includes('.')
3731 ? createPathGetter(publicThis, key)
3732 : () => publicThis[key];
3733 if (isString(raw)) {
3734 const handler = ctx[raw];
3735 if (isFunction(handler)) {
3736 watch(getter, handler);
3737 }
3738 else {
3739 warn$1(`Invalid watch handler specified by key "${raw}"`, handler);
3740 }
3741 }
3742 else if (isFunction(raw)) {
3743 watch(getter, raw.bind(publicThis));
3744 }
3745 else if (isObject(raw)) {
3746 if (isArray(raw)) {
3747 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
3748 }
3749 else {
3750 const handler = isFunction(raw.handler)
3751 ? raw.handler.bind(publicThis)
3752 : ctx[raw.handler];
3753 if (isFunction(handler)) {
3754 watch(getter, handler, raw);
3755 }
3756 else {
3757 warn$1(`Invalid watch handler specified by key "${raw.handler}"`, handler);
3758 }
3759 }
3760 }
3761 else {
3762 warn$1(`Invalid watch option: "${key}"`, raw);
3763 }
3764}
3765/**
3766 * Resolve merged options and cache it on the component.
3767 * This is done only once per-component since the merging does not involve
3768 * instances.
3769 */
3770function resolveMergedOptions(instance) {
3771 const base = instance.type;
3772 const { mixins, extends: extendsOptions } = base;
3773 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
3774 const cached = cache.get(base);
3775 let resolved;
3776 if (cached) {
3777 resolved = cached;
3778 }
3779 else if (!globalMixins.length && !mixins && !extendsOptions) {
3780 {
3781 resolved = base;
3782 }
3783 }
3784 else {
3785 resolved = {};
3786 if (globalMixins.length) {
3787 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
3788 }
3789 mergeOptions(resolved, base, optionMergeStrategies);
3790 }
3791 cache.set(base, resolved);
3792 return resolved;
3793}
3794function mergeOptions(to, from, strats, asMixin = false) {
3795 const { mixins, extends: extendsOptions } = from;
3796 if (extendsOptions) {
3797 mergeOptions(to, extendsOptions, strats, true);
3798 }
3799 if (mixins) {
3800 mixins.forEach((m) => mergeOptions(to, m, strats, true));
3801 }
3802 for (const key in from) {
3803 if (asMixin && key === 'expose') {
3804 warn$1(`"expose" option is ignored when declared in mixins or extends. ` +
3805 `It should only be declared in the base component itself.`);
3806 }
3807 else {
3808 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
3809 to[key] = strat ? strat(to[key], from[key]) : from[key];
3810 }
3811 }
3812 return to;
3813}
3814const internalOptionMergeStrats = {
3815 data: mergeDataFn,
3816 props: mergeObjectOptions,
3817 emits: mergeObjectOptions,
3818 // objects
3819 methods: mergeObjectOptions,
3820 computed: mergeObjectOptions,
3821 // lifecycle
3822 beforeCreate: mergeAsArray,
3823 created: mergeAsArray,
3824 beforeMount: mergeAsArray,
3825 mounted: mergeAsArray,
3826 beforeUpdate: mergeAsArray,
3827 updated: mergeAsArray,
3828 beforeDestroy: mergeAsArray,
3829 beforeUnmount: mergeAsArray,
3830 destroyed: mergeAsArray,
3831 unmounted: mergeAsArray,
3832 activated: mergeAsArray,
3833 deactivated: mergeAsArray,
3834 errorCaptured: mergeAsArray,
3835 serverPrefetch: mergeAsArray,
3836 // assets
3837 components: mergeObjectOptions,
3838 directives: mergeObjectOptions,
3839 // watch
3840 watch: mergeWatchOptions,
3841 // provide / inject
3842 provide: mergeDataFn,
3843 inject: mergeInject
3844};
3845function mergeDataFn(to, from) {
3846 if (!from) {
3847 return to;
3848 }
3849 if (!to) {
3850 return from;
3851 }
3852 return function mergedDataFn() {
3853 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
3854 };
3855}
3856function mergeInject(to, from) {
3857 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
3858}
3859function normalizeInject(raw) {
3860 if (isArray(raw)) {
3861 const res = {};
3862 for (let i = 0; i < raw.length; i++) {
3863 res[raw[i]] = raw[i];
3864 }
3865 return res;
3866 }
3867 return raw;
3868}
3869function mergeAsArray(to, from) {
3870 return to ? [...new Set([].concat(to, from))] : from;
3871}
3872function mergeObjectOptions(to, from) {
3873 return to ? extend(extend(Object.create(null), to), from) : from;
3874}
3875function mergeWatchOptions(to, from) {
3876 if (!to)
3877 return from;
3878 if (!from)
3879 return to;
3880 const merged = extend(Object.create(null), to);
3881 for (const key in from) {
3882 merged[key] = mergeAsArray(to[key], from[key]);
3883 }
3884 return merged;
3885}
3886
3887function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
3888isSSR = false) {
3889 const props = {};
3890 const attrs = {};
3891 def(attrs, InternalObjectKey, 1);
3892 instance.propsDefaults = Object.create(null);
3893 setFullProps(instance, rawProps, props, attrs);
3894 // ensure all declared prop keys are present
3895 for (const key in instance.propsOptions[0]) {
3896 if (!(key in props)) {
3897 props[key] = undefined;
3898 }
3899 }
3900 // validation
3901 {
3902 validateProps(rawProps || {}, props, instance);
3903 }
3904 if (isStateful) {
3905 // stateful
3906 instance.props = isSSR ? props : shallowReactive(props);
3907 }
3908 else {
3909 if (!instance.type.props) {
3910 // functional w/ optional props, props === attrs
3911 instance.props = attrs;
3912 }
3913 else {
3914 // functional w/ declared props
3915 instance.props = props;
3916 }
3917 }
3918 instance.attrs = attrs;
3919}
3920function updateProps(instance, rawProps, rawPrevProps, optimized) {
3921 const { props, attrs, vnode: { patchFlag } } = instance;
3922 const rawCurrentProps = toRaw(props);
3923 const [options] = instance.propsOptions;
3924 let hasAttrsChanged = false;
3925 if (
3926 // always force full diff in dev
3927 // - #1942 if hmr is enabled with sfc component
3928 // - vite#872 non-sfc component used by sfc component
3929 !((instance.type.__hmrId ||
3930 (instance.parent && instance.parent.type.__hmrId))) &&
3931 (optimized || patchFlag > 0) &&
3932 !(patchFlag & 16 /* FULL_PROPS */)) {
3933 if (patchFlag & 8 /* PROPS */) {
3934 // Compiler-generated props & no keys change, just set the updated
3935 // the props.
3936 const propsToUpdate = instance.vnode.dynamicProps;
3937 for (let i = 0; i < propsToUpdate.length; i++) {
3938 let key = propsToUpdate[i];
3939 // PROPS flag guarantees rawProps to be non-null
3940 const value = rawProps[key];
3941 if (options) {
3942 // attr / props separation was done on init and will be consistent
3943 // in this code path, so just check if attrs have it.
3944 if (hasOwn(attrs, key)) {
3945 if (value !== attrs[key]) {
3946 attrs[key] = value;
3947 hasAttrsChanged = true;
3948 }
3949 }
3950 else {
3951 const camelizedKey = camelize(key);
3952 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
3953 }
3954 }
3955 else {
3956 if (value !== attrs[key]) {
3957 attrs[key] = value;
3958 hasAttrsChanged = true;
3959 }
3960 }
3961 }
3962 }
3963 }
3964 else {
3965 // full props update.
3966 if (setFullProps(instance, rawProps, props, attrs)) {
3967 hasAttrsChanged = true;
3968 }
3969 // in case of dynamic props, check if we need to delete keys from
3970 // the props object
3971 let kebabKey;
3972 for (const key in rawCurrentProps) {
3973 if (!rawProps ||
3974 // for camelCase
3975 (!hasOwn(rawProps, key) &&
3976 // it's possible the original props was passed in as kebab-case
3977 // and converted to camelCase (#955)
3978 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
3979 if (options) {
3980 if (rawPrevProps &&
3981 // for camelCase
3982 (rawPrevProps[key] !== undefined ||
3983 // for kebab-case
3984 rawPrevProps[kebabKey] !== undefined)) {
3985 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
3986 }
3987 }
3988 else {
3989 delete props[key];
3990 }
3991 }
3992 }
3993 // in the case of functional component w/o props declaration, props and
3994 // attrs point to the same object so it should already have been updated.
3995 if (attrs !== rawCurrentProps) {
3996 for (const key in attrs) {
3997 if (!rawProps || !hasOwn(rawProps, key)) {
3998 delete attrs[key];
3999 hasAttrsChanged = true;
4000 }
4001 }
4002 }
4003 }
4004 // trigger updates for $attrs in case it's used in component slots
4005 if (hasAttrsChanged) {
4006 trigger(instance, "set" /* SET */, '$attrs');
4007 }
4008 {
4009 validateProps(rawProps || {}, props, instance);
4010 }
4011}
4012function setFullProps(instance, rawProps, props, attrs) {
4013 const [options, needCastKeys] = instance.propsOptions;
4014 let hasAttrsChanged = false;
4015 let rawCastValues;
4016 if (rawProps) {
4017 for (let key in rawProps) {
4018 // key, ref are reserved and never passed down
4019 if (isReservedProp(key)) {
4020 continue;
4021 }
4022 const value = rawProps[key];
4023 // prop option names are camelized during normalization, so to support
4024 // kebab -> camel conversion here we need to camelize the key.
4025 let camelKey;
4026 if (options && hasOwn(options, (camelKey = camelize(key)))) {
4027 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
4028 props[camelKey] = value;
4029 }
4030 else {
4031 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
4032 }
4033 }
4034 else if (!isEmitListener(instance.emitsOptions, key)) {
4035 if (value !== attrs[key]) {
4036 attrs[key] = value;
4037 hasAttrsChanged = true;
4038 }
4039 }
4040 }
4041 }
4042 if (needCastKeys) {
4043 const rawCurrentProps = toRaw(props);
4044 const castValues = rawCastValues || EMPTY_OBJ;
4045 for (let i = 0; i < needCastKeys.length; i++) {
4046 const key = needCastKeys[i];
4047 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
4048 }
4049 }
4050 return hasAttrsChanged;
4051}
4052function resolvePropValue(options, props, key, value, instance, isAbsent) {
4053 const opt = options[key];
4054 if (opt != null) {
4055 const hasDefault = hasOwn(opt, 'default');
4056 // default values
4057 if (hasDefault && value === undefined) {
4058 const defaultValue = opt.default;
4059 if (opt.type !== Function && isFunction(defaultValue)) {
4060 const { propsDefaults } = instance;
4061 if (key in propsDefaults) {
4062 value = propsDefaults[key];
4063 }
4064 else {
4065 setCurrentInstance(instance);
4066 value = propsDefaults[key] = defaultValue.call(null, props);
4067 unsetCurrentInstance();
4068 }
4069 }
4070 else {
4071 value = defaultValue;
4072 }
4073 }
4074 // boolean casting
4075 if (opt[0 /* shouldCast */]) {
4076 if (isAbsent && !hasDefault) {
4077 value = false;
4078 }
4079 else if (opt[1 /* shouldCastTrue */] &&
4080 (value === '' || value === hyphenate(key))) {
4081 value = true;
4082 }
4083 }
4084 }
4085 return value;
4086}
4087function normalizePropsOptions(comp, appContext, asMixin = false) {
4088 const cache = appContext.propsCache;
4089 const cached = cache.get(comp);
4090 if (cached) {
4091 return cached;
4092 }
4093 const raw = comp.props;
4094 const normalized = {};
4095 const needCastKeys = [];
4096 // apply mixin/extends props
4097 let hasExtends = false;
4098 if (!isFunction(comp)) {
4099 const extendProps = (raw) => {
4100 hasExtends = true;
4101 const [props, keys] = normalizePropsOptions(raw, appContext, true);
4102 extend(normalized, props);
4103 if (keys)
4104 needCastKeys.push(...keys);
4105 };
4106 if (!asMixin && appContext.mixins.length) {
4107 appContext.mixins.forEach(extendProps);
4108 }
4109 if (comp.extends) {
4110 extendProps(comp.extends);
4111 }
4112 if (comp.mixins) {
4113 comp.mixins.forEach(extendProps);
4114 }
4115 }
4116 if (!raw && !hasExtends) {
4117 cache.set(comp, EMPTY_ARR);
4118 return EMPTY_ARR;
4119 }
4120 if (isArray(raw)) {
4121 for (let i = 0; i < raw.length; i++) {
4122 if (!isString(raw[i])) {
4123 warn$1(`props must be strings when using array syntax.`, raw[i]);
4124 }
4125 const normalizedKey = camelize(raw[i]);
4126 if (validatePropName(normalizedKey)) {
4127 normalized[normalizedKey] = EMPTY_OBJ;
4128 }
4129 }
4130 }
4131 else if (raw) {
4132 if (!isObject(raw)) {
4133 warn$1(`invalid props options`, raw);
4134 }
4135 for (const key in raw) {
4136 const normalizedKey = camelize(key);
4137 if (validatePropName(normalizedKey)) {
4138 const opt = raw[key];
4139 const prop = (normalized[normalizedKey] =
4140 isArray(opt) || isFunction(opt) ? { type: opt } : opt);
4141 if (prop) {
4142 const booleanIndex = getTypeIndex(Boolean, prop.type);
4143 const stringIndex = getTypeIndex(String, prop.type);
4144 prop[0 /* shouldCast */] = booleanIndex > -1;
4145 prop[1 /* shouldCastTrue */] =
4146 stringIndex < 0 || booleanIndex < stringIndex;
4147 // if the prop needs boolean casting or default value
4148 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
4149 needCastKeys.push(normalizedKey);
4150 }
4151 }
4152 }
4153 }
4154 }
4155 const res = [normalized, needCastKeys];
4156 cache.set(comp, res);
4157 return res;
4158}
4159function validatePropName(key) {
4160 if (key[0] !== '$') {
4161 return true;
4162 }
4163 else {
4164 warn$1(`Invalid prop name: "${key}" is a reserved property.`);
4165 }
4166 return false;
4167}
4168// use function string name to check type constructors
4169// so that it works across vms / iframes.
4170function getType(ctor) {
4171 const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
4172 return match ? match[1] : ctor === null ? 'null' : '';
4173}
4174function isSameType(a, b) {
4175 return getType(a) === getType(b);
4176}
4177function getTypeIndex(type, expectedTypes) {
4178 if (isArray(expectedTypes)) {
4179 return expectedTypes.findIndex(t => isSameType(t, type));
4180 }
4181 else if (isFunction(expectedTypes)) {
4182 return isSameType(expectedTypes, type) ? 0 : -1;
4183 }
4184 return -1;
4185}
4186/**
4187 * dev only
4188 */
4189function validateProps(rawProps, props, instance) {
4190 const resolvedValues = toRaw(props);
4191 const options = instance.propsOptions[0];
4192 for (const key in options) {
4193 let opt = options[key];
4194 if (opt == null)
4195 continue;
4196 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
4197 }
4198}
4199/**
4200 * dev only
4201 */
4202function validateProp(name, value, prop, isAbsent) {
4203 const { type, required, validator } = prop;
4204 // required!
4205 if (required && isAbsent) {
4206 warn$1('Missing required prop: "' + name + '"');
4207 return;
4208 }
4209 // missing but optional
4210 if (value == null && !prop.required) {
4211 return;
4212 }
4213 // type check
4214 if (type != null && type !== true) {
4215 let isValid = false;
4216 const types = isArray(type) ? type : [type];
4217 const expectedTypes = [];
4218 // value is valid as long as one of the specified types match
4219 for (let i = 0; i < types.length && !isValid; i++) {
4220 const { valid, expectedType } = assertType(value, types[i]);
4221 expectedTypes.push(expectedType || '');
4222 isValid = valid;
4223 }
4224 if (!isValid) {
4225 warn$1(getInvalidTypeMessage(name, value, expectedTypes));
4226 return;
4227 }
4228 }
4229 // custom validator
4230 if (validator && !validator(value)) {
4231 warn$1('Invalid prop: custom validator check failed for prop "' + name + '".');
4232 }
4233}
4234const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
4235/**
4236 * dev only
4237 */
4238function assertType(value, type) {
4239 let valid;
4240 const expectedType = getType(type);
4241 if (isSimpleType(expectedType)) {
4242 const t = typeof value;
4243 valid = t === expectedType.toLowerCase();
4244 // for primitive wrapper objects
4245 if (!valid && t === 'object') {
4246 valid = value instanceof type;
4247 }
4248 }
4249 else if (expectedType === 'Object') {
4250 valid = isObject(value);
4251 }
4252 else if (expectedType === 'Array') {
4253 valid = isArray(value);
4254 }
4255 else if (expectedType === 'null') {
4256 valid = value === null;
4257 }
4258 else {
4259 valid = value instanceof type;
4260 }
4261 return {
4262 valid,
4263 expectedType
4264 };
4265}
4266/**
4267 * dev only
4268 */
4269function getInvalidTypeMessage(name, value, expectedTypes) {
4270 let message = `Invalid prop: type check failed for prop "${name}".` +
4271 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
4272 const expectedType = expectedTypes[0];
4273 const receivedType = toRawType(value);
4274 const expectedValue = styleValue(value, expectedType);
4275 const receivedValue = styleValue(value, receivedType);
4276 // check if we need to specify expected value
4277 if (expectedTypes.length === 1 &&
4278 isExplicable(expectedType) &&
4279 !isBoolean(expectedType, receivedType)) {
4280 message += ` with value ${expectedValue}`;
4281 }
4282 message += `, got ${receivedType} `;
4283 // check if we need to specify received value
4284 if (isExplicable(receivedType)) {
4285 message += `with value ${receivedValue}.`;
4286 }
4287 return message;
4288}
4289/**
4290 * dev only
4291 */
4292function styleValue(value, type) {
4293 if (type === 'String') {
4294 return `"${value}"`;
4295 }
4296 else if (type === 'Number') {
4297 return `${Number(value)}`;
4298 }
4299 else {
4300 return `${value}`;
4301 }
4302}
4303/**
4304 * dev only
4305 */
4306function isExplicable(type) {
4307 const explicitTypes = ['string', 'number', 'boolean'];
4308 return explicitTypes.some(elem => type.toLowerCase() === elem);
4309}
4310/**
4311 * dev only
4312 */
4313function isBoolean(...args) {
4314 return args.some(elem => elem.toLowerCase() === 'boolean');
4315}
4316
4317const isInternalKey = (key) => key[0] === '_' || key === '$stable';
4318const normalizeSlotValue = (value) => isArray(value)
4319 ? value.map(normalizeVNode)
4320 : [normalizeVNode(value)];
4321const normalizeSlot = (key, rawSlot, ctx) => {
4322 const normalized = withCtx((...args) => {
4323 if (currentInstance) {
4324 warn$1(`Slot "${key}" invoked outside of the render function: ` +
4325 `this will not track dependencies used in the slot. ` +
4326 `Invoke the slot function inside the render function instead.`);
4327 }
4328 return normalizeSlotValue(rawSlot(...args));
4329 }, ctx);
4330 normalized._c = false;
4331 return normalized;
4332};
4333const normalizeObjectSlots = (rawSlots, slots, instance) => {
4334 const ctx = rawSlots._ctx;
4335 for (const key in rawSlots) {
4336 if (isInternalKey(key))
4337 continue;
4338 const value = rawSlots[key];
4339 if (isFunction(value)) {
4340 slots[key] = normalizeSlot(key, value, ctx);
4341 }
4342 else if (value != null) {
4343 {
4344 warn$1(`Non-function value encountered for slot "${key}". ` +
4345 `Prefer function slots for better performance.`);
4346 }
4347 const normalized = normalizeSlotValue(value);
4348 slots[key] = () => normalized;
4349 }
4350 }
4351};
4352const normalizeVNodeSlots = (instance, children) => {
4353 if (!isKeepAlive(instance.vnode) &&
4354 !(false )) {
4355 warn$1(`Non-function value encountered for default slot. ` +
4356 `Prefer function slots for better performance.`);
4357 }
4358 const normalized = normalizeSlotValue(children);
4359 instance.slots.default = () => normalized;
4360};
4361const initSlots = (instance, children) => {
4362 if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4363 const type = children._;
4364 if (type) {
4365 // users can get the shallow readonly version of the slots object through `this.$slots`,
4366 // we should avoid the proxy object polluting the slots of the internal instance
4367 instance.slots = toRaw(children);
4368 // make compiler marker non-enumerable
4369 def(children, '_', type);
4370 }
4371 else {
4372 normalizeObjectSlots(children, (instance.slots = {}));
4373 }
4374 }
4375 else {
4376 instance.slots = {};
4377 if (children) {
4378 normalizeVNodeSlots(instance, children);
4379 }
4380 }
4381 def(instance.slots, InternalObjectKey, 1);
4382};
4383const updateSlots = (instance, children, optimized) => {
4384 const { vnode, slots } = instance;
4385 let needDeletionCheck = true;
4386 let deletionComparisonTarget = EMPTY_OBJ;
4387 if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
4388 const type = children._;
4389 if (type) {
4390 // compiled slots.
4391 if (isHmrUpdating) {
4392 // Parent was HMR updated so slot content may have changed.
4393 // force update slots and mark instance for hmr as well
4394 extend(slots, children);
4395 }
4396 else if (optimized && type === 1 /* STABLE */) {
4397 // compiled AND stable.
4398 // no need to update, and skip stale slots removal.
4399 needDeletionCheck = false;
4400 }
4401 else {
4402 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
4403 // normalization.
4404 extend(slots, children);
4405 // #2893
4406 // when rendering the optimized slots by manually written render function,
4407 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
4408 // i.e. let the `renderSlot` create the bailed Fragment
4409 if (!optimized && type === 1 /* STABLE */) {
4410 delete slots._;
4411 }
4412 }
4413 }
4414 else {
4415 needDeletionCheck = !children.$stable;
4416 normalizeObjectSlots(children, slots);
4417 }
4418 deletionComparisonTarget = children;
4419 }
4420 else if (children) {
4421 // non slot object children (direct value) passed to a component
4422 normalizeVNodeSlots(instance, children);
4423 deletionComparisonTarget = { default: 1 };
4424 }
4425 // delete stale slots
4426 if (needDeletionCheck) {
4427 for (const key in slots) {
4428 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
4429 delete slots[key];
4430 }
4431 }
4432 }
4433};
4434
4435/**
4436Runtime helper for applying directives to a vnode. Example usage:
4437
4438const comp = resolveComponent('comp')
4439const foo = resolveDirective('foo')
4440const bar = resolveDirective('bar')
4441
4442return withDirectives(h(comp), [
4443 [foo, this.x],
4444 [bar, this.y]
4445])
4446*/
4447const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
4448function validateDirectiveName(name) {
4449 if (isBuiltInDirective(name)) {
4450 warn$1('Do not use built-in directive ids as custom directive id: ' + name);
4451 }
4452}
4453/**
4454 * Adds directives to a VNode.
4455 */
4456function withDirectives(vnode, directives) {
4457 const internalInstance = currentRenderingInstance;
4458 if (internalInstance === null) {
4459 warn$1(`withDirectives can only be used inside render functions.`);
4460 return vnode;
4461 }
4462 const instance = internalInstance.proxy;
4463 const bindings = vnode.dirs || (vnode.dirs = []);
4464 for (let i = 0; i < directives.length; i++) {
4465 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4466 if (isFunction(dir)) {
4467 dir = {
4468 mounted: dir,
4469 updated: dir
4470 };
4471 }
4472 if (dir.deep) {
4473 traverse(value);
4474 }
4475 bindings.push({
4476 dir,
4477 instance,
4478 value,
4479 oldValue: void 0,
4480 arg,
4481 modifiers
4482 });
4483 }
4484 return vnode;
4485}
4486function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4487 const bindings = vnode.dirs;
4488 const oldBindings = prevVNode && prevVNode.dirs;
4489 for (let i = 0; i < bindings.length; i++) {
4490 const binding = bindings[i];
4491 if (oldBindings) {
4492 binding.oldValue = oldBindings[i].value;
4493 }
4494 let hook = binding.dir[name];
4495 if (hook) {
4496 // disable tracking inside all lifecycle hooks
4497 // since they can potentially be called inside effects.
4498 pauseTracking();
4499 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
4500 vnode.el,
4501 binding,
4502 vnode,
4503 prevVNode
4504 ]);
4505 resetTracking();
4506 }
4507 }
4508}
4509
4510function createAppContext() {
4511 return {
4512 app: null,
4513 config: {
4514 isNativeTag: NO,
4515 performance: false,
4516 globalProperties: {},
4517 optionMergeStrategies: {},
4518 errorHandler: undefined,
4519 warnHandler: undefined,
4520 compilerOptions: {}
4521 },
4522 mixins: [],
4523 components: {},
4524 directives: {},
4525 provides: Object.create(null),
4526 optionsCache: new WeakMap(),
4527 propsCache: new WeakMap(),
4528 emitsCache: new WeakMap()
4529 };
4530}
4531let uid = 0;
4532function createAppAPI(render, hydrate) {
4533 return function createApp(rootComponent, rootProps = null) {
4534 if (rootProps != null && !isObject(rootProps)) {
4535 warn$1(`root props passed to app.mount() must be an object.`);
4536 rootProps = null;
4537 }
4538 const context = createAppContext();
4539 const installedPlugins = new Set();
4540 let isMounted = false;
4541 const app = (context.app = {
4542 _uid: uid++,
4543 _component: rootComponent,
4544 _props: rootProps,
4545 _container: null,
4546 _context: context,
4547 _instance: null,
4548 version,
4549 get config() {
4550 return context.config;
4551 },
4552 set config(v) {
4553 {
4554 warn$1(`app.config cannot be replaced. Modify individual options instead.`);
4555 }
4556 },
4557 use(plugin, ...options) {
4558 if (installedPlugins.has(plugin)) {
4559 warn$1(`Plugin has already been applied to target app.`);
4560 }
4561 else if (plugin && isFunction(plugin.install)) {
4562 installedPlugins.add(plugin);
4563 plugin.install(app, ...options);
4564 }
4565 else if (isFunction(plugin)) {
4566 installedPlugins.add(plugin);
4567 plugin(app, ...options);
4568 }
4569 else {
4570 warn$1(`A plugin must either be a function or an object with an "install" ` +
4571 `function.`);
4572 }
4573 return app;
4574 },
4575 mixin(mixin) {
4576 {
4577 if (!context.mixins.includes(mixin)) {
4578 context.mixins.push(mixin);
4579 }
4580 else {
4581 warn$1('Mixin has already been applied to target app' +
4582 (mixin.name ? `: ${mixin.name}` : ''));
4583 }
4584 }
4585 return app;
4586 },
4587 component(name, component) {
4588 {
4589 validateComponentName(name, context.config);
4590 }
4591 if (!component) {
4592 return context.components[name];
4593 }
4594 if (context.components[name]) {
4595 warn$1(`Component "${name}" has already been registered in target app.`);
4596 }
4597 context.components[name] = component;
4598 return app;
4599 },
4600 directive(name, directive) {
4601 {
4602 validateDirectiveName(name);
4603 }
4604 if (!directive) {
4605 return context.directives[name];
4606 }
4607 if (context.directives[name]) {
4608 warn$1(`Directive "${name}" has already been registered in target app.`);
4609 }
4610 context.directives[name] = directive;
4611 return app;
4612 },
4613 mount(rootContainer, isHydrate, isSVG) {
4614 if (!isMounted) {
4615 const vnode = createVNode(rootComponent, rootProps);
4616 // store app context on the root VNode.
4617 // this will be set on the root instance on initial mount.
4618 vnode.appContext = context;
4619 // HMR root reload
4620 {
4621 context.reload = () => {
4622 render(cloneVNode(vnode), rootContainer, isSVG);
4623 };
4624 }
4625 if (isHydrate && hydrate) {
4626 hydrate(vnode, rootContainer);
4627 }
4628 else {
4629 render(vnode, rootContainer, isSVG);
4630 }
4631 isMounted = true;
4632 app._container = rootContainer;
4633 rootContainer.__vue_app__ = app;
4634 {
4635 app._instance = vnode.component;
4636 devtoolsInitApp(app, version);
4637 }
4638 return getExposeProxy(vnode.component) || vnode.component.proxy;
4639 }
4640 else {
4641 warn$1(`App has already been mounted.\n` +
4642 `If you want to remount the same app, move your app creation logic ` +
4643 `into a factory function and create fresh app instances for each ` +
4644 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
4645 }
4646 },
4647 unmount() {
4648 if (isMounted) {
4649 render(null, app._container);
4650 {
4651 app._instance = null;
4652 devtoolsUnmountApp(app);
4653 }
4654 delete app._container.__vue_app__;
4655 }
4656 else {
4657 warn$1(`Cannot unmount an app that is not mounted.`);
4658 }
4659 },
4660 provide(key, value) {
4661 if (key in context.provides) {
4662 warn$1(`App already provides property with key "${String(key)}". ` +
4663 `It will be overwritten with the new value.`);
4664 }
4665 // TypeScript doesn't allow symbols as index type
4666 // https://github.com/Microsoft/TypeScript/issues/24587
4667 context.provides[key] = value;
4668 return app;
4669 }
4670 });
4671 return app;
4672 };
4673}
4674
4675let hasMismatch = false;
4676const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4677const isComment = (node) => node.nodeType === 8 /* COMMENT */;
4678// Note: hydration is DOM-specific
4679// But we have to place it in core due to tight coupling with core - splitting
4680// it out creates a ton of unnecessary complexity.
4681// Hydration also depends on some renderer internal logic which needs to be
4682// passed in via arguments.
4683function createHydrationFunctions(rendererInternals) {
4684 const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
4685 const hydrate = (vnode, container) => {
4686 if (!container.hasChildNodes()) {
4687 warn$1(`Attempting to hydrate existing markup but container is empty. ` +
4688 `Performing full mount instead.`);
4689 patch(null, vnode, container);
4690 flushPostFlushCbs();
4691 return;
4692 }
4693 hasMismatch = false;
4694 hydrateNode(container.firstChild, vnode, null, null, null);
4695 flushPostFlushCbs();
4696 if (hasMismatch && !false) {
4697 // this error should show up in production
4698 console.error(`Hydration completed but contains mismatches.`);
4699 }
4700 };
4701 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
4702 const isFragmentStart = isComment(node) && node.data === '[';
4703 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
4704 const { type, ref, shapeFlag } = vnode;
4705 const domType = node.nodeType;
4706 vnode.el = node;
4707 let nextNode = null;
4708 switch (type) {
4709 case Text:
4710 if (domType !== 3 /* TEXT */) {
4711 nextNode = onMismatch();
4712 }
4713 else {
4714 if (node.data !== vnode.children) {
4715 hasMismatch = true;
4716 warn$1(`Hydration text mismatch:` +
4717 `\n- Client: ${JSON.stringify(node.data)}` +
4718 `\n- Server: ${JSON.stringify(vnode.children)}`);
4719 node.data = vnode.children;
4720 }
4721 nextNode = nextSibling(node);
4722 }
4723 break;
4724 case Comment:
4725 if (domType !== 8 /* COMMENT */ || isFragmentStart) {
4726 nextNode = onMismatch();
4727 }
4728 else {
4729 nextNode = nextSibling(node);
4730 }
4731 break;
4732 case Static:
4733 if (domType !== 1 /* ELEMENT */) {
4734 nextNode = onMismatch();
4735 }
4736 else {
4737 // determine anchor, adopt content
4738 nextNode = node;
4739 // if the static vnode has its content stripped during build,
4740 // adopt it from the server-rendered HTML.
4741 const needToAdoptContent = !vnode.children.length;
4742 for (let i = 0; i < vnode.staticCount; i++) {
4743 if (needToAdoptContent)
4744 vnode.children += nextNode.outerHTML;
4745 if (i === vnode.staticCount - 1) {
4746 vnode.anchor = nextNode;
4747 }
4748 nextNode = nextSibling(nextNode);
4749 }
4750 return nextNode;
4751 }
4752 break;
4753 case Fragment:
4754 if (!isFragmentStart) {
4755 nextNode = onMismatch();
4756 }
4757 else {
4758 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4759 }
4760 break;
4761 default:
4762 if (shapeFlag & 1 /* ELEMENT */) {
4763 if (domType !== 1 /* ELEMENT */ ||
4764 vnode.type.toLowerCase() !==
4765 node.tagName.toLowerCase()) {
4766 nextNode = onMismatch();
4767 }
4768 else {
4769 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4770 }
4771 }
4772 else if (shapeFlag & 6 /* COMPONENT */) {
4773 // when setting up the render effect, if the initial vnode already
4774 // has .el set, the component will perform hydration instead of mount
4775 // on its sub-tree.
4776 vnode.slotScopeIds = slotScopeIds;
4777 const container = parentNode(node);
4778 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
4779 // component may be async, so in the case of fragments we cannot rely
4780 // on component's rendered output to determine the end of the fragment
4781 // instead, we do a lookahead to find the end anchor node.
4782 nextNode = isFragmentStart
4783 ? locateClosingAsyncAnchor(node)
4784 : nextSibling(node);
4785 // #3787
4786 // if component is async, it may get moved / unmounted before its
4787 // inner component is loaded, so we need to give it a placeholder
4788 // vnode that matches its adopted DOM.
4789 if (isAsyncWrapper(vnode)) {
4790 let subTree;
4791 if (isFragmentStart) {
4792 subTree = createVNode(Fragment);
4793 subTree.anchor = nextNode
4794 ? nextNode.previousSibling
4795 : container.lastChild;
4796 }
4797 else {
4798 subTree =
4799 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
4800 }
4801 subTree.el = node;
4802 vnode.component.subTree = subTree;
4803 }
4804 }
4805 else if (shapeFlag & 64 /* TELEPORT */) {
4806 if (domType !== 8 /* COMMENT */) {
4807 nextNode = onMismatch();
4808 }
4809 else {
4810 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
4811 }
4812 }
4813 else if (shapeFlag & 128 /* SUSPENSE */) {
4814 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
4815 }
4816 else {
4817 warn$1('Invalid HostVNode type:', type, `(${typeof type})`);
4818 }
4819 }
4820 if (ref != null) {
4821 setRef(ref, null, parentSuspense, vnode);
4822 }
4823 return nextNode;
4824 };
4825 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4826 optimized = optimized || !!vnode.dynamicChildren;
4827 const { type, props, patchFlag, shapeFlag, dirs } = vnode;
4828 // #4006 for form elements with non-string v-model value bindings
4829 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
4830 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
4831 // skip props & children if this is hoisted static nodes
4832 if (forcePatchValue || patchFlag !== -1 /* HOISTED */) {
4833 if (dirs) {
4834 invokeDirectiveHook(vnode, null, parentComponent, 'created');
4835 }
4836 // props
4837 if (props) {
4838 if (forcePatchValue ||
4839 !optimized ||
4840 patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) {
4841 for (const key in props) {
4842 if ((forcePatchValue && key.endsWith('value')) ||
4843 (isOn(key) && !isReservedProp(key))) {
4844 patchProp(el, key, null, props[key], false, undefined, parentComponent);
4845 }
4846 }
4847 }
4848 else if (props.onClick) {
4849 // Fast path for click listeners (which is most often) to avoid
4850 // iterating through props.
4851 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent);
4852 }
4853 }
4854 // vnode / directive hooks
4855 let vnodeHooks;
4856 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
4857 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4858 }
4859 if (dirs) {
4860 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
4861 }
4862 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
4863 queueEffectWithSuspense(() => {
4864 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
4865 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
4866 }, parentSuspense);
4867 }
4868 // children
4869 if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
4870 // skip if element has innerHTML / textContent
4871 !(props && (props.innerHTML || props.textContent))) {
4872 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
4873 let hasWarned = false;
4874 while (next) {
4875 hasMismatch = true;
4876 if (!hasWarned) {
4877 warn$1(`Hydration children mismatch in <${vnode.type}>: ` +
4878 `server rendered element contains more child nodes than client vdom.`);
4879 hasWarned = true;
4880 }
4881 // The SSRed DOM contains more nodes than it should. Remove them.
4882 const cur = next;
4883 next = next.nextSibling;
4884 remove(cur);
4885 }
4886 }
4887 else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
4888 if (el.textContent !== vnode.children) {
4889 hasMismatch = true;
4890 warn$1(`Hydration text content mismatch in <${vnode.type}>:\n` +
4891 `- Client: ${el.textContent}\n` +
4892 `- Server: ${vnode.children}`);
4893 el.textContent = vnode.children;
4894 }
4895 }
4896 }
4897 return el.nextSibling;
4898 };
4899 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4900 optimized = optimized || !!parentVNode.dynamicChildren;
4901 const children = parentVNode.children;
4902 const l = children.length;
4903 let hasWarned = false;
4904 for (let i = 0; i < l; i++) {
4905 const vnode = optimized
4906 ? children[i]
4907 : (children[i] = normalizeVNode(children[i]));
4908 if (node) {
4909 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
4910 }
4911 else if (vnode.type === Text && !vnode.children) {
4912 continue;
4913 }
4914 else {
4915 hasMismatch = true;
4916 if (!hasWarned) {
4917 warn$1(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
4918 `server rendered element contains fewer child nodes than client vdom.`);
4919 hasWarned = true;
4920 }
4921 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
4922 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
4923 }
4924 }
4925 return node;
4926 };
4927 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
4928 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
4929 if (fragmentSlotScopeIds) {
4930 slotScopeIds = slotScopeIds
4931 ? slotScopeIds.concat(fragmentSlotScopeIds)
4932 : fragmentSlotScopeIds;
4933 }
4934 const container = parentNode(node);
4935 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
4936 if (next && isComment(next) && next.data === ']') {
4937 return nextSibling((vnode.anchor = next));
4938 }
4939 else {
4940 // fragment didn't hydrate successfully, since we didn't get a end anchor
4941 // back. This should have led to node/children mismatch warnings.
4942 hasMismatch = true;
4943 // since the anchor is missing, we need to create one and insert it
4944 insert((vnode.anchor = createComment(`]`)), container, next);
4945 return next;
4946 }
4947 };
4948 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
4949 hasMismatch = true;
4950 warn$1(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
4951 ? `(text)`
4952 : isComment(node) && node.data === '['
4953 ? `(start of fragment)`
4954 : ``);
4955 vnode.el = null;
4956 if (isFragment) {
4957 // remove excessive fragment nodes
4958 const end = locateClosingAsyncAnchor(node);
4959 while (true) {
4960 const next = nextSibling(node);
4961 if (next && next !== end) {
4962 remove(next);
4963 }
4964 else {
4965 break;
4966 }
4967 }
4968 }
4969 const next = nextSibling(node);
4970 const container = parentNode(node);
4971 remove(node);
4972 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
4973 return next;
4974 };
4975 const locateClosingAsyncAnchor = (node) => {
4976 let match = 0;
4977 while (node) {
4978 node = nextSibling(node);
4979 if (node && isComment(node)) {
4980 if (node.data === '[')
4981 match++;
4982 if (node.data === ']') {
4983 if (match === 0) {
4984 return nextSibling(node);
4985 }
4986 else {
4987 match--;
4988 }
4989 }
4990 }
4991 }
4992 return node;
4993 };
4994 return [hydrate, hydrateNode];
4995}
4996
4997let supported;
4998let perf;
4999function startMeasure(instance, type) {
5000 if (instance.appContext.config.performance && isSupported()) {
5001 perf.mark(`vue-${type}-${instance.uid}`);
5002 }
5003 {
5004 devtoolsPerfStart(instance, type, supported ? perf.now() : Date.now());
5005 }
5006}
5007function endMeasure(instance, type) {
5008 if (instance.appContext.config.performance && isSupported()) {
5009 const startTag = `vue-${type}-${instance.uid}`;
5010 const endTag = startTag + `:end`;
5011 perf.mark(endTag);
5012 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
5013 perf.clearMarks(startTag);
5014 perf.clearMarks(endTag);
5015 }
5016 {
5017 devtoolsPerfEnd(instance, type, supported ? perf.now() : Date.now());
5018 }
5019}
5020function isSupported() {
5021 if (supported !== undefined) {
5022 return supported;
5023 }
5024 /* eslint-disable no-restricted-globals */
5025 if (typeof window !== 'undefined' && window.performance) {
5026 supported = true;
5027 perf = window.performance;
5028 }
5029 else {
5030 supported = false;
5031 }
5032 /* eslint-enable no-restricted-globals */
5033 return supported;
5034}
5035
5036const queuePostRenderEffect = queueEffectWithSuspense
5037 ;
5038/**
5039 * The createRenderer function accepts two generic arguments:
5040 * HostNode and HostElement, corresponding to Node and Element types in the
5041 * host environment. For example, for runtime-dom, HostNode would be the DOM
5042 * `Node` interface and HostElement would be the DOM `Element` interface.
5043 *
5044 * Custom renderers can pass in the platform specific types like this:
5045 *
5046 * ``` js
5047 * const { render, createApp } = createRenderer<Node, Element>({
5048 * patchProp,
5049 * ...nodeOps
5050 * })
5051 * ```
5052 */
5053function createRenderer(options) {
5054 return baseCreateRenderer(options);
5055}
5056// Separate API for creating hydration-enabled renderer.
5057// Hydration logic is only used when calling this function, making it
5058// tree-shakable.
5059function createHydrationRenderer(options) {
5060 return baseCreateRenderer(options, createHydrationFunctions);
5061}
5062// implementation
5063function baseCreateRenderer(options, createHydrationFns) {
5064 const target = getGlobalThis();
5065 target.__VUE__ = true;
5066 {
5067 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
5068 }
5069 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
5070 // Note: functions inside this closure should use `const xxx = () => {}`
5071 // style in order to prevent being inlined by minifiers.
5072 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
5073 if (n1 === n2) {
5074 return;
5075 }
5076 // patching & not same type, unmount old tree
5077 if (n1 && !isSameVNodeType(n1, n2)) {
5078 anchor = getNextHostNode(n1);
5079 unmount(n1, parentComponent, parentSuspense, true);
5080 n1 = null;
5081 }
5082 if (n2.patchFlag === -2 /* BAIL */) {
5083 optimized = false;
5084 n2.dynamicChildren = null;
5085 }
5086 const { type, ref, shapeFlag } = n2;
5087 switch (type) {
5088 case Text:
5089 processText(n1, n2, container, anchor);
5090 break;
5091 case Comment:
5092 processCommentNode(n1, n2, container, anchor);
5093 break;
5094 case Static:
5095 if (n1 == null) {
5096 mountStaticNode(n2, container, anchor, isSVG);
5097 }
5098 else {
5099 patchStaticNode(n1, n2, container, isSVG);
5100 }
5101 break;
5102 case Fragment:
5103 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5104 break;
5105 default:
5106 if (shapeFlag & 1 /* ELEMENT */) {
5107 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5108 }
5109 else if (shapeFlag & 6 /* COMPONENT */) {
5110 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5111 }
5112 else if (shapeFlag & 64 /* TELEPORT */) {
5113 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
5114 }
5115 else if (shapeFlag & 128 /* SUSPENSE */) {
5116 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
5117 }
5118 else {
5119 warn$1('Invalid VNode type:', type, `(${typeof type})`);
5120 }
5121 }
5122 // set ref
5123 if (ref != null && parentComponent) {
5124 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
5125 }
5126 };
5127 const processText = (n1, n2, container, anchor) => {
5128 if (n1 == null) {
5129 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
5130 }
5131 else {
5132 const el = (n2.el = n1.el);
5133 if (n2.children !== n1.children) {
5134 hostSetText(el, n2.children);
5135 }
5136 }
5137 };
5138 const processCommentNode = (n1, n2, container, anchor) => {
5139 if (n1 == null) {
5140 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
5141 }
5142 else {
5143 // there's no support for dynamic comments
5144 n2.el = n1.el;
5145 }
5146 };
5147 const mountStaticNode = (n2, container, anchor, isSVG) => {
5148 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5149 };
5150 /**
5151 * Dev / HMR only
5152 */
5153 const patchStaticNode = (n1, n2, container, isSVG) => {
5154 // static nodes are only patched during dev for HMR
5155 if (n2.children !== n1.children) {
5156 const anchor = hostNextSibling(n1.anchor);
5157 // remove existing
5158 removeStaticNode(n1);
5159 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
5160 }
5161 else {
5162 n2.el = n1.el;
5163 n2.anchor = n1.anchor;
5164 }
5165 };
5166 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
5167 let next;
5168 while (el && el !== anchor) {
5169 next = hostNextSibling(el);
5170 hostInsert(el, container, nextSibling);
5171 el = next;
5172 }
5173 hostInsert(anchor, container, nextSibling);
5174 };
5175 const removeStaticNode = ({ el, anchor }) => {
5176 let next;
5177 while (el && el !== anchor) {
5178 next = hostNextSibling(el);
5179 hostRemove(el);
5180 el = next;
5181 }
5182 hostRemove(anchor);
5183 };
5184 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5185 isSVG = isSVG || n2.type === 'svg';
5186 if (n1 == null) {
5187 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5188 }
5189 else {
5190 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5191 }
5192 };
5193 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5194 let el;
5195 let vnodeHook;
5196 const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
5197 {
5198 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
5199 // mount children first, since some props may rely on child content
5200 // being already rendered, e.g. `<select value>`
5201 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5202 hostSetElementText(el, vnode.children);
5203 }
5204 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5205 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
5206 }
5207 if (dirs) {
5208 invokeDirectiveHook(vnode, null, parentComponent, 'created');
5209 }
5210 // props
5211 if (props) {
5212 for (const key in props) {
5213 if (key !== 'value' && !isReservedProp(key)) {
5214 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5215 }
5216 }
5217 /**
5218 * Special case for setting value on DOM elements:
5219 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
5220 * - it needs to be forced (#1471)
5221 * #2353 proposes adding another renderer option to configure this, but
5222 * the properties affects are so finite it is worth special casing it
5223 * here to reduce the complexity. (Special casing it also should not
5224 * affect non-DOM renderers)
5225 */
5226 if ('value' in props) {
5227 hostPatchProp(el, 'value', null, props.value);
5228 }
5229 if ((vnodeHook = props.onVnodeBeforeMount)) {
5230 invokeVNodeHook(vnodeHook, parentComponent, vnode);
5231 }
5232 }
5233 // scopeId
5234 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
5235 }
5236 {
5237 Object.defineProperty(el, '__vnode', {
5238 value: vnode,
5239 enumerable: false
5240 });
5241 Object.defineProperty(el, '__vueParentComponent', {
5242 value: parentComponent,
5243 enumerable: false
5244 });
5245 }
5246 if (dirs) {
5247 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
5248 }
5249 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
5250 // #1689 For inside suspense + suspense resolved case, just call it
5251 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
5252 transition &&
5253 !transition.persisted;
5254 if (needCallTransitionHooks) {
5255 transition.beforeEnter(el);
5256 }
5257 hostInsert(el, container, anchor);
5258 if ((vnodeHook = props && props.onVnodeMounted) ||
5259 needCallTransitionHooks ||
5260 dirs) {
5261 queuePostRenderEffect(() => {
5262 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
5263 needCallTransitionHooks && transition.enter(el);
5264 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
5265 }, parentSuspense);
5266 }
5267 };
5268 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
5269 if (scopeId) {
5270 hostSetScopeId(el, scopeId);
5271 }
5272 if (slotScopeIds) {
5273 for (let i = 0; i < slotScopeIds.length; i++) {
5274 hostSetScopeId(el, slotScopeIds[i]);
5275 }
5276 }
5277 if (parentComponent) {
5278 let subTree = parentComponent.subTree;
5279 if (subTree.patchFlag > 0 &&
5280 subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
5281 subTree =
5282 filterSingleRoot(subTree.children) || subTree;
5283 }
5284 if (vnode === subTree) {
5285 const parentVNode = parentComponent.vnode;
5286 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
5287 }
5288 }
5289 };
5290 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
5291 for (let i = start; i < children.length; i++) {
5292 const child = (children[i] = optimized
5293 ? cloneIfMounted(children[i])
5294 : normalizeVNode(children[i]));
5295 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5296 }
5297 };
5298 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5299 const el = (n2.el = n1.el);
5300 let { patchFlag, dynamicChildren, dirs } = n2;
5301 // #1426 take the old vnode's patch flag into account since user may clone a
5302 // compiler-generated vnode, which de-opts to FULL_PROPS
5303 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
5304 const oldProps = n1.props || EMPTY_OBJ;
5305 const newProps = n2.props || EMPTY_OBJ;
5306 let vnodeHook;
5307 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5308 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5309 }
5310 if (dirs) {
5311 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5312 }
5313 if (isHmrUpdating) {
5314 // HMR updated, force full diff
5315 patchFlag = 0;
5316 optimized = false;
5317 dynamicChildren = null;
5318 }
5319 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
5320 if (dynamicChildren) {
5321 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
5322 if (parentComponent && parentComponent.type.__hmrId) {
5323 traverseStaticChildren(n1, n2);
5324 }
5325 }
5326 else if (!optimized) {
5327 // full diff
5328 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
5329 }
5330 if (patchFlag > 0) {
5331 // the presence of a patchFlag means this element's render code was
5332 // generated by the compiler and can take the fast path.
5333 // in this path old node and new node are guaranteed to have the same shape
5334 // (i.e. at the exact same position in the source template)
5335 if (patchFlag & 16 /* FULL_PROPS */) {
5336 // element props contain dynamic keys, full diff needed
5337 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5338 }
5339 else {
5340 // class
5341 // this flag is matched when the element has dynamic class bindings.
5342 if (patchFlag & 2 /* CLASS */) {
5343 if (oldProps.class !== newProps.class) {
5344 hostPatchProp(el, 'class', null, newProps.class, isSVG);
5345 }
5346 }
5347 // style
5348 // this flag is matched when the element has dynamic style bindings
5349 if (patchFlag & 4 /* STYLE */) {
5350 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
5351 }
5352 // props
5353 // This flag is matched when the element has dynamic prop/attr bindings
5354 // other than class and style. The keys of dynamic prop/attrs are saved for
5355 // faster iteration.
5356 // Note dynamic keys like :[foo]="bar" will cause this optimization to
5357 // bail out and go through a full diff because we need to unset the old key
5358 if (patchFlag & 8 /* PROPS */) {
5359 // if the flag is present then dynamicProps must be non-null
5360 const propsToUpdate = n2.dynamicProps;
5361 for (let i = 0; i < propsToUpdate.length; i++) {
5362 const key = propsToUpdate[i];
5363 const prev = oldProps[key];
5364 const next = newProps[key];
5365 // #1471 force patch value
5366 if (next !== prev || key === 'value') {
5367 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
5368 }
5369 }
5370 }
5371 }
5372 // text
5373 // This flag is matched when the element has only dynamic text children.
5374 if (patchFlag & 1 /* TEXT */) {
5375 if (n1.children !== n2.children) {
5376 hostSetElementText(el, n2.children);
5377 }
5378 }
5379 }
5380 else if (!optimized && dynamicChildren == null) {
5381 // unoptimized, full diff
5382 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
5383 }
5384 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
5385 queuePostRenderEffect(() => {
5386 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5387 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
5388 }, parentSuspense);
5389 }
5390 };
5391 // The fast path for blocks.
5392 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
5393 for (let i = 0; i < newChildren.length; i++) {
5394 const oldVNode = oldChildren[i];
5395 const newVNode = newChildren[i];
5396 // Determine the container (parent element) for the patch.
5397 const container =
5398 // oldVNode may be an errored async setup() component inside Suspense
5399 // which will not have a mounted element
5400 oldVNode.el &&
5401 // - In the case of a Fragment, we need to provide the actual parent
5402 // of the Fragment itself so it can move its children.
5403 (oldVNode.type === Fragment ||
5404 // - In the case of different nodes, there is going to be a replacement
5405 // which also requires the correct parent container
5406 !isSameVNodeType(oldVNode, newVNode) ||
5407 // - In the case of a component, it could contain anything.
5408 oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */))
5409 ? hostParentNode(oldVNode.el)
5410 : // In other cases, the parent container is not actually used so we
5411 // just pass the block element here to avoid a DOM parentNode call.
5412 fallbackContainer;
5413 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
5414 }
5415 };
5416 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
5417 if (oldProps !== newProps) {
5418 for (const key in newProps) {
5419 // empty string is not valid prop
5420 if (isReservedProp(key))
5421 continue;
5422 const next = newProps[key];
5423 const prev = oldProps[key];
5424 // defer patching value
5425 if (next !== prev && key !== 'value') {
5426 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5427 }
5428 }
5429 if (oldProps !== EMPTY_OBJ) {
5430 for (const key in oldProps) {
5431 if (!isReservedProp(key) && !(key in newProps)) {
5432 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
5433 }
5434 }
5435 }
5436 if ('value' in newProps) {
5437 hostPatchProp(el, 'value', oldProps.value, newProps.value);
5438 }
5439 }
5440 };
5441 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5442 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
5443 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
5444 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
5445 if (isHmrUpdating) {
5446 // HMR updated, force full diff
5447 patchFlag = 0;
5448 optimized = false;
5449 dynamicChildren = null;
5450 }
5451 // check if this is a slot fragment with :slotted scope ids
5452 if (fragmentSlotScopeIds) {
5453 slotScopeIds = slotScopeIds
5454 ? slotScopeIds.concat(fragmentSlotScopeIds)
5455 : fragmentSlotScopeIds;
5456 }
5457 if (n1 == null) {
5458 hostInsert(fragmentStartAnchor, container, anchor);
5459 hostInsert(fragmentEndAnchor, container, anchor);
5460 // a fragment can only have array children
5461 // since they are either generated by the compiler, or implicitly created
5462 // from arrays.
5463 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5464 }
5465 else {
5466 if (patchFlag > 0 &&
5467 patchFlag & 64 /* STABLE_FRAGMENT */ &&
5468 dynamicChildren &&
5469 // #2715 the previous fragment could've been a BAILed one as a result
5470 // of renderSlot() with no valid children
5471 n1.dynamicChildren) {
5472 // a stable fragment (template root or <template v-for>) doesn't need to
5473 // patch children order, but it may contain dynamicChildren.
5474 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
5475 if (parentComponent && parentComponent.type.__hmrId) {
5476 traverseStaticChildren(n1, n2);
5477 }
5478 else if (
5479 // #2080 if the stable fragment has a key, it's a <template v-for> that may
5480 // get moved around. Make sure all root level vnodes inherit el.
5481 // #2134 or if it's a component root, it may also get moved around
5482 // as the component is being moved.
5483 n2.key != null ||
5484 (parentComponent && n2 === parentComponent.subTree)) {
5485 traverseStaticChildren(n1, n2, true /* shallow */);
5486 }
5487 }
5488 else {
5489 // keyed / unkeyed, or manual fragments.
5490 // for keyed & unkeyed, since they are compiler generated from v-for,
5491 // each child is guaranteed to be a block so the fragment will never
5492 // have dynamicChildren.
5493 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5494 }
5495 }
5496 };
5497 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5498 n2.slotScopeIds = slotScopeIds;
5499 if (n1 == null) {
5500 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
5501 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
5502 }
5503 else {
5504 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
5505 }
5506 }
5507 else {
5508 updateComponent(n1, n2, optimized);
5509 }
5510 };
5511 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
5512 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
5513 if (instance.type.__hmrId) {
5514 registerHMR(instance);
5515 }
5516 {
5517 pushWarningContext(initialVNode);
5518 startMeasure(instance, `mount`);
5519 }
5520 // inject renderer internals for keepAlive
5521 if (isKeepAlive(initialVNode)) {
5522 instance.ctx.renderer = internals;
5523 }
5524 // resolve props and slots for setup context
5525 {
5526 {
5527 startMeasure(instance, `init`);
5528 }
5529 setupComponent(instance);
5530 {
5531 endMeasure(instance, `init`);
5532 }
5533 }
5534 // setup() is async. This component relies on async logic to be resolved
5535 // before proceeding
5536 if (instance.asyncDep) {
5537 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
5538 // Give it a placeholder if this is not hydration
5539 // TODO handle self-defined fallback
5540 if (!initialVNode.el) {
5541 const placeholder = (instance.subTree = createVNode(Comment));
5542 processCommentNode(null, placeholder, container, anchor);
5543 }
5544 return;
5545 }
5546 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
5547 {
5548 popWarningContext();
5549 endMeasure(instance, `mount`);
5550 }
5551 };
5552 const updateComponent = (n1, n2, optimized) => {
5553 const instance = (n2.component = n1.component);
5554 if (shouldUpdateComponent(n1, n2, optimized)) {
5555 if (instance.asyncDep &&
5556 !instance.asyncResolved) {
5557 // async & still pending - just update props and slots
5558 // since the component's reactive effect for render isn't set-up yet
5559 {
5560 pushWarningContext(n2);
5561 }
5562 updateComponentPreRender(instance, n2, optimized);
5563 {
5564 popWarningContext();
5565 }
5566 return;
5567 }
5568 else {
5569 // normal update
5570 instance.next = n2;
5571 // in case the child component is also queued, remove it to avoid
5572 // double updating the same child component in the same flush.
5573 invalidateJob(instance.update);
5574 // instance.update is the reactive effect.
5575 instance.update();
5576 }
5577 }
5578 else {
5579 // no update needed. just copy over properties
5580 n2.component = n1.component;
5581 n2.el = n1.el;
5582 instance.vnode = n2;
5583 }
5584 };
5585 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
5586 const componentUpdateFn = () => {
5587 if (!instance.isMounted) {
5588 let vnodeHook;
5589 const { el, props } = initialVNode;
5590 const { bm, m, parent } = instance;
5591 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
5592 effect.allowRecurse = false;
5593 // beforeMount hook
5594 if (bm) {
5595 invokeArrayFns(bm);
5596 }
5597 // onVnodeBeforeMount
5598 if (!isAsyncWrapperVNode &&
5599 (vnodeHook = props && props.onVnodeBeforeMount)) {
5600 invokeVNodeHook(vnodeHook, parent, initialVNode);
5601 }
5602 effect.allowRecurse = true;
5603 if (el && hydrateNode) {
5604 // vnode has adopted host node - perform hydration instead of mount.
5605 const hydrateSubTree = () => {
5606 {
5607 startMeasure(instance, `render`);
5608 }
5609 instance.subTree = renderComponentRoot(instance);
5610 {
5611 endMeasure(instance, `render`);
5612 }
5613 {
5614 startMeasure(instance, `hydrate`);
5615 }
5616 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
5617 {
5618 endMeasure(instance, `hydrate`);
5619 }
5620 };
5621 if (isAsyncWrapperVNode) {
5622 initialVNode.type.__asyncLoader().then(
5623 // note: we are moving the render call into an async callback,
5624 // which means it won't track dependencies - but it's ok because
5625 // a server-rendered async wrapper is already in resolved state
5626 // and it will never need to change.
5627 () => !instance.isUnmounted && hydrateSubTree());
5628 }
5629 else {
5630 hydrateSubTree();
5631 }
5632 }
5633 else {
5634 {
5635 startMeasure(instance, `render`);
5636 }
5637 const subTree = (instance.subTree = renderComponentRoot(instance));
5638 {
5639 endMeasure(instance, `render`);
5640 }
5641 {
5642 startMeasure(instance, `patch`);
5643 }
5644 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
5645 {
5646 endMeasure(instance, `patch`);
5647 }
5648 initialVNode.el = subTree.el;
5649 }
5650 // mounted hook
5651 if (m) {
5652 queuePostRenderEffect(m, parentSuspense);
5653 }
5654 // onVnodeMounted
5655 if (!isAsyncWrapperVNode &&
5656 (vnodeHook = props && props.onVnodeMounted)) {
5657 const scopedInitialVNode = initialVNode;
5658 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
5659 }
5660 // activated hook for keep-alive roots.
5661 // #1742 activated hook must be accessed after first render
5662 // since the hook may be injected by a child keep-alive
5663 if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
5664 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
5665 }
5666 instance.isMounted = true;
5667 {
5668 devtoolsComponentAdded(instance);
5669 }
5670 // #2458: deference mount-only object parameters to prevent memleaks
5671 initialVNode = container = anchor = null;
5672 }
5673 else {
5674 // updateComponent
5675 // This is triggered by mutation of component's own state (next: null)
5676 // OR parent calling processComponent (next: VNode)
5677 let { next, bu, u, parent, vnode } = instance;
5678 let originNext = next;
5679 let vnodeHook;
5680 {
5681 pushWarningContext(next || instance.vnode);
5682 }
5683 // Disallow component effect recursion during pre-lifecycle hooks.
5684 effect.allowRecurse = false;
5685 if (next) {
5686 next.el = vnode.el;
5687 updateComponentPreRender(instance, next, optimized);
5688 }
5689 else {
5690 next = vnode;
5691 }
5692 // beforeUpdate hook
5693 if (bu) {
5694 invokeArrayFns(bu);
5695 }
5696 // onVnodeBeforeUpdate
5697 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
5698 invokeVNodeHook(vnodeHook, parent, next, vnode);
5699 }
5700 effect.allowRecurse = true;
5701 // render
5702 {
5703 startMeasure(instance, `render`);
5704 }
5705 const nextTree = renderComponentRoot(instance);
5706 {
5707 endMeasure(instance, `render`);
5708 }
5709 const prevTree = instance.subTree;
5710 instance.subTree = nextTree;
5711 {
5712 startMeasure(instance, `patch`);
5713 }
5714 patch(prevTree, nextTree,
5715 // parent may have changed if it's in a teleport
5716 hostParentNode(prevTree.el),
5717 // anchor may have changed if it's in a fragment
5718 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
5719 {
5720 endMeasure(instance, `patch`);
5721 }
5722 next.el = nextTree.el;
5723 if (originNext === null) {
5724 // self-triggered update. In case of HOC, update parent component
5725 // vnode el. HOC is indicated by parent instance's subTree pointing
5726 // to child component's vnode
5727 updateHOCHostEl(instance, nextTree.el);
5728 }
5729 // updated hook
5730 if (u) {
5731 queuePostRenderEffect(u, parentSuspense);
5732 }
5733 // onVnodeUpdated
5734 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
5735 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
5736 }
5737 {
5738 devtoolsComponentUpdated(instance);
5739 }
5740 {
5741 popWarningContext();
5742 }
5743 }
5744 };
5745 // create reactive effect for rendering
5746 const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5747 );
5748 const update = (instance.update = effect.run.bind(effect));
5749 update.id = instance.uid;
5750 // allowRecurse
5751 // #1801, #2043 component render effects should allow recursive updates
5752 effect.allowRecurse = update.allowRecurse = true;
5753 {
5754 effect.onTrack = instance.rtc
5755 ? e => invokeArrayFns(instance.rtc, e)
5756 : void 0;
5757 effect.onTrigger = instance.rtg
5758 ? e => invokeArrayFns(instance.rtg, e)
5759 : void 0;
5760 // @ts-ignore (for scheduler)
5761 update.ownerInstance = instance;
5762 }
5763 update();
5764 };
5765 const updateComponentPreRender = (instance, nextVNode, optimized) => {
5766 nextVNode.component = instance;
5767 const prevProps = instance.vnode.props;
5768 instance.vnode = nextVNode;
5769 instance.next = null;
5770 updateProps(instance, nextVNode.props, prevProps, optimized);
5771 updateSlots(instance, nextVNode.children, optimized);
5772 pauseTracking();
5773 // props update may have triggered pre-flush watchers.
5774 // flush them before the render update.
5775 flushPreFlushCbs(undefined, instance.update);
5776 resetTracking();
5777 };
5778 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
5779 const c1 = n1 && n1.children;
5780 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
5781 const c2 = n2.children;
5782 const { patchFlag, shapeFlag } = n2;
5783 // fast path
5784 if (patchFlag > 0) {
5785 if (patchFlag & 128 /* KEYED_FRAGMENT */) {
5786 // this could be either fully-keyed or mixed (some keyed some not)
5787 // presence of patchFlag means children are guaranteed to be arrays
5788 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5789 return;
5790 }
5791 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
5792 // unkeyed
5793 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5794 return;
5795 }
5796 }
5797 // children has 3 possibilities: text, array or no children.
5798 if (shapeFlag & 8 /* TEXT_CHILDREN */) {
5799 // text children fast path
5800 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5801 unmountChildren(c1, parentComponent, parentSuspense);
5802 }
5803 if (c2 !== c1) {
5804 hostSetElementText(container, c2);
5805 }
5806 }
5807 else {
5808 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
5809 // prev children was array
5810 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5811 // two arrays, cannot assume anything, do full diff
5812 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5813 }
5814 else {
5815 // no new children, just unmount old
5816 unmountChildren(c1, parentComponent, parentSuspense, true);
5817 }
5818 }
5819 else {
5820 // prev children was text OR null
5821 // new children is array OR null
5822 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
5823 hostSetElementText(container, '');
5824 }
5825 // mount new if array
5826 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
5827 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5828 }
5829 }
5830 }
5831 };
5832 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5833 c1 = c1 || EMPTY_ARR;
5834 c2 = c2 || EMPTY_ARR;
5835 const oldLength = c1.length;
5836 const newLength = c2.length;
5837 const commonLength = Math.min(oldLength, newLength);
5838 let i;
5839 for (i = 0; i < commonLength; i++) {
5840 const nextChild = (c2[i] = optimized
5841 ? cloneIfMounted(c2[i])
5842 : normalizeVNode(c2[i]));
5843 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5844 }
5845 if (oldLength > newLength) {
5846 // remove old
5847 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
5848 }
5849 else {
5850 // mount new
5851 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
5852 }
5853 };
5854 // can be all-keyed or mixed
5855 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
5856 let i = 0;
5857 const l2 = c2.length;
5858 let e1 = c1.length - 1; // prev ending index
5859 let e2 = l2 - 1; // next ending index
5860 // 1. sync from start
5861 // (a b) c
5862 // (a b) d e
5863 while (i <= e1 && i <= e2) {
5864 const n1 = c1[i];
5865 const n2 = (c2[i] = optimized
5866 ? cloneIfMounted(c2[i])
5867 : normalizeVNode(c2[i]));
5868 if (isSameVNodeType(n1, n2)) {
5869 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5870 }
5871 else {
5872 break;
5873 }
5874 i++;
5875 }
5876 // 2. sync from end
5877 // a (b c)
5878 // d e (b c)
5879 while (i <= e1 && i <= e2) {
5880 const n1 = c1[e1];
5881 const n2 = (c2[e2] = optimized
5882 ? cloneIfMounted(c2[e2])
5883 : normalizeVNode(c2[e2]));
5884 if (isSameVNodeType(n1, n2)) {
5885 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5886 }
5887 else {
5888 break;
5889 }
5890 e1--;
5891 e2--;
5892 }
5893 // 3. common sequence + mount
5894 // (a b)
5895 // (a b) c
5896 // i = 2, e1 = 1, e2 = 2
5897 // (a b)
5898 // c (a b)
5899 // i = 0, e1 = -1, e2 = 0
5900 if (i > e1) {
5901 if (i <= e2) {
5902 const nextPos = e2 + 1;
5903 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
5904 while (i <= e2) {
5905 patch(null, (c2[i] = optimized
5906 ? cloneIfMounted(c2[i])
5907 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5908 i++;
5909 }
5910 }
5911 }
5912 // 4. common sequence + unmount
5913 // (a b) c
5914 // (a b)
5915 // i = 2, e1 = 2, e2 = 1
5916 // a (b c)
5917 // (b c)
5918 // i = 0, e1 = 0, e2 = -1
5919 else if (i > e2) {
5920 while (i <= e1) {
5921 unmount(c1[i], parentComponent, parentSuspense, true);
5922 i++;
5923 }
5924 }
5925 // 5. unknown sequence
5926 // [i ... e1 + 1]: a b [c d e] f g
5927 // [i ... e2 + 1]: a b [e d c h] f g
5928 // i = 2, e1 = 4, e2 = 5
5929 else {
5930 const s1 = i; // prev starting index
5931 const s2 = i; // next starting index
5932 // 5.1 build key:index map for newChildren
5933 const keyToNewIndexMap = new Map();
5934 for (i = s2; i <= e2; i++) {
5935 const nextChild = (c2[i] = optimized
5936 ? cloneIfMounted(c2[i])
5937 : normalizeVNode(c2[i]));
5938 if (nextChild.key != null) {
5939 if (keyToNewIndexMap.has(nextChild.key)) {
5940 warn$1(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
5941 }
5942 keyToNewIndexMap.set(nextChild.key, i);
5943 }
5944 }
5945 // 5.2 loop through old children left to be patched and try to patch
5946 // matching nodes & remove nodes that are no longer present
5947 let j;
5948 let patched = 0;
5949 const toBePatched = e2 - s2 + 1;
5950 let moved = false;
5951 // used to track whether any node has moved
5952 let maxNewIndexSoFar = 0;
5953 // works as Map<newIndex, oldIndex>
5954 // Note that oldIndex is offset by +1
5955 // and oldIndex = 0 is a special value indicating the new node has
5956 // no corresponding old node.
5957 // used for determining longest stable subsequence
5958 const newIndexToOldIndexMap = new Array(toBePatched);
5959 for (i = 0; i < toBePatched; i++)
5960 newIndexToOldIndexMap[i] = 0;
5961 for (i = s1; i <= e1; i++) {
5962 const prevChild = c1[i];
5963 if (patched >= toBePatched) {
5964 // all new children have been patched so this can only be a removal
5965 unmount(prevChild, parentComponent, parentSuspense, true);
5966 continue;
5967 }
5968 let newIndex;
5969 if (prevChild.key != null) {
5970 newIndex = keyToNewIndexMap.get(prevChild.key);
5971 }
5972 else {
5973 // key-less node, try to locate a key-less node of the same type
5974 for (j = s2; j <= e2; j++) {
5975 if (newIndexToOldIndexMap[j - s2] === 0 &&
5976 isSameVNodeType(prevChild, c2[j])) {
5977 newIndex = j;
5978 break;
5979 }
5980 }
5981 }
5982 if (newIndex === undefined) {
5983 unmount(prevChild, parentComponent, parentSuspense, true);
5984 }
5985 else {
5986 newIndexToOldIndexMap[newIndex - s2] = i + 1;
5987 if (newIndex >= maxNewIndexSoFar) {
5988 maxNewIndexSoFar = newIndex;
5989 }
5990 else {
5991 moved = true;
5992 }
5993 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
5994 patched++;
5995 }
5996 }
5997 // 5.3 move and mount
5998 // generate longest stable subsequence only when nodes have moved
5999 const increasingNewIndexSequence = moved
6000 ? getSequence(newIndexToOldIndexMap)
6001 : EMPTY_ARR;
6002 j = increasingNewIndexSequence.length - 1;
6003 // looping backwards so that we can use last patched node as anchor
6004 for (i = toBePatched - 1; i >= 0; i--) {
6005 const nextIndex = s2 + i;
6006 const nextChild = c2[nextIndex];
6007 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
6008 if (newIndexToOldIndexMap[i] === 0) {
6009 // mount new
6010 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6011 }
6012 else if (moved) {
6013 // move if:
6014 // There is no stable subsequence (e.g. a reverse)
6015 // OR current node is not among the stable sequence
6016 if (j < 0 || i !== increasingNewIndexSequence[j]) {
6017 move(nextChild, container, anchor, 2 /* REORDER */);
6018 }
6019 else {
6020 j--;
6021 }
6022 }
6023 }
6024 }
6025 };
6026 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
6027 const { el, type, transition, children, shapeFlag } = vnode;
6028 if (shapeFlag & 6 /* COMPONENT */) {
6029 move(vnode.component.subTree, container, anchor, moveType);
6030 return;
6031 }
6032 if (shapeFlag & 128 /* SUSPENSE */) {
6033 vnode.suspense.move(container, anchor, moveType);
6034 return;
6035 }
6036 if (shapeFlag & 64 /* TELEPORT */) {
6037 type.move(vnode, container, anchor, internals);
6038 return;
6039 }
6040 if (type === Fragment) {
6041 hostInsert(el, container, anchor);
6042 for (let i = 0; i < children.length; i++) {
6043 move(children[i], container, anchor, moveType);
6044 }
6045 hostInsert(vnode.anchor, container, anchor);
6046 return;
6047 }
6048 if (type === Static) {
6049 moveStaticNode(vnode, container, anchor);
6050 return;
6051 }
6052 // single nodes
6053 const needTransition = moveType !== 2 /* REORDER */ &&
6054 shapeFlag & 1 /* ELEMENT */ &&
6055 transition;
6056 if (needTransition) {
6057 if (moveType === 0 /* ENTER */) {
6058 transition.beforeEnter(el);
6059 hostInsert(el, container, anchor);
6060 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
6061 }
6062 else {
6063 const { leave, delayLeave, afterLeave } = transition;
6064 const remove = () => hostInsert(el, container, anchor);
6065 const performLeave = () => {
6066 leave(el, () => {
6067 remove();
6068 afterLeave && afterLeave();
6069 });
6070 };
6071 if (delayLeave) {
6072 delayLeave(el, remove, performLeave);
6073 }
6074 else {
6075 performLeave();
6076 }
6077 }
6078 }
6079 else {
6080 hostInsert(el, container, anchor);
6081 }
6082 };
6083 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
6084 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
6085 // unset ref
6086 if (ref != null) {
6087 setRef(ref, null, parentSuspense, vnode, true);
6088 }
6089 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
6090 parentComponent.ctx.deactivate(vnode);
6091 return;
6092 }
6093 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
6094 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
6095 let vnodeHook;
6096 if (shouldInvokeVnodeHook &&
6097 (vnodeHook = props && props.onVnodeBeforeUnmount)) {
6098 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6099 }
6100 if (shapeFlag & 6 /* COMPONENT */) {
6101 unmountComponent(vnode.component, parentSuspense, doRemove);
6102 }
6103 else {
6104 if (shapeFlag & 128 /* SUSPENSE */) {
6105 vnode.suspense.unmount(parentSuspense, doRemove);
6106 return;
6107 }
6108 if (shouldInvokeDirs) {
6109 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
6110 }
6111 if (shapeFlag & 64 /* TELEPORT */) {
6112 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
6113 }
6114 else if (dynamicChildren &&
6115 // #1153: fast path should not be taken for non-stable (v-for) fragments
6116 (type !== Fragment ||
6117 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
6118 // fast path for block nodes: only need to unmount dynamic children.
6119 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
6120 }
6121 else if ((type === Fragment &&
6122 patchFlag &
6123 (128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) ||
6124 (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
6125 unmountChildren(children, parentComponent, parentSuspense);
6126 }
6127 if (doRemove) {
6128 remove(vnode);
6129 }
6130 }
6131 if ((shouldInvokeVnodeHook &&
6132 (vnodeHook = props && props.onVnodeUnmounted)) ||
6133 shouldInvokeDirs) {
6134 queuePostRenderEffect(() => {
6135 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6136 shouldInvokeDirs &&
6137 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
6138 }, parentSuspense);
6139 }
6140 };
6141 const remove = vnode => {
6142 const { type, el, anchor, transition } = vnode;
6143 if (type === Fragment) {
6144 removeFragment(el, anchor);
6145 return;
6146 }
6147 if (type === Static) {
6148 removeStaticNode(vnode);
6149 return;
6150 }
6151 const performRemove = () => {
6152 hostRemove(el);
6153 if (transition && !transition.persisted && transition.afterLeave) {
6154 transition.afterLeave();
6155 }
6156 };
6157 if (vnode.shapeFlag & 1 /* ELEMENT */ &&
6158 transition &&
6159 !transition.persisted) {
6160 const { leave, delayLeave } = transition;
6161 const performLeave = () => leave(el, performRemove);
6162 if (delayLeave) {
6163 delayLeave(vnode.el, performRemove, performLeave);
6164 }
6165 else {
6166 performLeave();
6167 }
6168 }
6169 else {
6170 performRemove();
6171 }
6172 };
6173 const removeFragment = (cur, end) => {
6174 // For fragments, directly remove all contained DOM nodes.
6175 // (fragment child nodes cannot have transition)
6176 let next;
6177 while (cur !== end) {
6178 next = hostNextSibling(cur);
6179 hostRemove(cur);
6180 cur = next;
6181 }
6182 hostRemove(end);
6183 };
6184 const unmountComponent = (instance, parentSuspense, doRemove) => {
6185 if (instance.type.__hmrId) {
6186 unregisterHMR(instance);
6187 }
6188 const { bum, scope, update, subTree, um } = instance;
6189 // beforeUnmount hook
6190 if (bum) {
6191 invokeArrayFns(bum);
6192 }
6193 // stop effects in component scope
6194 scope.stop();
6195 // update may be null if a component is unmounted before its async
6196 // setup has resolved.
6197 if (update) {
6198 // so that scheduler will no longer invoke it
6199 update.active = false;
6200 unmount(subTree, instance, parentSuspense, doRemove);
6201 }
6202 // unmounted hook
6203 if (um) {
6204 queuePostRenderEffect(um, parentSuspense);
6205 }
6206 queuePostRenderEffect(() => {
6207 instance.isUnmounted = true;
6208 }, parentSuspense);
6209 // A component with async dep inside a pending suspense is unmounted before
6210 // its async dep resolves. This should remove the dep from the suspense, and
6211 // cause the suspense to resolve immediately if that was the last dep.
6212 if (parentSuspense &&
6213 parentSuspense.pendingBranch &&
6214 !parentSuspense.isUnmounted &&
6215 instance.asyncDep &&
6216 !instance.asyncResolved &&
6217 instance.suspenseId === parentSuspense.pendingId) {
6218 parentSuspense.deps--;
6219 if (parentSuspense.deps === 0) {
6220 parentSuspense.resolve();
6221 }
6222 }
6223 {
6224 devtoolsComponentRemoved(instance);
6225 }
6226 };
6227 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
6228 for (let i = start; i < children.length; i++) {
6229 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
6230 }
6231 };
6232 const getNextHostNode = vnode => {
6233 if (vnode.shapeFlag & 6 /* COMPONENT */) {
6234 return getNextHostNode(vnode.component.subTree);
6235 }
6236 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
6237 return vnode.suspense.next();
6238 }
6239 return hostNextSibling((vnode.anchor || vnode.el));
6240 };
6241 const render = (vnode, container, isSVG) => {
6242 if (vnode == null) {
6243 if (container._vnode) {
6244 unmount(container._vnode, null, null, true);
6245 }
6246 }
6247 else {
6248 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
6249 }
6250 flushPostFlushCbs();
6251 container._vnode = vnode;
6252 };
6253 const internals = {
6254 p: patch,
6255 um: unmount,
6256 m: move,
6257 r: remove,
6258 mt: mountComponent,
6259 mc: mountChildren,
6260 pc: patchChildren,
6261 pbc: patchBlockChildren,
6262 n: getNextHostNode,
6263 o: options
6264 };
6265 let hydrate;
6266 let hydrateNode;
6267 if (createHydrationFns) {
6268 [hydrate, hydrateNode] = createHydrationFns(internals);
6269 }
6270 return {
6271 render,
6272 hydrate,
6273 createApp: createAppAPI(render, hydrate)
6274 };
6275}
6276function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6277 if (isArray(rawRef)) {
6278 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6279 return;
6280 }
6281 if (isAsyncWrapper(vnode) && !isUnmount) {
6282 // when mounting async components, nothing needs to be done,
6283 // because the template ref is forwarded to inner component
6284 return;
6285 }
6286 const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
6287 ? getExposeProxy(vnode.component) || vnode.component.proxy
6288 : vnode.el;
6289 const value = isUnmount ? null : refValue;
6290 const { i: owner, r: ref } = rawRef;
6291 if (!owner) {
6292 warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
6293 `A vnode with ref must be created inside the render function.`);
6294 return;
6295 }
6296 const oldRef = oldRawRef && oldRawRef.r;
6297 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6298 const setupState = owner.setupState;
6299 // dynamic ref changed. unset old ref
6300 if (oldRef != null && oldRef !== ref) {
6301 if (isString(oldRef)) {
6302 refs[oldRef] = null;
6303 if (hasOwn(setupState, oldRef)) {
6304 setupState[oldRef] = null;
6305 }
6306 }
6307 else if (isRef(oldRef)) {
6308 oldRef.value = null;
6309 }
6310 }
6311 if (isString(ref)) {
6312 const doSet = () => {
6313 {
6314 refs[ref] = value;
6315 }
6316 if (hasOwn(setupState, ref)) {
6317 setupState[ref] = value;
6318 }
6319 };
6320 // #1789: for non-null values, set them after render
6321 // null values means this is unmount and it should not overwrite another
6322 // ref with the same key
6323 if (value) {
6324 doSet.id = -1;
6325 queuePostRenderEffect(doSet, parentSuspense);
6326 }
6327 else {
6328 doSet();
6329 }
6330 }
6331 else if (isRef(ref)) {
6332 const doSet = () => {
6333 ref.value = value;
6334 };
6335 if (value) {
6336 doSet.id = -1;
6337 queuePostRenderEffect(doSet, parentSuspense);
6338 }
6339 else {
6340 doSet();
6341 }
6342 }
6343 else if (isFunction(ref)) {
6344 callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6345 }
6346 else {
6347 warn$1('Invalid template ref type:', value, `(${typeof value})`);
6348 }
6349}
6350function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6351 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6352 vnode,
6353 prevVNode
6354 ]);
6355}
6356/**
6357 * #1156
6358 * When a component is HMR-enabled, we need to make sure that all static nodes
6359 * inside a block also inherit the DOM element from the previous tree so that
6360 * HMR updates (which are full updates) can retrieve the element for patching.
6361 *
6362 * #2080
6363 * Inside keyed `template` fragment static children, if a fragment is moved,
6364 * the children will always moved so that need inherit el form previous nodes
6365 * to ensure correct moved position.
6366 */
6367function traverseStaticChildren(n1, n2, shallow = false) {
6368 const ch1 = n1.children;
6369 const ch2 = n2.children;
6370 if (isArray(ch1) && isArray(ch2)) {
6371 for (let i = 0; i < ch1.length; i++) {
6372 // this is only called in the optimized path so array children are
6373 // guaranteed to be vnodes
6374 const c1 = ch1[i];
6375 let c2 = ch2[i];
6376 if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
6377 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
6378 c2 = ch2[i] = cloneIfMounted(ch2[i]);
6379 c2.el = c1.el;
6380 }
6381 if (!shallow)
6382 traverseStaticChildren(c1, c2);
6383 }
6384 // also inherit for comment nodes, but not placeholders (e.g. v-if which
6385 // would have received .el during block patch)
6386 if (c2.type === Comment && !c2.el) {
6387 c2.el = c1.el;
6388 }
6389 }
6390 }
6391}
6392// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
6393function getSequence(arr) {
6394 const p = arr.slice();
6395 const result = [0];
6396 let i, j, u, v, c;
6397 const len = arr.length;
6398 for (i = 0; i < len; i++) {
6399 const arrI = arr[i];
6400 if (arrI !== 0) {
6401 j = result[result.length - 1];
6402 if (arr[j] < arrI) {
6403 p[i] = j;
6404 result.push(i);
6405 continue;
6406 }
6407 u = 0;
6408 v = result.length - 1;
6409 while (u < v) {
6410 c = (u + v) >> 1;
6411 if (arr[result[c]] < arrI) {
6412 u = c + 1;
6413 }
6414 else {
6415 v = c;
6416 }
6417 }
6418 if (arrI < arr[result[u]]) {
6419 if (u > 0) {
6420 p[i] = result[u - 1];
6421 }
6422 result[u] = i;
6423 }
6424 }
6425 }
6426 u = result.length;
6427 v = result[u - 1];
6428 while (u-- > 0) {
6429 result[u] = v;
6430 v = p[v];
6431 }
6432 return result;
6433}
6434
6435const isTeleport = (type) => type.__isTeleport;
6436const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
6437const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
6438const resolveTarget = (props, select) => {
6439 const targetSelector = props && props.to;
6440 if (isString(targetSelector)) {
6441 if (!select) {
6442 warn$1(`Current renderer does not support string target for Teleports. ` +
6443 `(missing querySelector renderer option)`);
6444 return null;
6445 }
6446 else {
6447 const target = select(targetSelector);
6448 if (!target) {
6449 warn$1(`Failed to locate Teleport target with selector "${targetSelector}". ` +
6450 `Note the target element must exist before the component is mounted - ` +
6451 `i.e. the target cannot be rendered by the component itself, and ` +
6452 `ideally should be outside of the entire Vue component tree.`);
6453 }
6454 return target;
6455 }
6456 }
6457 else {
6458 if (!targetSelector && !isTeleportDisabled(props)) {
6459 warn$1(`Invalid Teleport target: ${targetSelector}`);
6460 }
6461 return targetSelector;
6462 }
6463};
6464const TeleportImpl = {
6465 __isTeleport: true,
6466 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
6467 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
6468 const disabled = isTeleportDisabled(n2.props);
6469 let { shapeFlag, children, dynamicChildren } = n2;
6470 // #3302
6471 // HMR updated, force full diff
6472 if (isHmrUpdating) {
6473 optimized = false;
6474 dynamicChildren = null;
6475 }
6476 if (n1 == null) {
6477 // insert anchors in the main view
6478 const placeholder = (n2.el = createComment('teleport start')
6479 );
6480 const mainAnchor = (n2.anchor = createComment('teleport end')
6481 );
6482 insert(placeholder, container, anchor);
6483 insert(mainAnchor, container, anchor);
6484 const target = (n2.target = resolveTarget(n2.props, querySelector));
6485 const targetAnchor = (n2.targetAnchor = createText(''));
6486 if (target) {
6487 insert(targetAnchor, target);
6488 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
6489 isSVG = isSVG || isTargetSVG(target);
6490 }
6491 else if (!disabled) {
6492 warn$1('Invalid Teleport target on mount:', target, `(${typeof target})`);
6493 }
6494 const mount = (container, anchor) => {
6495 // Teleport *always* has Array children. This is enforced in both the
6496 // compiler and vnode children normalization.
6497 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6498 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6499 }
6500 };
6501 if (disabled) {
6502 mount(container, mainAnchor);
6503 }
6504 else if (target) {
6505 mount(target, targetAnchor);
6506 }
6507 }
6508 else {
6509 // update content
6510 n2.el = n1.el;
6511 const mainAnchor = (n2.anchor = n1.anchor);
6512 const target = (n2.target = n1.target);
6513 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
6514 const wasDisabled = isTeleportDisabled(n1.props);
6515 const currentContainer = wasDisabled ? container : target;
6516 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
6517 isSVG = isSVG || isTargetSVG(target);
6518 if (dynamicChildren) {
6519 // fast path when the teleport happens to be a block root
6520 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
6521 // even in block tree mode we need to make sure all root-level nodes
6522 // in the teleport inherit previous DOM references so that they can
6523 // be moved in future patches.
6524 traverseStaticChildren(n1, n2, true);
6525 }
6526 else if (!optimized) {
6527 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
6528 }
6529 if (disabled) {
6530 if (!wasDisabled) {
6531 // enabled -> disabled
6532 // move into main container
6533 moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
6534 }
6535 }
6536 else {
6537 // target changed
6538 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
6539 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
6540 if (nextTarget) {
6541 moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
6542 }
6543 else {
6544 warn$1('Invalid Teleport target on update:', target, `(${typeof target})`);
6545 }
6546 }
6547 else if (wasDisabled) {
6548 // disabled -> enabled
6549 // move into teleport target
6550 moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
6551 }
6552 }
6553 }
6554 },
6555 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
6556 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
6557 if (target) {
6558 hostRemove(targetAnchor);
6559 }
6560 // an unmounted teleport should always remove its children if not disabled
6561 if (doRemove || !isTeleportDisabled(props)) {
6562 hostRemove(anchor);
6563 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6564 for (let i = 0; i < children.length; i++) {
6565 const child = children[i];
6566 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
6567 }
6568 }
6569 }
6570 },
6571 move: moveTeleport,
6572 hydrate: hydrateTeleport
6573};
6574function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
6575 // move target anchor if this is a target change.
6576 if (moveType === 0 /* TARGET_CHANGE */) {
6577 insert(vnode.targetAnchor, container, parentAnchor);
6578 }
6579 const { el, anchor, shapeFlag, children, props } = vnode;
6580 const isReorder = moveType === 2 /* REORDER */;
6581 // move main view anchor if this is a re-order.
6582 if (isReorder) {
6583 insert(el, container, parentAnchor);
6584 }
6585 // if this is a re-order and teleport is enabled (content is in target)
6586 // do not move children. So the opposite is: only move children if this
6587 // is not a reorder, or the teleport is disabled
6588 if (!isReorder || isTeleportDisabled(props)) {
6589 // Teleport has either Array children or no children.
6590 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
6591 for (let i = 0; i < children.length; i++) {
6592 move(children[i], container, parentAnchor, 2 /* REORDER */);
6593 }
6594 }
6595 }
6596 // move main view anchor if this is a re-order.
6597 if (isReorder) {
6598 insert(anchor, container, parentAnchor);
6599 }
6600}
6601function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
6602 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
6603 if (target) {
6604 // if multiple teleports rendered to the same target element, we need to
6605 // pick up from where the last teleport finished instead of the first node
6606 const targetNode = target._lpa || target.firstChild;
6607 if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
6608 if (isTeleportDisabled(vnode.props)) {
6609 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
6610 vnode.targetAnchor = targetNode;
6611 }
6612 else {
6613 vnode.anchor = nextSibling(node);
6614 vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
6615 }
6616 target._lpa =
6617 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
6618 }
6619 }
6620 return vnode.anchor && nextSibling(vnode.anchor);
6621}
6622// Force-casted public typing for h and TSX props inference
6623const Teleport = TeleportImpl;
6624
6625const COMPONENTS = 'components';
6626const DIRECTIVES = 'directives';
6627/**
6628 * @private
6629 */
6630function resolveComponent(name, maybeSelfReference) {
6631 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
6632}
6633const NULL_DYNAMIC_COMPONENT = Symbol();
6634/**
6635 * @private
6636 */
6637function resolveDynamicComponent(component) {
6638 if (isString(component)) {
6639 return resolveAsset(COMPONENTS, component, false) || component;
6640 }
6641 else {
6642 // invalid types will fallthrough to createVNode and raise warning
6643 return (component || NULL_DYNAMIC_COMPONENT);
6644 }
6645}
6646/**
6647 * @private
6648 */
6649function resolveDirective(name) {
6650 return resolveAsset(DIRECTIVES, name);
6651}
6652// implementation
6653function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
6654 const instance = currentRenderingInstance || currentInstance;
6655 if (instance) {
6656 const Component = instance.type;
6657 // explicit self name has highest priority
6658 if (type === COMPONENTS) {
6659 const selfName = getComponentName(Component);
6660 if (selfName &&
6661 (selfName === name ||
6662 selfName === camelize(name) ||
6663 selfName === capitalize(camelize(name)))) {
6664 return Component;
6665 }
6666 }
6667 const res =
6668 // local registration
6669 // check instance[type] first which is resolved for options API
6670 resolve(instance[type] || Component[type], name) ||
6671 // global registration
6672 resolve(instance.appContext[type], name);
6673 if (!res && maybeSelfReference) {
6674 // fallback to implicit self-reference
6675 return Component;
6676 }
6677 if (warnMissing && !res) {
6678 const extra = type === COMPONENTS
6679 ? `\nIf this is a native custom element, make sure to exclude it from ` +
6680 `component resolution via compilerOptions.isCustomElement.`
6681 : ``;
6682 warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
6683 }
6684 return res;
6685 }
6686 else {
6687 warn$1(`resolve${capitalize(type.slice(0, -1))} ` +
6688 `can only be used in render() or setup().`);
6689 }
6690}
6691function resolve(registry, name) {
6692 return (registry &&
6693 (registry[name] ||
6694 registry[camelize(name)] ||
6695 registry[capitalize(camelize(name))]));
6696}
6697
6698const Fragment = Symbol('Fragment' );
6699const Text = Symbol('Text' );
6700const Comment = Symbol('Comment' );
6701const Static = Symbol('Static' );
6702// Since v-if and v-for are the two possible ways node structure can dynamically
6703// change, once we consider v-if branches and each v-for fragment a block, we
6704// can divide a template into nested blocks, and within each block the node
6705// structure would be stable. This allows us to skip most children diffing
6706// and only worry about the dynamic nodes (indicated by patch flags).
6707const blockStack = [];
6708let currentBlock = null;
6709/**
6710 * Open a block.
6711 * This must be called before `createBlock`. It cannot be part of `createBlock`
6712 * because the children of the block are evaluated before `createBlock` itself
6713 * is called. The generated code typically looks like this:
6714 *
6715 * ```js
6716 * function render() {
6717 * return (openBlock(),createBlock('div', null, [...]))
6718 * }
6719 * ```
6720 * disableTracking is true when creating a v-for fragment block, since a v-for
6721 * fragment always diffs its children.
6722 *
6723 * @private
6724 */
6725function openBlock(disableTracking = false) {
6726 blockStack.push((currentBlock = disableTracking ? null : []));
6727}
6728function closeBlock() {
6729 blockStack.pop();
6730 currentBlock = blockStack[blockStack.length - 1] || null;
6731}
6732// Whether we should be tracking dynamic child nodes inside a block.
6733// Only tracks when this value is > 0
6734// We are not using a simple boolean because this value may need to be
6735// incremented/decremented by nested usage of v-once (see below)
6736let isBlockTreeEnabled = 1;
6737/**
6738 * Block tracking sometimes needs to be disabled, for example during the
6739 * creation of a tree that needs to be cached by v-once. The compiler generates
6740 * code like this:
6741 *
6742 * ``` js
6743 * _cache[1] || (
6744 * setBlockTracking(-1),
6745 * _cache[1] = createVNode(...),
6746 * setBlockTracking(1),
6747 * _cache[1]
6748 * )
6749 * ```
6750 *
6751 * @private
6752 */
6753function setBlockTracking(value) {
6754 isBlockTreeEnabled += value;
6755}
6756function setupBlock(vnode) {
6757 // save current block children on the block vnode
6758 vnode.dynamicChildren =
6759 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
6760 // close block
6761 closeBlock();
6762 // a block is always going to be patched, so track it as a child of its
6763 // parent block
6764 if (isBlockTreeEnabled > 0 && currentBlock) {
6765 currentBlock.push(vnode);
6766 }
6767 return vnode;
6768}
6769/**
6770 * @private
6771 */
6772function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
6773 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
6774}
6775/**
6776 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
6777 * A block root keeps track of dynamic nodes within the block in the
6778 * `dynamicChildren` array.
6779 *
6780 * @private
6781 */
6782function createBlock(type, props, children, patchFlag, dynamicProps) {
6783 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
6784}
6785function isVNode(value) {
6786 return value ? value.__v_isVNode === true : false;
6787}
6788function isSameVNodeType(n1, n2) {
6789 if (n2.shapeFlag & 6 /* COMPONENT */ &&
6790 hmrDirtyComponents.has(n2.type)) {
6791 // HMR only: if the component has been hot-updated, force a reload.
6792 return false;
6793 }
6794 return n1.type === n2.type && n1.key === n2.key;
6795}
6796let vnodeArgsTransformer;
6797/**
6798 * Internal API for registering an arguments transform for createVNode
6799 * used for creating stubs in the test-utils
6800 * It is *internal* but needs to be exposed for test-utils to pick up proper
6801 * typings
6802 */
6803function transformVNodeArgs(transformer) {
6804 vnodeArgsTransformer = transformer;
6805}
6806const createVNodeWithArgsTransform = (...args) => {
6807 return _createVNode(...(vnodeArgsTransformer
6808 ? vnodeArgsTransformer(args, currentRenderingInstance)
6809 : args));
6810};
6811const InternalObjectKey = `__vInternal`;
6812const normalizeKey = ({ key }) => key != null ? key : null;
6813const normalizeRef = ({ ref }) => {
6814 return (ref != null
6815 ? isString(ref) || isRef(ref) || isFunction(ref)
6816 ? { i: currentRenderingInstance, r: ref }
6817 : ref
6818 : null);
6819};
6820function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
6821 const vnode = {
6822 __v_isVNode: true,
6823 __v_skip: true,
6824 type,
6825 props,
6826 key: props && normalizeKey(props),
6827 ref: props && normalizeRef(props),
6828 scopeId: currentScopeId,
6829 slotScopeIds: null,
6830 children,
6831 component: null,
6832 suspense: null,
6833 ssContent: null,
6834 ssFallback: null,
6835 dirs: null,
6836 transition: null,
6837 el: null,
6838 anchor: null,
6839 target: null,
6840 targetAnchor: null,
6841 staticCount: 0,
6842 shapeFlag,
6843 patchFlag,
6844 dynamicProps,
6845 dynamicChildren: null,
6846 appContext: null
6847 };
6848 if (needFullChildrenNormalization) {
6849 normalizeChildren(vnode, children);
6850 // normalize suspense children
6851 if (shapeFlag & 128 /* SUSPENSE */) {
6852 type.normalize(vnode);
6853 }
6854 }
6855 else if (children) {
6856 // compiled element vnode - if children is passed, only possible types are
6857 // string or Array.
6858 vnode.shapeFlag |= isString(children)
6859 ? 8 /* TEXT_CHILDREN */
6860 : 16 /* ARRAY_CHILDREN */;
6861 }
6862 // validate key
6863 if (vnode.key !== vnode.key) {
6864 warn$1(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
6865 }
6866 // track vnode for block tree
6867 if (isBlockTreeEnabled > 0 &&
6868 // avoid a block node from tracking itself
6869 !isBlockNode &&
6870 // has current parent block
6871 currentBlock &&
6872 // presence of a patch flag indicates this node needs patching on updates.
6873 // component nodes also should always be patched, because even if the
6874 // component doesn't need to update, it needs to persist the instance on to
6875 // the next vnode so that it can be properly unmounted later.
6876 (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
6877 // the EVENTS flag is only for hydration and if it is the only flag, the
6878 // vnode should not be considered dynamic due to handler caching.
6879 vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
6880 currentBlock.push(vnode);
6881 }
6882 return vnode;
6883}
6884const createVNode = (createVNodeWithArgsTransform );
6885function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
6886 if (!type || type === NULL_DYNAMIC_COMPONENT) {
6887 if (!type) {
6888 warn$1(`Invalid vnode type when creating vnode: ${type}.`);
6889 }
6890 type = Comment;
6891 }
6892 if (isVNode(type)) {
6893 // createVNode receiving an existing vnode. This happens in cases like
6894 // <component :is="vnode"/>
6895 // #2078 make sure to merge refs during the clone instead of overwriting it
6896 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
6897 if (children) {
6898 normalizeChildren(cloned, children);
6899 }
6900 return cloned;
6901 }
6902 // class component normalization.
6903 if (isClassComponent(type)) {
6904 type = type.__vccOpts;
6905 }
6906 // class & style normalization.
6907 if (props) {
6908 // for reactive or proxy objects, we need to clone it to enable mutation.
6909 props = guardReactiveProps(props);
6910 let { class: klass, style } = props;
6911 if (klass && !isString(klass)) {
6912 props.class = normalizeClass(klass);
6913 }
6914 if (isObject(style)) {
6915 // reactive state objects need to be cloned since they are likely to be
6916 // mutated
6917 if (isProxy(style) && !isArray(style)) {
6918 style = extend({}, style);
6919 }
6920 props.style = normalizeStyle(style);
6921 }
6922 }
6923 // encode the vnode type information into a bitmap
6924 const shapeFlag = isString(type)
6925 ? 1 /* ELEMENT */
6926 : isSuspense(type)
6927 ? 128 /* SUSPENSE */
6928 : isTeleport(type)
6929 ? 64 /* TELEPORT */
6930 : isObject(type)
6931 ? 4 /* STATEFUL_COMPONENT */
6932 : isFunction(type)
6933 ? 2 /* FUNCTIONAL_COMPONENT */
6934 : 0;
6935 if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
6936 type = toRaw(type);
6937 warn$1(`Vue received a Component which was made a reactive object. This can ` +
6938 `lead to unnecessary performance overhead, and should be avoided by ` +
6939 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
6940 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
6941 }
6942 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
6943}
6944function guardReactiveProps(props) {
6945 if (!props)
6946 return null;
6947 return isProxy(props) || InternalObjectKey in props
6948 ? extend({}, props)
6949 : props;
6950}
6951function cloneVNode(vnode, extraProps, mergeRef = false) {
6952 // This is intentionally NOT using spread or extend to avoid the runtime
6953 // key enumeration cost.
6954 const { props, ref, patchFlag, children } = vnode;
6955 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
6956 const cloned = {
6957 __v_isVNode: true,
6958 __v_skip: true,
6959 type: vnode.type,
6960 props: mergedProps,
6961 key: mergedProps && normalizeKey(mergedProps),
6962 ref: extraProps && extraProps.ref
6963 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
6964 // if the vnode itself already has a ref, cloneVNode will need to merge
6965 // the refs so the single vnode can be set on multiple refs
6966 mergeRef && ref
6967 ? isArray(ref)
6968 ? ref.concat(normalizeRef(extraProps))
6969 : [ref, normalizeRef(extraProps)]
6970 : normalizeRef(extraProps)
6971 : ref,
6972 scopeId: vnode.scopeId,
6973 slotScopeIds: vnode.slotScopeIds,
6974 children: patchFlag === -1 /* HOISTED */ && isArray(children)
6975 ? children.map(deepCloneVNode)
6976 : children,
6977 target: vnode.target,
6978 targetAnchor: vnode.targetAnchor,
6979 staticCount: vnode.staticCount,
6980 shapeFlag: vnode.shapeFlag,
6981 // if the vnode is cloned with extra props, we can no longer assume its
6982 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
6983 // note: perserve flag for fragments since they use the flag for children
6984 // fast paths only.
6985 patchFlag: extraProps && vnode.type !== Fragment
6986 ? patchFlag === -1 // hoisted node
6987 ? 16 /* FULL_PROPS */
6988 : patchFlag | 16 /* FULL_PROPS */
6989 : patchFlag,
6990 dynamicProps: vnode.dynamicProps,
6991 dynamicChildren: vnode.dynamicChildren,
6992 appContext: vnode.appContext,
6993 dirs: vnode.dirs,
6994 transition: vnode.transition,
6995 // These should technically only be non-null on mounted VNodes. However,
6996 // they *should* be copied for kept-alive vnodes. So we just always copy
6997 // them since them being non-null during a mount doesn't affect the logic as
6998 // they will simply be overwritten.
6999 component: vnode.component,
7000 suspense: vnode.suspense,
7001 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
7002 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
7003 el: vnode.el,
7004 anchor: vnode.anchor
7005 };
7006 return cloned;
7007}
7008/**
7009 * Dev only, for HMR of hoisted vnodes reused in v-for
7010 * https://github.com/vitejs/vite/issues/2022
7011 */
7012function deepCloneVNode(vnode) {
7013 const cloned = cloneVNode(vnode);
7014 if (isArray(vnode.children)) {
7015 cloned.children = vnode.children.map(deepCloneVNode);
7016 }
7017 return cloned;
7018}
7019/**
7020 * @private
7021 */
7022function createTextVNode(text = ' ', flag = 0) {
7023 return createVNode(Text, null, text, flag);
7024}
7025/**
7026 * @private
7027 */
7028function createStaticVNode(content, numberOfNodes) {
7029 // A static vnode can contain multiple stringified elements, and the number
7030 // of elements is necessary for hydration.
7031 const vnode = createVNode(Static, null, content);
7032 vnode.staticCount = numberOfNodes;
7033 return vnode;
7034}
7035/**
7036 * @private
7037 */
7038function createCommentVNode(text = '',
7039// when used as the v-else branch, the comment node must be created as a
7040// block to ensure correct updates.
7041asBlock = false) {
7042 return asBlock
7043 ? (openBlock(), createBlock(Comment, null, text))
7044 : createVNode(Comment, null, text);
7045}
7046function normalizeVNode(child) {
7047 if (child == null || typeof child === 'boolean') {
7048 // empty placeholder
7049 return createVNode(Comment);
7050 }
7051 else if (isArray(child)) {
7052 // fragment
7053 return createVNode(Fragment, null,
7054 // #3666, avoid reference pollution when reusing vnode
7055 child.slice());
7056 }
7057 else if (typeof child === 'object') {
7058 // already vnode, this should be the most common since compiled templates
7059 // always produce all-vnode children arrays
7060 return cloneIfMounted(child);
7061 }
7062 else {
7063 // strings and numbers
7064 return createVNode(Text, null, String(child));
7065 }
7066}
7067// optimized normalization for template-compiled render fns
7068function cloneIfMounted(child) {
7069 return child.el === null || child.memo ? child : cloneVNode(child);
7070}
7071function normalizeChildren(vnode, children) {
7072 let type = 0;
7073 const { shapeFlag } = vnode;
7074 if (children == null) {
7075 children = null;
7076 }
7077 else if (isArray(children)) {
7078 type = 16 /* ARRAY_CHILDREN */;
7079 }
7080 else if (typeof children === 'object') {
7081 if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
7082 // Normalize slot to plain children for plain element and Teleport
7083 const slot = children.default;
7084 if (slot) {
7085 // _c marker is added by withCtx() indicating this is a compiled slot
7086 slot._c && (slot._d = false);
7087 normalizeChildren(vnode, slot());
7088 slot._c && (slot._d = true);
7089 }
7090 return;
7091 }
7092 else {
7093 type = 32 /* SLOTS_CHILDREN */;
7094 const slotFlag = children._;
7095 if (!slotFlag && !(InternalObjectKey in children)) {
7096 children._ctx = currentRenderingInstance;
7097 }
7098 else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
7099 // a child component receives forwarded slots from the parent.
7100 // its slot type is determined by its parent's slot type.
7101 if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
7102 children._ = 1 /* STABLE */;
7103 }
7104 else {
7105 children._ = 2 /* DYNAMIC */;
7106 vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
7107 }
7108 }
7109 }
7110 }
7111 else if (isFunction(children)) {
7112 children = { default: children, _ctx: currentRenderingInstance };
7113 type = 32 /* SLOTS_CHILDREN */;
7114 }
7115 else {
7116 children = String(children);
7117 // force teleport children to array so it can be moved around
7118 if (shapeFlag & 64 /* TELEPORT */) {
7119 type = 16 /* ARRAY_CHILDREN */;
7120 children = [createTextVNode(children)];
7121 }
7122 else {
7123 type = 8 /* TEXT_CHILDREN */;
7124 }
7125 }
7126 vnode.children = children;
7127 vnode.shapeFlag |= type;
7128}
7129function mergeProps(...args) {
7130 const ret = {};
7131 for (let i = 0; i < args.length; i++) {
7132 const toMerge = args[i];
7133 for (const key in toMerge) {
7134 if (key === 'class') {
7135 if (ret.class !== toMerge.class) {
7136 ret.class = normalizeClass([ret.class, toMerge.class]);
7137 }
7138 }
7139 else if (key === 'style') {
7140 ret.style = normalizeStyle([ret.style, toMerge.style]);
7141 }
7142 else if (isOn(key)) {
7143 const existing = ret[key];
7144 const incoming = toMerge[key];
7145 if (existing !== incoming) {
7146 ret[key] = existing
7147 ? [].concat(existing, incoming)
7148 : incoming;
7149 }
7150 }
7151 else if (key !== '') {
7152 ret[key] = toMerge[key];
7153 }
7154 }
7155 }
7156 return ret;
7157}
7158
7159/**
7160 * Actual implementation
7161 */
7162function renderList(source, renderItem, cache, index) {
7163 let ret;
7164 const cached = (cache && cache[index]);
7165 if (isArray(source) || isString(source)) {
7166 ret = new Array(source.length);
7167 for (let i = 0, l = source.length; i < l; i++) {
7168 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
7169 }
7170 }
7171 else if (typeof source === 'number') {
7172 if (!Number.isInteger(source)) {
7173 warn$1(`The v-for range expect an integer value but got ${source}.`);
7174 return [];
7175 }
7176 ret = new Array(source);
7177 for (let i = 0; i < source; i++) {
7178 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
7179 }
7180 }
7181 else if (isObject(source)) {
7182 if (source[Symbol.iterator]) {
7183 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
7184 }
7185 else {
7186 const keys = Object.keys(source);
7187 ret = new Array(keys.length);
7188 for (let i = 0, l = keys.length; i < l; i++) {
7189 const key = keys[i];
7190 ret[i] = renderItem(source[key], key, i, cached && cached[i]);
7191 }
7192 }
7193 }
7194 else {
7195 ret = [];
7196 }
7197 if (cache) {
7198 cache[index] = ret;
7199 }
7200 return ret;
7201}
7202
7203/**
7204 * Compiler runtime helper for creating dynamic slots object
7205 * @private
7206 */
7207function createSlots(slots, dynamicSlots) {
7208 for (let i = 0; i < dynamicSlots.length; i++) {
7209 const slot = dynamicSlots[i];
7210 // array of dynamic slot generated by <template v-for="..." #[...]>
7211 if (isArray(slot)) {
7212 for (let j = 0; j < slot.length; j++) {
7213 slots[slot[j].name] = slot[j].fn;
7214 }
7215 }
7216 else if (slot) {
7217 // conditional single slot generated by <template v-if="..." #foo>
7218 slots[slot.name] = slot.fn;
7219 }
7220 }
7221 return slots;
7222}
7223
7224/**
7225 * Compiler runtime helper for rendering `<slot/>`
7226 * @private
7227 */
7228function renderSlot(slots, name, props = {},
7229// this is not a user-facing function, so the fallback is always generated by
7230// the compiler and guaranteed to be a function returning an array
7231fallback, noSlotted) {
7232 if (currentRenderingInstance.isCE) {
7233 return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback());
7234 }
7235 let slot = slots[name];
7236 if (slot && slot.length > 1) {
7237 warn$1(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
7238 `function. You need to mark this component with $dynamic-slots in the ` +
7239 `parent template.`);
7240 slot = () => [];
7241 }
7242 // a compiled slot disables block tracking by default to avoid manual
7243 // invocation interfering with template-based block tracking, but in
7244 // `renderSlot` we can be sure that it's template-based so we can force
7245 // enable it.
7246 if (slot && slot._c) {
7247 slot._d = false;
7248 }
7249 openBlock();
7250 const validSlotContent = slot && ensureValidVNode(slot(props));
7251 const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
7252 ? 64 /* STABLE_FRAGMENT */
7253 : -2 /* BAIL */);
7254 if (!noSlotted && rendered.scopeId) {
7255 rendered.slotScopeIds = [rendered.scopeId + '-s'];
7256 }
7257 if (slot && slot._c) {
7258 slot._d = true;
7259 }
7260 return rendered;
7261}
7262function ensureValidVNode(vnodes) {
7263 return vnodes.some(child => {
7264 if (!isVNode(child))
7265 return true;
7266 if (child.type === Comment)
7267 return false;
7268 if (child.type === Fragment &&
7269 !ensureValidVNode(child.children))
7270 return false;
7271 return true;
7272 })
7273 ? vnodes
7274 : null;
7275}
7276
7277/**
7278 * For prefixing keys in v-on="obj" with "on"
7279 * @private
7280 */
7281function toHandlers(obj) {
7282 const ret = {};
7283 if (!isObject(obj)) {
7284 warn$1(`v-on with no argument expects an object value.`);
7285 return ret;
7286 }
7287 for (const key in obj) {
7288 ret[toHandlerKey(key)] = obj[key];
7289 }
7290 return ret;
7291}
7292
7293/**
7294 * #2437 In Vue 3, functional components do not have a public instance proxy but
7295 * they exist in the internal parent chain. For code that relies on traversing
7296 * public $parent chains, skip functional ones and go to the parent instead.
7297 */
7298const getPublicInstance = (i) => {
7299 if (!i)
7300 return null;
7301 if (isStatefulComponent(i))
7302 return getExposeProxy(i) || i.proxy;
7303 return getPublicInstance(i.parent);
7304};
7305const publicPropertiesMap = extend(Object.create(null), {
7306 $: i => i,
7307 $el: i => i.vnode.el,
7308 $data: i => i.data,
7309 $props: i => (shallowReadonly(i.props) ),
7310 $attrs: i => (shallowReadonly(i.attrs) ),
7311 $slots: i => (shallowReadonly(i.slots) ),
7312 $refs: i => (shallowReadonly(i.refs) ),
7313 $parent: i => getPublicInstance(i.parent),
7314 $root: i => getPublicInstance(i.root),
7315 $emit: i => i.emit,
7316 $options: i => (resolveMergedOptions(i) ),
7317 $forceUpdate: i => () => queueJob(i.update),
7318 $nextTick: i => nextTick.bind(i.proxy),
7319 $watch: i => (instanceWatch.bind(i) )
7320});
7321const PublicInstanceProxyHandlers = {
7322 get({ _: instance }, key) {
7323 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
7324 // for internal formatters to know that this is a Vue instance
7325 if (key === '__isVue') {
7326 return true;
7327 }
7328 // prioritize <script setup> bindings during dev.
7329 // this allows even properties that start with _ or $ to be used - so that
7330 // it aligns with the production behavior where the render fn is inlined and
7331 // indeed has access to all declared variables.
7332 if (setupState !== EMPTY_OBJ &&
7333 setupState.__isScriptSetup &&
7334 hasOwn(setupState, key)) {
7335 return setupState[key];
7336 }
7337 // data / props / ctx
7338 // This getter gets called for every property access on the render context
7339 // during render and is a major hotspot. The most expensive part of this
7340 // is the multiple hasOwn() calls. It's much faster to do a simple property
7341 // access on a plain object, so we use an accessCache object (with null
7342 // prototype) to memoize what access type a key corresponds to.
7343 let normalizedProps;
7344 if (key[0] !== '$') {
7345 const n = accessCache[key];
7346 if (n !== undefined) {
7347 switch (n) {
7348 case 0 /* SETUP */:
7349 return setupState[key];
7350 case 1 /* DATA */:
7351 return data[key];
7352 case 3 /* CONTEXT */:
7353 return ctx[key];
7354 case 2 /* PROPS */:
7355 return props[key];
7356 // default: just fallthrough
7357 }
7358 }
7359 else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7360 accessCache[key] = 0 /* SETUP */;
7361 return setupState[key];
7362 }
7363 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7364 accessCache[key] = 1 /* DATA */;
7365 return data[key];
7366 }
7367 else if (
7368 // only cache other properties when instance has declared (thus stable)
7369 // props
7370 (normalizedProps = instance.propsOptions[0]) &&
7371 hasOwn(normalizedProps, key)) {
7372 accessCache[key] = 2 /* PROPS */;
7373 return props[key];
7374 }
7375 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7376 accessCache[key] = 3 /* CONTEXT */;
7377 return ctx[key];
7378 }
7379 else if (shouldCacheAccess) {
7380 accessCache[key] = 4 /* OTHER */;
7381 }
7382 }
7383 const publicGetter = publicPropertiesMap[key];
7384 let cssModule, globalProperties;
7385 // public $xxx properties
7386 if (publicGetter) {
7387 if (key === '$attrs') {
7388 track(instance, "get" /* GET */, key);
7389 markAttrsAccessed();
7390 }
7391 return publicGetter(instance);
7392 }
7393 else if (
7394 // css module (injected by vue-loader)
7395 (cssModule = type.__cssModules) &&
7396 (cssModule = cssModule[key])) {
7397 return cssModule;
7398 }
7399 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7400 // user may set custom properties to `this` that start with `$`
7401 accessCache[key] = 3 /* CONTEXT */;
7402 return ctx[key];
7403 }
7404 else if (
7405 // global properties
7406 ((globalProperties = appContext.config.globalProperties),
7407 hasOwn(globalProperties, key))) {
7408 {
7409 return globalProperties[key];
7410 }
7411 }
7412 else if (currentRenderingInstance &&
7413 (!isString(key) ||
7414 // #1091 avoid internal isRef/isVNode checks on component instance leading
7415 // to infinite warning loop
7416 key.indexOf('__v') !== 0)) {
7417 if (data !== EMPTY_OBJ &&
7418 (key[0] === '$' || key[0] === '_') &&
7419 hasOwn(data, key)) {
7420 warn$1(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
7421 `character ("$" or "_") and is not proxied on the render context.`);
7422 }
7423 else if (instance === currentRenderingInstance) {
7424 warn$1(`Property ${JSON.stringify(key)} was accessed during render ` +
7425 `but is not defined on instance.`);
7426 }
7427 }
7428 },
7429 set({ _: instance }, key, value) {
7430 const { data, setupState, ctx } = instance;
7431 if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7432 setupState[key] = value;
7433 }
7434 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7435 data[key] = value;
7436 }
7437 else if (hasOwn(instance.props, key)) {
7438 warn$1(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
7439 return false;
7440 }
7441 if (key[0] === '$' && key.slice(1) in instance) {
7442 warn$1(`Attempting to mutate public property "${key}". ` +
7443 `Properties starting with $ are reserved and readonly.`, instance);
7444 return false;
7445 }
7446 else {
7447 if (key in instance.appContext.config.globalProperties) {
7448 Object.defineProperty(ctx, key, {
7449 enumerable: true,
7450 configurable: true,
7451 value
7452 });
7453 }
7454 else {
7455 ctx[key] = value;
7456 }
7457 }
7458 return true;
7459 },
7460 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7461 let normalizedProps;
7462 return (accessCache[key] !== undefined ||
7463 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7464 (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7465 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
7466 hasOwn(ctx, key) ||
7467 hasOwn(publicPropertiesMap, key) ||
7468 hasOwn(appContext.config.globalProperties, key));
7469 }
7470};
7471{
7472 PublicInstanceProxyHandlers.ownKeys = (target) => {
7473 warn$1(`Avoid app logic that relies on enumerating keys on a component instance. ` +
7474 `The keys will be empty in production mode to avoid performance overhead.`);
7475 return Reflect.ownKeys(target);
7476 };
7477}
7478const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, {
7479 get(target, key) {
7480 // fast path for unscopables when using `with` block
7481 if (key === Symbol.unscopables) {
7482 return;
7483 }
7484 return PublicInstanceProxyHandlers.get(target, key, target);
7485 },
7486 has(_, key) {
7487 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
7488 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
7489 warn$1(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
7490 }
7491 return has;
7492 }
7493});
7494// dev only
7495// In dev mode, the proxy target exposes the same properties as seen on `this`
7496// for easier console inspection. In prod mode it will be an empty object so
7497// these properties definitions can be skipped.
7498function createDevRenderContext(instance) {
7499 const target = {};
7500 // expose internal instance for proxy handlers
7501 Object.defineProperty(target, `_`, {
7502 configurable: true,
7503 enumerable: false,
7504 get: () => instance
7505 });
7506 // expose public properties
7507 Object.keys(publicPropertiesMap).forEach(key => {
7508 Object.defineProperty(target, key, {
7509 configurable: true,
7510 enumerable: false,
7511 get: () => publicPropertiesMap[key](instance),
7512 // intercepted by the proxy so no need for implementation,
7513 // but needed to prevent set errors
7514 set: NOOP
7515 });
7516 });
7517 return target;
7518}
7519// dev only
7520function exposePropsOnRenderContext(instance) {
7521 const { ctx, propsOptions: [propsOptions] } = instance;
7522 if (propsOptions) {
7523 Object.keys(propsOptions).forEach(key => {
7524 Object.defineProperty(ctx, key, {
7525 enumerable: true,
7526 configurable: true,
7527 get: () => instance.props[key],
7528 set: NOOP
7529 });
7530 });
7531 }
7532}
7533// dev only
7534function exposeSetupStateOnRenderContext(instance) {
7535 const { ctx, setupState } = instance;
7536 Object.keys(toRaw(setupState)).forEach(key => {
7537 if (!setupState.__isScriptSetup) {
7538 if (key[0] === '$' || key[0] === '_') {
7539 warn$1(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
7540 `which are reserved prefixes for Vue internals.`);
7541 return;
7542 }
7543 Object.defineProperty(ctx, key, {
7544 enumerable: true,
7545 configurable: true,
7546 get: () => setupState[key],
7547 set: NOOP
7548 });
7549 }
7550 });
7551}
7552
7553const emptyAppContext = createAppContext();
7554let uid$1 = 0;
7555function createComponentInstance(vnode, parent, suspense) {
7556 const type = vnode.type;
7557 // inherit parent app context - or - if root, adopt from root vnode
7558 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
7559 const instance = {
7560 uid: uid$1++,
7561 vnode,
7562 type,
7563 parent,
7564 appContext,
7565 root: null,
7566 next: null,
7567 subTree: null,
7568 update: null,
7569 scope: new EffectScope(true /* detached */),
7570 render: null,
7571 proxy: null,
7572 exposed: null,
7573 exposeProxy: null,
7574 withProxy: null,
7575 provides: parent ? parent.provides : Object.create(appContext.provides),
7576 accessCache: null,
7577 renderCache: [],
7578 // local resovled assets
7579 components: null,
7580 directives: null,
7581 // resolved props and emits options
7582 propsOptions: normalizePropsOptions(type, appContext),
7583 emitsOptions: normalizeEmitsOptions(type, appContext),
7584 // emit
7585 emit: null,
7586 emitted: null,
7587 // props default value
7588 propsDefaults: EMPTY_OBJ,
7589 // inheritAttrs
7590 inheritAttrs: type.inheritAttrs,
7591 // state
7592 ctx: EMPTY_OBJ,
7593 data: EMPTY_OBJ,
7594 props: EMPTY_OBJ,
7595 attrs: EMPTY_OBJ,
7596 slots: EMPTY_OBJ,
7597 refs: EMPTY_OBJ,
7598 setupState: EMPTY_OBJ,
7599 setupContext: null,
7600 // suspense related
7601 suspense,
7602 suspenseId: suspense ? suspense.pendingId : 0,
7603 asyncDep: null,
7604 asyncResolved: false,
7605 // lifecycle hooks
7606 // not using enums here because it results in computed properties
7607 isMounted: false,
7608 isUnmounted: false,
7609 isDeactivated: false,
7610 bc: null,
7611 c: null,
7612 bm: null,
7613 m: null,
7614 bu: null,
7615 u: null,
7616 um: null,
7617 bum: null,
7618 da: null,
7619 a: null,
7620 rtg: null,
7621 rtc: null,
7622 ec: null,
7623 sp: null
7624 };
7625 {
7626 instance.ctx = createDevRenderContext(instance);
7627 }
7628 instance.root = parent ? parent.root : instance;
7629 instance.emit = emit$1.bind(null, instance);
7630 // apply custom element special handling
7631 if (vnode.ce) {
7632 vnode.ce(instance);
7633 }
7634 return instance;
7635}
7636let currentInstance = null;
7637const getCurrentInstance = () => currentInstance || currentRenderingInstance;
7638const setCurrentInstance = (instance) => {
7639 currentInstance = instance;
7640 instance.scope.on();
7641};
7642const unsetCurrentInstance = () => {
7643 currentInstance && currentInstance.scope.off();
7644 currentInstance = null;
7645};
7646const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
7647function validateComponentName(name, config) {
7648 const appIsNativeTag = config.isNativeTag || NO;
7649 if (isBuiltInTag(name) || appIsNativeTag(name)) {
7650 warn$1('Do not use built-in or reserved HTML elements as component id: ' + name);
7651 }
7652}
7653function isStatefulComponent(instance) {
7654 return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
7655}
7656let isInSSRComponentSetup = false;
7657function setupComponent(instance, isSSR = false) {
7658 isInSSRComponentSetup = isSSR;
7659 const { props, children } = instance.vnode;
7660 const isStateful = isStatefulComponent(instance);
7661 initProps(instance, props, isStateful, isSSR);
7662 initSlots(instance, children);
7663 const setupResult = isStateful
7664 ? setupStatefulComponent(instance, isSSR)
7665 : undefined;
7666 isInSSRComponentSetup = false;
7667 return setupResult;
7668}
7669function setupStatefulComponent(instance, isSSR) {
7670 const Component = instance.type;
7671 {
7672 if (Component.name) {
7673 validateComponentName(Component.name, instance.appContext.config);
7674 }
7675 if (Component.components) {
7676 const names = Object.keys(Component.components);
7677 for (let i = 0; i < names.length; i++) {
7678 validateComponentName(names[i], instance.appContext.config);
7679 }
7680 }
7681 if (Component.directives) {
7682 const names = Object.keys(Component.directives);
7683 for (let i = 0; i < names.length; i++) {
7684 validateDirectiveName(names[i]);
7685 }
7686 }
7687 if (Component.compilerOptions && isRuntimeOnly()) {
7688 warn$1(`"compilerOptions" is only supported when using a build of Vue that ` +
7689 `includes the runtime compiler. Since you are using a runtime-only ` +
7690 `build, the options should be passed via your build tool config instead.`);
7691 }
7692 }
7693 // 0. create render proxy property access cache
7694 instance.accessCache = Object.create(null);
7695 // 1. create public instance / render proxy
7696 // also mark it raw so it's never observed
7697 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
7698 {
7699 exposePropsOnRenderContext(instance);
7700 }
7701 // 2. call setup()
7702 const { setup } = Component;
7703 if (setup) {
7704 const setupContext = (instance.setupContext =
7705 setup.length > 1 ? createSetupContext(instance) : null);
7706 setCurrentInstance(instance);
7707 pauseTracking();
7708 const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
7709 resetTracking();
7710 unsetCurrentInstance();
7711 if (isPromise(setupResult)) {
7712 setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
7713 if (isSSR) {
7714 // return the promise so server-renderer can wait on it
7715 return setupResult
7716 .then((resolvedResult) => {
7717 handleSetupResult(instance, resolvedResult, isSSR);
7718 })
7719 .catch(e => {
7720 handleError(e, instance, 0 /* SETUP_FUNCTION */);
7721 });
7722 }
7723 else {
7724 // async setup returned Promise.
7725 // bail here and wait for re-entry.
7726 instance.asyncDep = setupResult;
7727 }
7728 }
7729 else {
7730 handleSetupResult(instance, setupResult, isSSR);
7731 }
7732 }
7733 else {
7734 finishComponentSetup(instance, isSSR);
7735 }
7736}
7737function handleSetupResult(instance, setupResult, isSSR) {
7738 if (isFunction(setupResult)) {
7739 // setup returned an inline render function
7740 {
7741 instance.render = setupResult;
7742 }
7743 }
7744 else if (isObject(setupResult)) {
7745 if (isVNode(setupResult)) {
7746 warn$1(`setup() should not return VNodes directly - ` +
7747 `return a render function instead.`);
7748 }
7749 // setup returned bindings.
7750 // assuming a render function compiled from template is present.
7751 {
7752 instance.devtoolsRawSetupState = setupResult;
7753 }
7754 instance.setupState = proxyRefs(setupResult);
7755 {
7756 exposeSetupStateOnRenderContext(instance);
7757 }
7758 }
7759 else if (setupResult !== undefined) {
7760 warn$1(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
7761 }
7762 finishComponentSetup(instance, isSSR);
7763}
7764let compile;
7765let installWithProxy;
7766/**
7767 * For runtime-dom to register the compiler.
7768 * Note the exported method uses any to avoid d.ts relying on the compiler types.
7769 */
7770function registerRuntimeCompiler(_compile) {
7771 compile = _compile;
7772 installWithProxy = i => {
7773 if (i.render._rc) {
7774 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
7775 }
7776 };
7777}
7778// dev only
7779const isRuntimeOnly = () => !compile;
7780function finishComponentSetup(instance, isSSR, skipOptions) {
7781 const Component = instance.type;
7782 // template / render function normalization
7783 // could be already set when returned from setup()
7784 if (!instance.render) {
7785 // only do on-the-fly compile if not in SSR - SSR on-the-fly compliation
7786 // is done by server-renderer
7787 if (!isSSR && compile && !Component.render) {
7788 const template = Component.template;
7789 if (template) {
7790 {
7791 startMeasure(instance, `compile`);
7792 }
7793 const { isCustomElement, compilerOptions } = instance.appContext.config;
7794 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
7795 const finalCompilerOptions = extend(extend({
7796 isCustomElement,
7797 delimiters
7798 }, compilerOptions), componentCompilerOptions);
7799 Component.render = compile(template, finalCompilerOptions);
7800 {
7801 endMeasure(instance, `compile`);
7802 }
7803 }
7804 }
7805 instance.render = (Component.render || NOOP);
7806 // for runtime-compiled render functions using `with` blocks, the render
7807 // proxy used needs a different `has` handler which is more performant and
7808 // also only allows a whitelist of globals to fallthrough.
7809 if (installWithProxy) {
7810 installWithProxy(instance);
7811 }
7812 }
7813 // support for 2.x options
7814 {
7815 setCurrentInstance(instance);
7816 pauseTracking();
7817 applyOptions(instance);
7818 resetTracking();
7819 unsetCurrentInstance();
7820 }
7821 // warn missing template/render
7822 // the runtime compilation of template in SSR is done by server-render
7823 if (!Component.render && instance.render === NOOP && !isSSR) {
7824 /* istanbul ignore if */
7825 if (!compile && Component.template) {
7826 warn$1(`Component provided template option but ` +
7827 `runtime compilation is not supported in this build of Vue.` +
7828 (` Use "vue.esm-browser.js" instead.`
7829 ) /* should not happen */);
7830 }
7831 else {
7832 warn$1(`Component is missing template or render function.`);
7833 }
7834 }
7835}
7836function createAttrsProxy(instance) {
7837 return new Proxy(instance.attrs, {
7838 get(target, key) {
7839 markAttrsAccessed();
7840 track(instance, "get" /* GET */, '$attrs');
7841 return target[key];
7842 },
7843 set() {
7844 warn$1(`setupContext.attrs is readonly.`);
7845 return false;
7846 },
7847 deleteProperty() {
7848 warn$1(`setupContext.attrs is readonly.`);
7849 return false;
7850 }
7851 }
7852 );
7853}
7854function createSetupContext(instance) {
7855 const expose = exposed => {
7856 if (instance.exposed) {
7857 warn$1(`expose() should be called only once per setup().`);
7858 }
7859 instance.exposed = exposed || {};
7860 };
7861 let attrs;
7862 {
7863 // We use getters in dev in case libs like test-utils overwrite instance
7864 // properties (overwrites should not be done in prod)
7865 return Object.freeze({
7866 get attrs() {
7867 return attrs || (attrs = createAttrsProxy(instance));
7868 },
7869 get slots() {
7870 return shallowReadonly(instance.slots);
7871 },
7872 get emit() {
7873 return (event, ...args) => instance.emit(event, ...args);
7874 },
7875 expose
7876 });
7877 }
7878}
7879function getExposeProxy(instance) {
7880 if (instance.exposed) {
7881 return (instance.exposeProxy ||
7882 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
7883 get(target, key) {
7884 if (key in target) {
7885 return target[key];
7886 }
7887 else if (key in publicPropertiesMap) {
7888 return publicPropertiesMap[key](instance);
7889 }
7890 }
7891 })));
7892 }
7893}
7894const classifyRE = /(?:^|[-_])(\w)/g;
7895const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
7896function getComponentName(Component) {
7897 return isFunction(Component)
7898 ? Component.displayName || Component.name
7899 : Component.name;
7900}
7901/* istanbul ignore next */
7902function formatComponentName(instance, Component, isRoot = false) {
7903 let name = getComponentName(Component);
7904 if (!name && Component.__file) {
7905 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
7906 if (match) {
7907 name = match[1];
7908 }
7909 }
7910 if (!name && instance && instance.parent) {
7911 // try to infer the name based on reverse resolution
7912 const inferFromRegistry = (registry) => {
7913 for (const key in registry) {
7914 if (registry[key] === Component) {
7915 return key;
7916 }
7917 }
7918 };
7919 name =
7920 inferFromRegistry(instance.components ||
7921 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
7922 }
7923 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
7924}
7925function isClassComponent(value) {
7926 return isFunction(value) && '__vccOpts' in value;
7927}
7928
7929const stack = [];
7930function pushWarningContext(vnode) {
7931 stack.push(vnode);
7932}
7933function popWarningContext() {
7934 stack.pop();
7935}
7936function warn$1(msg, ...args) {
7937 // avoid props formatting or warn handler tracking deps that might be mutated
7938 // during patch, leading to infinite recursion.
7939 pauseTracking();
7940 const instance = stack.length ? stack[stack.length - 1].component : null;
7941 const appWarnHandler = instance && instance.appContext.config.warnHandler;
7942 const trace = getComponentTrace();
7943 if (appWarnHandler) {
7944 callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
7945 msg + args.join(''),
7946 instance && instance.proxy,
7947 trace
7948 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
7949 .join('\n'),
7950 trace
7951 ]);
7952 }
7953 else {
7954 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
7955 /* istanbul ignore if */
7956 if (trace.length &&
7957 // avoid spamming console during tests
7958 !false) {
7959 warnArgs.push(`\n`, ...formatTrace(trace));
7960 }
7961 console.warn(...warnArgs);
7962 }
7963 resetTracking();
7964}
7965function getComponentTrace() {
7966 let currentVNode = stack[stack.length - 1];
7967 if (!currentVNode) {
7968 return [];
7969 }
7970 // we can't just use the stack because it will be incomplete during updates
7971 // that did not start from the root. Re-construct the parent chain using
7972 // instance parent pointers.
7973 const normalizedStack = [];
7974 while (currentVNode) {
7975 const last = normalizedStack[0];
7976 if (last && last.vnode === currentVNode) {
7977 last.recurseCount++;
7978 }
7979 else {
7980 normalizedStack.push({
7981 vnode: currentVNode,
7982 recurseCount: 0
7983 });
7984 }
7985 const parentInstance = currentVNode.component && currentVNode.component.parent;
7986 currentVNode = parentInstance && parentInstance.vnode;
7987 }
7988 return normalizedStack;
7989}
7990/* istanbul ignore next */
7991function formatTrace(trace) {
7992 const logs = [];
7993 trace.forEach((entry, i) => {
7994 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
7995 });
7996 return logs;
7997}
7998function formatTraceEntry({ vnode, recurseCount }) {
7999 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
8000 const isRoot = vnode.component ? vnode.component.parent == null : false;
8001 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
8002 const close = `>` + postfix;
8003 return vnode.props
8004 ? [open, ...formatProps(vnode.props), close]
8005 : [open + close];
8006}
8007/* istanbul ignore next */
8008function formatProps(props) {
8009 const res = [];
8010 const keys = Object.keys(props);
8011 keys.slice(0, 3).forEach(key => {
8012 res.push(...formatProp(key, props[key]));
8013 });
8014 if (keys.length > 3) {
8015 res.push(` ...`);
8016 }
8017 return res;
8018}
8019/* istanbul ignore next */
8020function formatProp(key, value, raw) {
8021 if (isString(value)) {
8022 value = JSON.stringify(value);
8023 return raw ? value : [`${key}=${value}`];
8024 }
8025 else if (typeof value === 'number' ||
8026 typeof value === 'boolean' ||
8027 value == null) {
8028 return raw ? value : [`${key}=${value}`];
8029 }
8030 else if (isRef(value)) {
8031 value = formatProp(key, toRaw(value.value), true);
8032 return raw ? value : [`${key}=Ref<`, value, `>`];
8033 }
8034 else if (isFunction(value)) {
8035 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
8036 }
8037 else {
8038 value = toRaw(value);
8039 return raw ? value : [`${key}=`, value];
8040 }
8041}
8042
8043const ErrorTypeStrings = {
8044 ["sp" /* SERVER_PREFETCH */]: 'serverPrefetch hook',
8045 ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
8046 ["c" /* CREATED */]: 'created hook',
8047 ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
8048 ["m" /* MOUNTED */]: 'mounted hook',
8049 ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
8050 ["u" /* UPDATED */]: 'updated',
8051 ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
8052 ["um" /* UNMOUNTED */]: 'unmounted hook',
8053 ["a" /* ACTIVATED */]: 'activated hook',
8054 ["da" /* DEACTIVATED */]: 'deactivated hook',
8055 ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
8056 ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
8057 ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
8058 [0 /* SETUP_FUNCTION */]: 'setup function',
8059 [1 /* RENDER_FUNCTION */]: 'render function',
8060 [2 /* WATCH_GETTER */]: 'watcher getter',
8061 [3 /* WATCH_CALLBACK */]: 'watcher callback',
8062 [4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
8063 [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
8064 [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
8065 [7 /* VNODE_HOOK */]: 'vnode hook',
8066 [8 /* DIRECTIVE_HOOK */]: 'directive hook',
8067 [9 /* TRANSITION_HOOK */]: 'transition hook',
8068 [10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
8069 [11 /* APP_WARN_HANDLER */]: 'app warnHandler',
8070 [12 /* FUNCTION_REF */]: 'ref function',
8071 [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
8072 [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
8073 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
8074};
8075function callWithErrorHandling(fn, instance, type, args) {
8076 let res;
8077 try {
8078 res = args ? fn(...args) : fn();
8079 }
8080 catch (err) {
8081 handleError(err, instance, type);
8082 }
8083 return res;
8084}
8085function callWithAsyncErrorHandling(fn, instance, type, args) {
8086 if (isFunction(fn)) {
8087 const res = callWithErrorHandling(fn, instance, type, args);
8088 if (res && isPromise(res)) {
8089 res.catch(err => {
8090 handleError(err, instance, type);
8091 });
8092 }
8093 return res;
8094 }
8095 const values = [];
8096 for (let i = 0; i < fn.length; i++) {
8097 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
8098 }
8099 return values;
8100}
8101function handleError(err, instance, type, throwInDev = true) {
8102 const contextVNode = instance ? instance.vnode : null;
8103 if (instance) {
8104 let cur = instance.parent;
8105 // the exposed instance is the render proxy to keep it consistent with 2.x
8106 const exposedInstance = instance.proxy;
8107 // in production the hook receives only the error code
8108 const errorInfo = ErrorTypeStrings[type] ;
8109 while (cur) {
8110 const errorCapturedHooks = cur.ec;
8111 if (errorCapturedHooks) {
8112 for (let i = 0; i < errorCapturedHooks.length; i++) {
8113 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
8114 return;
8115 }
8116 }
8117 }
8118 cur = cur.parent;
8119 }
8120 // app-level handling
8121 const appErrorHandler = instance.appContext.config.errorHandler;
8122 if (appErrorHandler) {
8123 callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
8124 return;
8125 }
8126 }
8127 logError(err, type, contextVNode, throwInDev);
8128}
8129function logError(err, type, contextVNode, throwInDev = true) {
8130 {
8131 const info = ErrorTypeStrings[type];
8132 if (contextVNode) {
8133 pushWarningContext(contextVNode);
8134 }
8135 warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
8136 if (contextVNode) {
8137 popWarningContext();
8138 }
8139 // crash in dev by default so it's more noticeable
8140 if (throwInDev) {
8141 throw err;
8142 }
8143 else {
8144 console.error(err);
8145 }
8146 }
8147}
8148
8149let isFlushing = false;
8150let isFlushPending = false;
8151const queue = [];
8152let flushIndex = 0;
8153const pendingPreFlushCbs = [];
8154let activePreFlushCbs = null;
8155let preFlushIndex = 0;
8156const pendingPostFlushCbs = [];
8157let activePostFlushCbs = null;
8158let postFlushIndex = 0;
8159const resolvedPromise = Promise.resolve();
8160let currentFlushPromise = null;
8161let currentPreFlushParentJob = null;
8162const RECURSION_LIMIT = 100;
8163function nextTick(fn) {
8164 const p = currentFlushPromise || resolvedPromise;
8165 return fn ? p.then(this ? fn.bind(this) : fn) : p;
8166}
8167// #2768
8168// Use binary-search to find a suitable position in the queue,
8169// so that the queue maintains the increasing order of job's id,
8170// which can prevent the job from being skipped and also can avoid repeated patching.
8171function findInsertionIndex(id) {
8172 // the start index should be `flushIndex + 1`
8173 let start = flushIndex + 1;
8174 let end = queue.length;
8175 while (start < end) {
8176 const middle = (start + end) >>> 1;
8177 const middleJobId = getId(queue[middle]);
8178 middleJobId < id ? (start = middle + 1) : (end = middle);
8179 }
8180 return start;
8181}
8182function queueJob(job) {
8183 // the dedupe search uses the startIndex argument of Array.includes()
8184 // by default the search index includes the current job that is being run
8185 // so it cannot recursively trigger itself again.
8186 // if the job is a watch() callback, the search will start with a +1 index to
8187 // allow it recursively trigger itself - it is the user's responsibility to
8188 // ensure it doesn't end up in an infinite loop.
8189 if ((!queue.length ||
8190 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
8191 job !== currentPreFlushParentJob) {
8192 if (job.id == null) {
8193 queue.push(job);
8194 }
8195 else {
8196 queue.splice(findInsertionIndex(job.id), 0, job);
8197 }
8198 queueFlush();
8199 }
8200}
8201function queueFlush() {
8202 if (!isFlushing && !isFlushPending) {
8203 isFlushPending = true;
8204 currentFlushPromise = resolvedPromise.then(flushJobs);
8205 }
8206}
8207function invalidateJob(job) {
8208 const i = queue.indexOf(job);
8209 if (i > flushIndex) {
8210 queue.splice(i, 1);
8211 }
8212}
8213function queueCb(cb, activeQueue, pendingQueue, index) {
8214 if (!isArray(cb)) {
8215 if (!activeQueue ||
8216 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
8217 pendingQueue.push(cb);
8218 }
8219 }
8220 else {
8221 // if cb is an array, it is a component lifecycle hook which can only be
8222 // triggered by a job, which is already deduped in the main queue, so
8223 // we can skip duplicate check here to improve perf
8224 pendingQueue.push(...cb);
8225 }
8226 queueFlush();
8227}
8228function queuePreFlushCb(cb) {
8229 queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
8230}
8231function queuePostFlushCb(cb) {
8232 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
8233}
8234function flushPreFlushCbs(seen, parentJob = null) {
8235 if (pendingPreFlushCbs.length) {
8236 currentPreFlushParentJob = parentJob;
8237 activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
8238 pendingPreFlushCbs.length = 0;
8239 {
8240 seen = seen || new Map();
8241 }
8242 for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
8243 if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) {
8244 continue;
8245 }
8246 activePreFlushCbs[preFlushIndex]();
8247 }
8248 activePreFlushCbs = null;
8249 preFlushIndex = 0;
8250 currentPreFlushParentJob = null;
8251 // recursively flush until it drains
8252 flushPreFlushCbs(seen, parentJob);
8253 }
8254}
8255function flushPostFlushCbs(seen) {
8256 if (pendingPostFlushCbs.length) {
8257 const deduped = [...new Set(pendingPostFlushCbs)];
8258 pendingPostFlushCbs.length = 0;
8259 // #1947 already has active queue, nested flushPostFlushCbs call
8260 if (activePostFlushCbs) {
8261 activePostFlushCbs.push(...deduped);
8262 return;
8263 }
8264 activePostFlushCbs = deduped;
8265 {
8266 seen = seen || new Map();
8267 }
8268 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
8269 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
8270 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
8271 continue;
8272 }
8273 activePostFlushCbs[postFlushIndex]();
8274 }
8275 activePostFlushCbs = null;
8276 postFlushIndex = 0;
8277 }
8278}
8279const getId = (job) => job.id == null ? Infinity : job.id;
8280function flushJobs(seen) {
8281 isFlushPending = false;
8282 isFlushing = true;
8283 {
8284 seen = seen || new Map();
8285 }
8286 flushPreFlushCbs(seen);
8287 // Sort queue before flush.
8288 // This ensures that:
8289 // 1. Components are updated from parent to child. (because parent is always
8290 // created before the child so its render effect will have smaller
8291 // priority number)
8292 // 2. If a component is unmounted during a parent component's update,
8293 // its update can be skipped.
8294 queue.sort((a, b) => getId(a) - getId(b));
8295 // conditional usage of checkRecursiveUpdate must be determined out of
8296 // try ... catch block since Rollup by default de-optimizes treeshaking
8297 // inside try-catch. This can leave all warning code unshaked. Although
8298 // they would get eventually shaken by a minifier like terser, some minifiers
8299 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610)
8300 const check = (job) => checkRecursiveUpdates(seen, job)
8301 ;
8302 try {
8303 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
8304 const job = queue[flushIndex];
8305 if (job && job.active !== false) {
8306 if (true && check(job)) {
8307 continue;
8308 }
8309 // console.log(`running:`, job.id)
8310 callWithErrorHandling(job, null, 14 /* SCHEDULER */);
8311 }
8312 }
8313 }
8314 finally {
8315 flushIndex = 0;
8316 queue.length = 0;
8317 flushPostFlushCbs(seen);
8318 isFlushing = false;
8319 currentFlushPromise = null;
8320 // some postFlushCb queued jobs!
8321 // keep flushing until it drains.
8322 if (queue.length ||
8323 pendingPreFlushCbs.length ||
8324 pendingPostFlushCbs.length) {
8325 flushJobs(seen);
8326 }
8327 }
8328}
8329function checkRecursiveUpdates(seen, fn) {
8330 if (!seen.has(fn)) {
8331 seen.set(fn, 1);
8332 }
8333 else {
8334 const count = seen.get(fn);
8335 if (count > RECURSION_LIMIT) {
8336 const instance = fn.ownerInstance;
8337 const componentName = instance && getComponentName(instance.type);
8338 warn$1(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
8339 `This means you have a reactive effect that is mutating its own ` +
8340 `dependencies and thus recursively triggering itself. Possible sources ` +
8341 `include component template, render function, updated hook or ` +
8342 `watcher source function.`);
8343 return true;
8344 }
8345 else {
8346 seen.set(fn, count + 1);
8347 }
8348 }
8349}
8350
8351// Simple effect.
8352function watchEffect(effect, options) {
8353 return doWatch(effect, null, options);
8354}
8355function watchPostEffect(effect, options) {
8356 return doWatch(effect, null, (Object.assign(options || {}, { flush: 'post' })
8357 ));
8358}
8359function watchSyncEffect(effect, options) {
8360 return doWatch(effect, null, (Object.assign(options || {}, { flush: 'sync' })
8361 ));
8362}
8363// initial value for watchers to trigger on undefined initial values
8364const INITIAL_WATCHER_VALUE = {};
8365// implementation
8366function watch(source, cb, options) {
8367 if (!isFunction(cb)) {
8368 warn$1(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
8369 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
8370 `supports \`watch(source, cb, options?) signature.`);
8371 }
8372 return doWatch(source, cb, options);
8373}
8374function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
8375 if (!cb) {
8376 if (immediate !== undefined) {
8377 warn$1(`watch() "immediate" option is only respected when using the ` +
8378 `watch(source, callback, options?) signature.`);
8379 }
8380 if (deep !== undefined) {
8381 warn$1(`watch() "deep" option is only respected when using the ` +
8382 `watch(source, callback, options?) signature.`);
8383 }
8384 }
8385 const warnInvalidSource = (s) => {
8386 warn$1(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
8387 `a reactive object, or an array of these types.`);
8388 };
8389 const instance = currentInstance;
8390 let getter;
8391 let forceTrigger = false;
8392 let isMultiSource = false;
8393 if (isRef(source)) {
8394 getter = () => source.value;
8395 forceTrigger = !!source._shallow;
8396 }
8397 else if (isReactive(source)) {
8398 getter = () => source;
8399 deep = true;
8400 }
8401 else if (isArray(source)) {
8402 isMultiSource = true;
8403 forceTrigger = source.some(isReactive);
8404 getter = () => source.map(s => {
8405 if (isRef(s)) {
8406 return s.value;
8407 }
8408 else if (isReactive(s)) {
8409 return traverse(s);
8410 }
8411 else if (isFunction(s)) {
8412 return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
8413 }
8414 else {
8415 warnInvalidSource(s);
8416 }
8417 });
8418 }
8419 else if (isFunction(source)) {
8420 if (cb) {
8421 // getter with cb
8422 getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
8423 }
8424 else {
8425 // no cb -> simple effect
8426 getter = () => {
8427 if (instance && instance.isUnmounted) {
8428 return;
8429 }
8430 if (cleanup) {
8431 cleanup();
8432 }
8433 return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
8434 };
8435 }
8436 }
8437 else {
8438 getter = NOOP;
8439 warnInvalidSource(source);
8440 }
8441 if (cb && deep) {
8442 const baseGetter = getter;
8443 getter = () => traverse(baseGetter());
8444 }
8445 let cleanup;
8446 let onInvalidate = (fn) => {
8447 cleanup = effect.onStop = () => {
8448 callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
8449 };
8450 };
8451 let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;
8452 const job = () => {
8453 if (!effect.active) {
8454 return;
8455 }
8456 if (cb) {
8457 // watch(source, cb)
8458 const newValue = effect.run();
8459 if (deep ||
8460 forceTrigger ||
8461 (isMultiSource
8462 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
8463 : hasChanged(newValue, oldValue)) ||
8464 (false )) {
8465 // cleanup before running cb again
8466 if (cleanup) {
8467 cleanup();
8468 }
8469 callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
8470 newValue,
8471 // pass undefined as the old value when it's changed for the first time
8472 oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
8473 onInvalidate
8474 ]);
8475 oldValue = newValue;
8476 }
8477 }
8478 else {
8479 // watchEffect
8480 effect.run();
8481 }
8482 };
8483 // important: mark the job as a watcher callback so that scheduler knows
8484 // it is allowed to self-trigger (#1727)
8485 job.allowRecurse = !!cb;
8486 let scheduler;
8487 if (flush === 'sync') {
8488 scheduler = job; // the scheduler function gets called directly
8489 }
8490 else if (flush === 'post') {
8491 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
8492 }
8493 else {
8494 // default: 'pre'
8495 scheduler = () => {
8496 if (!instance || instance.isMounted) {
8497 queuePreFlushCb(job);
8498 }
8499 else {
8500 // with 'pre' option, the first call must happen before
8501 // the component is mounted so it is called synchronously.
8502 job();
8503 }
8504 };
8505 }
8506 const effect = new ReactiveEffect(getter, scheduler);
8507 {
8508 effect.onTrack = onTrack;
8509 effect.onTrigger = onTrigger;
8510 }
8511 // initial run
8512 if (cb) {
8513 if (immediate) {
8514 job();
8515 }
8516 else {
8517 oldValue = effect.run();
8518 }
8519 }
8520 else if (flush === 'post') {
8521 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
8522 }
8523 else {
8524 effect.run();
8525 }
8526 return () => {
8527 effect.stop();
8528 if (instance && instance.scope) {
8529 remove(instance.scope.effects, effect);
8530 }
8531 };
8532}
8533// this.$watch
8534function instanceWatch(source, value, options) {
8535 const publicThis = this.proxy;
8536 const getter = isString(source)
8537 ? source.includes('.')
8538 ? createPathGetter(publicThis, source)
8539 : () => publicThis[source]
8540 : source.bind(publicThis, publicThis);
8541 let cb;
8542 if (isFunction(value)) {
8543 cb = value;
8544 }
8545 else {
8546 cb = value.handler;
8547 options = value;
8548 }
8549 const cur = currentInstance;
8550 setCurrentInstance(this);
8551 const res = doWatch(getter, cb.bind(publicThis), options);
8552 if (cur) {
8553 setCurrentInstance(cur);
8554 }
8555 else {
8556 unsetCurrentInstance();
8557 }
8558 return res;
8559}
8560function createPathGetter(ctx, path) {
8561 const segments = path.split('.');
8562 return () => {
8563 let cur = ctx;
8564 for (let i = 0; i < segments.length && cur; i++) {
8565 cur = cur[segments[i]];
8566 }
8567 return cur;
8568 };
8569}
8570function traverse(value, seen) {
8571 if (!isObject(value) || value["__v_skip" /* SKIP */]) {
8572 return value;
8573 }
8574 seen = seen || new Set();
8575 if (seen.has(value)) {
8576 return value;
8577 }
8578 seen.add(value);
8579 if (isRef(value)) {
8580 traverse(value.value, seen);
8581 }
8582 else if (isArray(value)) {
8583 for (let i = 0; i < value.length; i++) {
8584 traverse(value[i], seen);
8585 }
8586 }
8587 else if (isSet(value) || isMap(value)) {
8588 value.forEach((v) => {
8589 traverse(v, seen);
8590 });
8591 }
8592 else if (isPlainObject(value)) {
8593 for (const key in value) {
8594 traverse(value[key], seen);
8595 }
8596 }
8597 return value;
8598}
8599
8600// dev only
8601const warnRuntimeUsage = (method) => warn$1(`${method}() is a compiler-hint helper that is only usable inside ` +
8602 `<script setup> of a single file component. Its arguments should be ` +
8603 `compiled away and passing it at runtime has no effect.`);
8604// implementation
8605function defineProps() {
8606 {
8607 warnRuntimeUsage(`defineProps`);
8608 }
8609 return null;
8610}
8611// implementation
8612function defineEmits() {
8613 {
8614 warnRuntimeUsage(`defineEmits`);
8615 }
8616 return null;
8617}
8618/**
8619 * Vue `<script setup>` compiler macro for declaring a component's exposed
8620 * instance properties when it is accessed by a parent component via template
8621 * refs.
8622 *
8623 * `<script setup>` components are closed by default - i.e. varaibles inside
8624 * the `<script setup>` scope is not exposed to parent unless explicitly exposed
8625 * via `defineExpose`.
8626 *
8627 * This is only usable inside `<script setup>`, is compiled away in the
8628 * output and should **not** be actually called at runtime.
8629 */
8630function defineExpose(exposed) {
8631 {
8632 warnRuntimeUsage(`defineExpose`);
8633 }
8634}
8635/**
8636 * Vue `<script setup>` compiler macro for providing props default values when
8637 * using type-based `defineProps` declaration.
8638 *
8639 * Example usage:
8640 * ```ts
8641 * withDefaults(defineProps<{
8642 * size?: number
8643 * labels?: string[]
8644 * }>(), {
8645 * size: 3,
8646 * labels: () => ['default label']
8647 * })
8648 * ```
8649 *
8650 * This is only usable inside `<script setup>`, is compiled away in the output
8651 * and should **not** be actually called at runtime.
8652 */
8653function withDefaults(props, defaults) {
8654 {
8655 warnRuntimeUsage(`withDefaults`);
8656 }
8657 return null;
8658}
8659function useSlots() {
8660 return getContext().slots;
8661}
8662function useAttrs() {
8663 return getContext().attrs;
8664}
8665function getContext() {
8666 const i = getCurrentInstance();
8667 if (!i) {
8668 warn$1(`useContext() called without active instance.`);
8669 }
8670 return i.setupContext || (i.setupContext = createSetupContext(i));
8671}
8672/**
8673 * Runtime helper for merging default declarations. Imported by compiled code
8674 * only.
8675 * @internal
8676 */
8677function mergeDefaults(
8678// the base props is compiler-generated and guaranteed to be in this shape.
8679props, defaults) {
8680 for (const key in defaults) {
8681 const val = props[key];
8682 if (val) {
8683 val.default = defaults[key];
8684 }
8685 else if (val === null) {
8686 props[key] = { default: defaults[key] };
8687 }
8688 else {
8689 warn$1(`props default key "${key}" has no corresponding declaration.`);
8690 }
8691 }
8692 return props;
8693}
8694/**
8695 * `<script setup>` helper for persisting the current instance context over
8696 * async/await flows.
8697 *
8698 * `@vue/compiler-sfc` converts the following:
8699 *
8700 * ```ts
8701 * const x = await foo()
8702 * ```
8703 *
8704 * into:
8705 *
8706 * ```ts
8707 * let __temp, __restore
8708 * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
8709 * ```
8710 * @internal
8711 */
8712function withAsyncContext(getAwaitable) {
8713 const ctx = getCurrentInstance();
8714 if (!ctx) {
8715 warn$1(`withAsyncContext called without active current instance. ` +
8716 `This is likely a bug.`);
8717 }
8718 let awaitable = getAwaitable();
8719 unsetCurrentInstance();
8720 if (isPromise(awaitable)) {
8721 awaitable = awaitable.catch(e => {
8722 setCurrentInstance(ctx);
8723 throw e;
8724 });
8725 }
8726 return [awaitable, () => setCurrentInstance(ctx)];
8727}
8728
8729// Actual implementation
8730function h(type, propsOrChildren, children) {
8731 const l = arguments.length;
8732 if (l === 2) {
8733 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
8734 // single vnode without props
8735 if (isVNode(propsOrChildren)) {
8736 return createVNode(type, null, [propsOrChildren]);
8737 }
8738 // props without children
8739 return createVNode(type, propsOrChildren);
8740 }
8741 else {
8742 // omit props
8743 return createVNode(type, null, propsOrChildren);
8744 }
8745 }
8746 else {
8747 if (l > 3) {
8748 children = Array.prototype.slice.call(arguments, 2);
8749 }
8750 else if (l === 3 && isVNode(children)) {
8751 children = [children];
8752 }
8753 return createVNode(type, propsOrChildren, children);
8754 }
8755}
8756
8757const ssrContextKey = Symbol(`ssrContext` );
8758const useSSRContext = () => {
8759 {
8760 const ctx = inject(ssrContextKey);
8761 if (!ctx) {
8762 warn$1(`Server rendering context not provided. Make sure to only call ` +
8763 `useSSRContext() conditionally in the server build.`);
8764 }
8765 return ctx;
8766 }
8767};
8768
8769function initCustomFormatter() {
8770 /* eslint-disable no-restricted-globals */
8771 if (typeof window === 'undefined') {
8772 return;
8773 }
8774 const vueStyle = { style: 'color:#3ba776' };
8775 const numberStyle = { style: 'color:#0b1bc9' };
8776 const stringStyle = { style: 'color:#b62e24' };
8777 const keywordStyle = { style: 'color:#9d288c' };
8778 // custom formatter for Chrome
8779 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
8780 const formatter = {
8781 header(obj) {
8782 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
8783 if (!isObject(obj)) {
8784 return null;
8785 }
8786 if (obj.__isVue) {
8787 return ['div', vueStyle, `VueInstance`];
8788 }
8789 else if (isRef(obj)) {
8790 return [
8791 'div',
8792 {},
8793 ['span', vueStyle, genRefFlag(obj)],
8794 '<',
8795 formatValue(obj.value),
8796 `>`
8797 ];
8798 }
8799 else if (isReactive(obj)) {
8800 return [
8801 'div',
8802 {},
8803 ['span', vueStyle, 'Reactive'],
8804 '<',
8805 formatValue(obj),
8806 `>${isReadonly(obj) ? ` (readonly)` : ``}`
8807 ];
8808 }
8809 else if (isReadonly(obj)) {
8810 return [
8811 'div',
8812 {},
8813 ['span', vueStyle, 'Readonly'],
8814 '<',
8815 formatValue(obj),
8816 '>'
8817 ];
8818 }
8819 return null;
8820 },
8821 hasBody(obj) {
8822 return obj && obj.__isVue;
8823 },
8824 body(obj) {
8825 if (obj && obj.__isVue) {
8826 return [
8827 'div',
8828 {},
8829 ...formatInstance(obj.$)
8830 ];
8831 }
8832 }
8833 };
8834 function formatInstance(instance) {
8835 const blocks = [];
8836 if (instance.type.props && instance.props) {
8837 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
8838 }
8839 if (instance.setupState !== EMPTY_OBJ) {
8840 blocks.push(createInstanceBlock('setup', instance.setupState));
8841 }
8842 if (instance.data !== EMPTY_OBJ) {
8843 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
8844 }
8845 const computed = extractKeys(instance, 'computed');
8846 if (computed) {
8847 blocks.push(createInstanceBlock('computed', computed));
8848 }
8849 const injected = extractKeys(instance, 'inject');
8850 if (injected) {
8851 blocks.push(createInstanceBlock('injected', injected));
8852 }
8853 blocks.push([
8854 'div',
8855 {},
8856 [
8857 'span',
8858 {
8859 style: keywordStyle.style + ';opacity:0.66'
8860 },
8861 '$ (internal): '
8862 ],
8863 ['object', { object: instance }]
8864 ]);
8865 return blocks;
8866 }
8867 function createInstanceBlock(type, target) {
8868 target = extend({}, target);
8869 if (!Object.keys(target).length) {
8870 return ['span', {}];
8871 }
8872 return [
8873 'div',
8874 { style: 'line-height:1.25em;margin-bottom:0.6em' },
8875 [
8876 'div',
8877 {
8878 style: 'color:#476582'
8879 },
8880 type
8881 ],
8882 [
8883 'div',
8884 {
8885 style: 'padding-left:1.25em'
8886 },
8887 ...Object.keys(target).map(key => {
8888 return [
8889 'div',
8890 {},
8891 ['span', keywordStyle, key + ': '],
8892 formatValue(target[key], false)
8893 ];
8894 })
8895 ]
8896 ];
8897 }
8898 function formatValue(v, asRaw = true) {
8899 if (typeof v === 'number') {
8900 return ['span', numberStyle, v];
8901 }
8902 else if (typeof v === 'string') {
8903 return ['span', stringStyle, JSON.stringify(v)];
8904 }
8905 else if (typeof v === 'boolean') {
8906 return ['span', keywordStyle, v];
8907 }
8908 else if (isObject(v)) {
8909 return ['object', { object: asRaw ? toRaw(v) : v }];
8910 }
8911 else {
8912 return ['span', stringStyle, String(v)];
8913 }
8914 }
8915 function extractKeys(instance, type) {
8916 const Comp = instance.type;
8917 if (isFunction(Comp)) {
8918 return;
8919 }
8920 const extracted = {};
8921 for (const key in instance.ctx) {
8922 if (isKeyOfType(Comp, key, type)) {
8923 extracted[key] = instance.ctx[key];
8924 }
8925 }
8926 return extracted;
8927 }
8928 function isKeyOfType(Comp, key, type) {
8929 const opts = Comp[type];
8930 if ((isArray(opts) && opts.includes(key)) ||
8931 (isObject(opts) && key in opts)) {
8932 return true;
8933 }
8934 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
8935 return true;
8936 }
8937 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
8938 return true;
8939 }
8940 }
8941 function genRefFlag(v) {
8942 if (v._shallow) {
8943 return `ShallowRef`;
8944 }
8945 if (v.effect) {
8946 return `ComputedRef`;
8947 }
8948 return `Ref`;
8949 }
8950 if (window.devtoolsFormatters) {
8951 window.devtoolsFormatters.push(formatter);
8952 }
8953 else {
8954 window.devtoolsFormatters = [formatter];
8955 }
8956}
8957
8958function withMemo(memo, render, cache, index) {
8959 const cached = cache[index];
8960 if (cached && isMemoSame(cached, memo)) {
8961 return cached;
8962 }
8963 const ret = render();
8964 // shallow clone
8965 ret.memo = memo.slice();
8966 return (cache[index] = ret);
8967}
8968function isMemoSame(cached, memo) {
8969 const prev = cached.memo;
8970 if (prev.length != memo.length) {
8971 return false;
8972 }
8973 for (let i = 0; i < prev.length; i++) {
8974 if (prev[i] !== memo[i]) {
8975 return false;
8976 }
8977 }
8978 // make sure to let parent block track it when returning cached
8979 if (isBlockTreeEnabled > 0 && currentBlock) {
8980 currentBlock.push(cached);
8981 }
8982 return true;
8983}
8984
8985// Core API ------------------------------------------------------------------
8986const version = "3.2.19";
8987/**
8988 * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
8989 * @internal
8990 */
8991const ssrUtils = (null);
8992/**
8993 * @internal only exposed in compat builds
8994 */
8995const resolveFilter = null;
8996/**
8997 * @internal only exposed in compat builds.
8998 */
8999const compatUtils = (null);
9000
9001const svgNS = 'http://www.w3.org/2000/svg';
9002const doc = (typeof document !== 'undefined' ? document : null);
9003const staticTemplateCache = new Map();
9004const nodeOps = {
9005 insert: (child, parent, anchor) => {
9006 parent.insertBefore(child, anchor || null);
9007 },
9008 remove: child => {
9009 const parent = child.parentNode;
9010 if (parent) {
9011 parent.removeChild(child);
9012 }
9013 },
9014 createElement: (tag, isSVG, is, props) => {
9015 const el = isSVG
9016 ? doc.createElementNS(svgNS, tag)
9017 : doc.createElement(tag, is ? { is } : undefined);
9018 if (tag === 'select' && props && props.multiple != null) {
9019 el.setAttribute('multiple', props.multiple);
9020 }
9021 return el;
9022 },
9023 createText: text => doc.createTextNode(text),
9024 createComment: text => doc.createComment(text),
9025 setText: (node, text) => {
9026 node.nodeValue = text;
9027 },
9028 setElementText: (el, text) => {
9029 el.textContent = text;
9030 },
9031 parentNode: node => node.parentNode,
9032 nextSibling: node => node.nextSibling,
9033 querySelector: selector => doc.querySelector(selector),
9034 setScopeId(el, id) {
9035 el.setAttribute(id, '');
9036 },
9037 cloneNode(el) {
9038 const cloned = el.cloneNode(true);
9039 // #3072
9040 // - in `patchDOMProp`, we store the actual value in the `el._value` property.
9041 // - normally, elements using `:value` bindings will not be hoisted, but if
9042 // the bound value is a constant, e.g. `:value="true"` - they do get
9043 // hoisted.
9044 // - in production, hoisted nodes are cloned when subsequent inserts, but
9045 // cloneNode() does not copy the custom property we attached.
9046 // - This may need to account for other custom DOM properties we attach to
9047 // elements in addition to `_value` in the future.
9048 if (`_value` in el) {
9049 cloned._value = el._value;
9050 }
9051 return cloned;
9052 },
9053 // __UNSAFE__
9054 // Reason: innerHTML.
9055 // Static content here can only come from compiled templates.
9056 // As long as the user only uses trusted templates, this is safe.
9057 insertStaticContent(content, parent, anchor, isSVG) {
9058 // <parent> before | first ... last | anchor </parent>
9059 const before = anchor ? anchor.previousSibling : parent.lastChild;
9060 let template = staticTemplateCache.get(content);
9061 if (!template) {
9062 const t = doc.createElement('template');
9063 t.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
9064 template = t.content;
9065 if (isSVG) {
9066 // remove outer svg wrapper
9067 const wrapper = template.firstChild;
9068 while (wrapper.firstChild) {
9069 template.appendChild(wrapper.firstChild);
9070 }
9071 template.removeChild(wrapper);
9072 }
9073 staticTemplateCache.set(content, template);
9074 }
9075 parent.insertBefore(template.cloneNode(true), anchor);
9076 return [
9077 // first
9078 before ? before.nextSibling : parent.firstChild,
9079 // last
9080 anchor ? anchor.previousSibling : parent.lastChild
9081 ];
9082 }
9083};
9084
9085// compiler should normalize class + :class bindings on the same element
9086// into a single binding ['staticClass', dynamic]
9087function patchClass(el, value, isSVG) {
9088 // directly setting className should be faster than setAttribute in theory
9089 // if this is an element during a transition, take the temporary transition
9090 // classes into account.
9091 const transitionClasses = el._vtc;
9092 if (transitionClasses) {
9093 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
9094 }
9095 if (value == null) {
9096 el.removeAttribute('class');
9097 }
9098 else if (isSVG) {
9099 el.setAttribute('class', value);
9100 }
9101 else {
9102 el.className = value;
9103 }
9104}
9105
9106function patchStyle(el, prev, next) {
9107 const style = el.style;
9108 const currentDisplay = style.display;
9109 if (!next) {
9110 el.removeAttribute('style');
9111 }
9112 else if (isString(next)) {
9113 if (prev !== next) {
9114 style.cssText = next;
9115 }
9116 }
9117 else {
9118 for (const key in next) {
9119 setStyle(style, key, next[key]);
9120 }
9121 if (prev && !isString(prev)) {
9122 for (const key in prev) {
9123 if (next[key] == null) {
9124 setStyle(style, key, '');
9125 }
9126 }
9127 }
9128 }
9129 // indicates that the `display` of the element is controlled by `v-show`,
9130 // so we always keep the current `display` value regardless of the `style` value,
9131 // thus handing over control to `v-show`.
9132 if ('_vod' in el) {
9133 style.display = currentDisplay;
9134 }
9135}
9136const importantRE = /\s*!important$/;
9137function setStyle(style, name, val) {
9138 if (isArray(val)) {
9139 val.forEach(v => setStyle(style, name, v));
9140 }
9141 else {
9142 if (name.startsWith('--')) {
9143 // custom property definition
9144 style.setProperty(name, val);
9145 }
9146 else {
9147 const prefixed = autoPrefix(style, name);
9148 if (importantRE.test(val)) {
9149 // !important
9150 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
9151 }
9152 else {
9153 style[prefixed] = val;
9154 }
9155 }
9156 }
9157}
9158const prefixes = ['Webkit', 'Moz', 'ms'];
9159const prefixCache = {};
9160function autoPrefix(style, rawName) {
9161 const cached = prefixCache[rawName];
9162 if (cached) {
9163 return cached;
9164 }
9165 let name = camelize(rawName);
9166 if (name !== 'filter' && name in style) {
9167 return (prefixCache[rawName] = name);
9168 }
9169 name = capitalize(name);
9170 for (let i = 0; i < prefixes.length; i++) {
9171 const prefixed = prefixes[i] + name;
9172 if (prefixed in style) {
9173 return (prefixCache[rawName] = prefixed);
9174 }
9175 }
9176 return rawName;
9177}
9178
9179const xlinkNS = 'http://www.w3.org/1999/xlink';
9180function patchAttr(el, key, value, isSVG, instance) {
9181 if (isSVG && key.startsWith('xlink:')) {
9182 if (value == null) {
9183 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
9184 }
9185 else {
9186 el.setAttributeNS(xlinkNS, key, value);
9187 }
9188 }
9189 else {
9190 // note we are only checking boolean attributes that don't have a
9191 // corresponding dom prop of the same name here.
9192 const isBoolean = isSpecialBooleanAttr(key);
9193 if (value == null || (isBoolean && !includeBooleanAttr(value))) {
9194 el.removeAttribute(key);
9195 }
9196 else {
9197 el.setAttribute(key, isBoolean ? '' : value);
9198 }
9199 }
9200}
9201
9202// __UNSAFE__
9203// functions. The user is responsible for using them with only trusted content.
9204function patchDOMProp(el, key, value,
9205// the following args are passed only due to potential innerHTML/textContent
9206// overriding existing VNodes, in which case the old tree must be properly
9207// unmounted.
9208prevChildren, parentComponent, parentSuspense, unmountChildren) {
9209 if (key === 'innerHTML' || key === 'textContent') {
9210 if (prevChildren) {
9211 unmountChildren(prevChildren, parentComponent, parentSuspense);
9212 }
9213 el[key] = value == null ? '' : value;
9214 return;
9215 }
9216 if (key === 'value' && el.tagName !== 'PROGRESS') {
9217 // store value as _value as well since
9218 // non-string values will be stringified.
9219 el._value = value;
9220 const newValue = value == null ? '' : value;
9221 if (el.value !== newValue) {
9222 el.value = newValue;
9223 }
9224 if (value == null) {
9225 el.removeAttribute(key);
9226 }
9227 return;
9228 }
9229 if (value === '' || value == null) {
9230 const type = typeof el[key];
9231 if (type === 'boolean') {
9232 // e.g. <select multiple> compiles to { multiple: '' }
9233 el[key] = includeBooleanAttr(value);
9234 return;
9235 }
9236 else if (value == null && type === 'string') {
9237 // e.g. <div :id="null">
9238 el[key] = '';
9239 el.removeAttribute(key);
9240 return;
9241 }
9242 else if (type === 'number') {
9243 // e.g. <img :width="null">
9244 // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
9245 try {
9246 el[key] = 0;
9247 }
9248 catch (_a) { }
9249 el.removeAttribute(key);
9250 return;
9251 }
9252 }
9253 // some properties perform value validation and throw
9254 try {
9255 el[key] = value;
9256 }
9257 catch (e) {
9258 {
9259 warn$1(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9260 `value ${value} is invalid.`, e);
9261 }
9262 }
9263}
9264
9265// Async edge case fix requires storing an event listener's attach timestamp.
9266let _getNow = Date.now;
9267let skipTimestampCheck = false;
9268if (typeof window !== 'undefined') {
9269 // Determine what event timestamp the browser is using. Annoyingly, the
9270 // timestamp can either be hi-res (relative to page load) or low-res
9271 // (relative to UNIX epoch), so in order to compare time we have to use the
9272 // same timestamp type when saving the flush timestamp.
9273 if (_getNow() > document.createEvent('Event').timeStamp) {
9274 // if the low-res timestamp which is bigger than the event timestamp
9275 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
9276 // and we need to use the hi-res version for event listeners as well.
9277 _getNow = () => performance.now();
9278 }
9279 // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
9280 // and does not fire microtasks in between event propagation, so safe to exclude.
9281 const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
9282 skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
9283}
9284// To avoid the overhead of repeatedly calling performance.now(), we cache
9285// and use the same timestamp for all event listeners attached in the same tick.
9286let cachedNow = 0;
9287const p = Promise.resolve();
9288const reset = () => {
9289 cachedNow = 0;
9290};
9291const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
9292function addEventListener(el, event, handler, options) {
9293 el.addEventListener(event, handler, options);
9294}
9295function removeEventListener(el, event, handler, options) {
9296 el.removeEventListener(event, handler, options);
9297}
9298function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9299 // vei = vue event invokers
9300 const invokers = el._vei || (el._vei = {});
9301 const existingInvoker = invokers[rawName];
9302 if (nextValue && existingInvoker) {
9303 // patch
9304 existingInvoker.value = nextValue;
9305 }
9306 else {
9307 const [name, options] = parseName(rawName);
9308 if (nextValue) {
9309 // add
9310 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9311 addEventListener(el, name, invoker, options);
9312 }
9313 else if (existingInvoker) {
9314 // remove
9315 removeEventListener(el, name, existingInvoker, options);
9316 invokers[rawName] = undefined;
9317 }
9318 }
9319}
9320const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9321function parseName(name) {
9322 let options;
9323 if (optionsModifierRE.test(name)) {
9324 options = {};
9325 let m;
9326 while ((m = name.match(optionsModifierRE))) {
9327 name = name.slice(0, name.length - m[0].length);
9328 options[m[0].toLowerCase()] = true;
9329 }
9330 }
9331 return [hyphenate(name.slice(2)), options];
9332}
9333function createInvoker(initialValue, instance) {
9334 const invoker = (e) => {
9335 // async edge case #6566: inner click event triggers patch, event handler
9336 // attached to outer element during patch, and triggered again. This
9337 // happens because browsers fire microtask ticks between event propagation.
9338 // the solution is simple: we save the timestamp when a handler is attached,
9339 // and the handler would only fire if the event passed to it was fired
9340 // AFTER it was attached.
9341 const timeStamp = e.timeStamp || _getNow();
9342 if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
9343 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
9344 }
9345 };
9346 invoker.value = initialValue;
9347 invoker.attached = getNow();
9348 return invoker;
9349}
9350function patchStopImmediatePropagation(e, value) {
9351 if (isArray(value)) {
9352 const originalStop = e.stopImmediatePropagation;
9353 e.stopImmediatePropagation = () => {
9354 originalStop.call(e);
9355 e._stopped = true;
9356 };
9357 return value.map(fn => (e) => !e._stopped && fn(e));
9358 }
9359 else {
9360 return value;
9361 }
9362}
9363
9364const nativeOnRE = /^on[a-z]/;
9365const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9366 if (key === 'class') {
9367 patchClass(el, nextValue, isSVG);
9368 }
9369 else if (key === 'style') {
9370 patchStyle(el, prevValue, nextValue);
9371 }
9372 else if (isOn(key)) {
9373 // ignore v-model listeners
9374 if (!isModelListener(key)) {
9375 patchEvent(el, key, prevValue, nextValue, parentComponent);
9376 }
9377 }
9378 else if (key[0] === '.'
9379 ? ((key = key.slice(1)), true)
9380 : key[0] === '^'
9381 ? ((key = key.slice(1)), false)
9382 : shouldSetAsProp(el, key, nextValue, isSVG)) {
9383 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9384 }
9385 else {
9386 // special case for <input v-model type="checkbox"> with
9387 // :true-value & :false-value
9388 // store value as dom properties since non-string values will be
9389 // stringified.
9390 if (key === 'true-value') {
9391 el._trueValue = nextValue;
9392 }
9393 else if (key === 'false-value') {
9394 el._falseValue = nextValue;
9395 }
9396 patchAttr(el, key, nextValue, isSVG);
9397 }
9398};
9399function shouldSetAsProp(el, key, value, isSVG) {
9400 if (isSVG) {
9401 // most keys must be set as attribute on svg elements to work
9402 // ...except innerHTML & textContent
9403 if (key === 'innerHTML' || key === 'textContent') {
9404 return true;
9405 }
9406 // or native onclick with function values
9407 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9408 return true;
9409 }
9410 return false;
9411 }
9412 // spellcheck and draggable are numerated attrs, however their
9413 // corresponding DOM properties are actually booleans - this leads to
9414 // setting it with a string "false" value leading it to be coerced to
9415 // `true`, so we need to always treat them as attributes.
9416 // Note that `contentEditable` doesn't have this problem: its DOM
9417 // property is also enumerated string values.
9418 if (key === 'spellcheck' || key === 'draggable') {
9419 return false;
9420 }
9421 // #1787, #2840 form property on form elements is readonly and must be set as
9422 // attribute.
9423 if (key === 'form') {
9424 return false;
9425 }
9426 // #1526 <input list> must be set as attribute
9427 if (key === 'list' && el.tagName === 'INPUT') {
9428 return false;
9429 }
9430 // #2766 <textarea type> must be set as attribute
9431 if (key === 'type' && el.tagName === 'TEXTAREA') {
9432 return false;
9433 }
9434 // native onclick with string value, must be set as attribute
9435 if (nativeOnRE.test(key) && isString(value)) {
9436 return false;
9437 }
9438 return key in el;
9439}
9440
9441function defineCustomElement(options, hydate) {
9442 const Comp = defineComponent(options);
9443 class VueCustomElement extends VueElement {
9444 constructor(initialProps) {
9445 super(Comp, initialProps, hydate);
9446 }
9447 }
9448 VueCustomElement.def = Comp;
9449 return VueCustomElement;
9450}
9451const defineSSRCustomElement = ((options) => {
9452 // @ts-ignore
9453 return defineCustomElement(options, hydrate);
9454});
9455const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
9456});
9457class VueElement extends BaseClass {
9458 constructor(_def, _props = {}, hydrate) {
9459 super();
9460 this._def = _def;
9461 this._props = _props;
9462 /**
9463 * @internal
9464 */
9465 this._instance = null;
9466 this._connected = false;
9467 this._resolved = false;
9468 this._numberProps = null;
9469 if (this.shadowRoot && hydrate) {
9470 hydrate(this._createVNode(), this.shadowRoot);
9471 }
9472 else {
9473 if (this.shadowRoot) {
9474 warn$1(`Custom element has pre-rendered declarative shadow root but is not ` +
9475 `defined as hydratable. Use \`defineSSRCustomElement\`.`);
9476 }
9477 this.attachShadow({ mode: 'open' });
9478 }
9479 // set initial attrs
9480 for (let i = 0; i < this.attributes.length; i++) {
9481 this._setAttr(this.attributes[i].name);
9482 }
9483 // watch future attr changes
9484 new MutationObserver(mutations => {
9485 for (const m of mutations) {
9486 this._setAttr(m.attributeName);
9487 }
9488 }).observe(this, { attributes: true });
9489 }
9490 connectedCallback() {
9491 this._connected = true;
9492 if (!this._instance) {
9493 this._resolveDef();
9494 this._update();
9495 }
9496 }
9497 disconnectedCallback() {
9498 this._connected = false;
9499 nextTick(() => {
9500 if (!this._connected) {
9501 render(null, this.shadowRoot);
9502 this._instance = null;
9503 }
9504 });
9505 }
9506 /**
9507 * resolve inner component definition (handle possible async component)
9508 */
9509 _resolveDef() {
9510 if (this._resolved) {
9511 return;
9512 }
9513 const resolve = (def) => {
9514 this._resolved = true;
9515 const { props, styles } = def;
9516 const hasOptions = !isArray(props);
9517 const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : [];
9518 // cast Number-type props set before resolve
9519 let numberProps;
9520 if (hasOptions) {
9521 for (const key in this._props) {
9522 const opt = props[key];
9523 if (opt === Number || (opt && opt.type === Number)) {
9524 this._props[key] = toNumber(this._props[key]);
9525 (numberProps || (numberProps = Object.create(null)))[key] = true;
9526 }
9527 }
9528 }
9529 if (numberProps) {
9530 this._numberProps = numberProps;
9531 this._update();
9532 }
9533 // check if there are props set pre-upgrade or connect
9534 for (const key of Object.keys(this)) {
9535 if (key[0] !== '_') {
9536 this._setProp(key, this[key]);
9537 }
9538 }
9539 // defining getter/setters on prototype
9540 for (const key of rawKeys.map(camelize)) {
9541 Object.defineProperty(this, key, {
9542 get() {
9543 return this._getProp(key);
9544 },
9545 set(val) {
9546 this._setProp(key, val);
9547 }
9548 });
9549 }
9550 this._applyStyles(styles);
9551 };
9552 const asyncDef = this._def.__asyncLoader;
9553 if (asyncDef) {
9554 asyncDef().then(resolve);
9555 }
9556 else {
9557 resolve(this._def);
9558 }
9559 }
9560 _setAttr(key) {
9561 let value = this.getAttribute(key);
9562 if (this._numberProps && this._numberProps[key]) {
9563 value = toNumber(value);
9564 }
9565 this._setProp(camelize(key), value, false);
9566 }
9567 /**
9568 * @internal
9569 */
9570 _getProp(key) {
9571 return this._props[key];
9572 }
9573 /**
9574 * @internal
9575 */
9576 _setProp(key, val, shouldReflect = true) {
9577 if (val !== this._props[key]) {
9578 this._props[key] = val;
9579 if (this._instance) {
9580 this._update();
9581 }
9582 // reflect
9583 if (shouldReflect) {
9584 if (val === true) {
9585 this.setAttribute(hyphenate(key), '');
9586 }
9587 else if (typeof val === 'string' || typeof val === 'number') {
9588 this.setAttribute(hyphenate(key), val + '');
9589 }
9590 else if (!val) {
9591 this.removeAttribute(hyphenate(key));
9592 }
9593 }
9594 }
9595 }
9596 _update() {
9597 render(this._createVNode(), this.shadowRoot);
9598 }
9599 _createVNode() {
9600 const vnode = createVNode(this._def, extend({}, this._props));
9601 if (!this._instance) {
9602 vnode.ce = instance => {
9603 this._instance = instance;
9604 instance.isCE = true;
9605 // HMR
9606 {
9607 instance.ceReload = newStyles => {
9608 // alawys reset styles
9609 if (this._styles) {
9610 this._styles.forEach(s => this.shadowRoot.removeChild(s));
9611 this._styles.length = 0;
9612 }
9613 this._applyStyles(newStyles);
9614 // if this is an async component, ceReload is called from the inner
9615 // component so no need to reload the async wrapper
9616 if (!this._def.__asyncLoader) {
9617 // reload
9618 this._instance = null;
9619 this._update();
9620 }
9621 };
9622 }
9623 // intercept emit
9624 instance.emit = (event, ...args) => {
9625 this.dispatchEvent(new CustomEvent(event, {
9626 detail: args
9627 }));
9628 };
9629 // locate nearest Vue custom element parent for provide/inject
9630 let parent = this;
9631 while ((parent =
9632 parent && (parent.parentNode || parent.host))) {
9633 if (parent instanceof VueElement) {
9634 instance.parent = parent._instance;
9635 break;
9636 }
9637 }
9638 };
9639 }
9640 return vnode;
9641 }
9642 _applyStyles(styles) {
9643 if (styles) {
9644 styles.forEach(css => {
9645 const s = document.createElement('style');
9646 s.textContent = css;
9647 this.shadowRoot.appendChild(s);
9648 // record for HMR
9649 {
9650 (this._styles || (this._styles = [])).push(s);
9651 }
9652 });
9653 }
9654 }
9655}
9656
9657function useCssModule(name = '$style') {
9658 /* istanbul ignore else */
9659 {
9660 const instance = getCurrentInstance();
9661 if (!instance) {
9662 warn$1(`useCssModule must be called inside setup()`);
9663 return EMPTY_OBJ;
9664 }
9665 const modules = instance.type.__cssModules;
9666 if (!modules) {
9667 warn$1(`Current instance does not have CSS modules injected.`);
9668 return EMPTY_OBJ;
9669 }
9670 const mod = modules[name];
9671 if (!mod) {
9672 warn$1(`Current instance does not have CSS module named "${name}".`);
9673 return EMPTY_OBJ;
9674 }
9675 return mod;
9676 }
9677}
9678
9679/**
9680 * Runtime helper for SFC's CSS variable injection feature.
9681 * @private
9682 */
9683function useCssVars(getter) {
9684 const instance = getCurrentInstance();
9685 /* istanbul ignore next */
9686 if (!instance) {
9687 warn$1(`useCssVars is called without current active component instance.`);
9688 return;
9689 }
9690 const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
9691 watchPostEffect(setVars);
9692 onMounted(() => {
9693 const ob = new MutationObserver(setVars);
9694 ob.observe(instance.subTree.el.parentNode, { childList: true });
9695 onUnmounted(() => ob.disconnect());
9696 });
9697}
9698function setVarsOnVNode(vnode, vars) {
9699 if (vnode.shapeFlag & 128 /* SUSPENSE */) {
9700 const suspense = vnode.suspense;
9701 vnode = suspense.activeBranch;
9702 if (suspense.pendingBranch && !suspense.isHydrating) {
9703 suspense.effects.push(() => {
9704 setVarsOnVNode(suspense.activeBranch, vars);
9705 });
9706 }
9707 }
9708 // drill down HOCs until it's a non-component vnode
9709 while (vnode.component) {
9710 vnode = vnode.component.subTree;
9711 }
9712 if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
9713 setVarsOnNode(vnode.el, vars);
9714 }
9715 else if (vnode.type === Fragment) {
9716 vnode.children.forEach(c => setVarsOnVNode(c, vars));
9717 }
9718 else if (vnode.type === Static) {
9719 let { el, anchor } = vnode;
9720 while (el) {
9721 setVarsOnNode(el, vars);
9722 if (el === anchor)
9723 break;
9724 el = el.nextSibling;
9725 }
9726 }
9727}
9728function setVarsOnNode(el, vars) {
9729 if (el.nodeType === 1) {
9730 const style = el.style;
9731 for (const key in vars) {
9732 style.setProperty(`--${key}`, vars[key]);
9733 }
9734 }
9735}
9736
9737const TRANSITION = 'transition';
9738const ANIMATION = 'animation';
9739// DOM Transition is a higher-order-component based on the platform-agnostic
9740// base Transition component, with DOM-specific logic.
9741const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
9742Transition.displayName = 'Transition';
9743const DOMTransitionPropsValidators = {
9744 name: String,
9745 type: String,
9746 css: {
9747 type: Boolean,
9748 default: true
9749 },
9750 duration: [String, Number, Object],
9751 enterFromClass: String,
9752 enterActiveClass: String,
9753 enterToClass: String,
9754 appearFromClass: String,
9755 appearActiveClass: String,
9756 appearToClass: String,
9757 leaveFromClass: String,
9758 leaveActiveClass: String,
9759 leaveToClass: String
9760};
9761const TransitionPropsValidators = (Transition.props =
9762 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
9763/**
9764 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
9765 * with custom HOCs.
9766 */
9767const callHook$1 = (hook, args = []) => {
9768 if (isArray(hook)) {
9769 hook.forEach(h => h(...args));
9770 }
9771 else if (hook) {
9772 hook(...args);
9773 }
9774};
9775/**
9776 * Check if a hook expects a callback (2nd arg), which means the user
9777 * intends to explicitly control the end of the transition.
9778 */
9779const hasExplicitCallback = (hook) => {
9780 return hook
9781 ? isArray(hook)
9782 ? hook.some(h => h.length > 1)
9783 : hook.length > 1
9784 : false;
9785};
9786function resolveTransitionProps(rawProps) {
9787 const baseProps = {};
9788 for (const key in rawProps) {
9789 if (!(key in DOMTransitionPropsValidators)) {
9790 baseProps[key] = rawProps[key];
9791 }
9792 }
9793 if (rawProps.css === false) {
9794 return baseProps;
9795 }
9796 const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
9797 const durations = normalizeDuration(duration);
9798 const enterDuration = durations && durations[0];
9799 const leaveDuration = durations && durations[1];
9800 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
9801 const finishEnter = (el, isAppear, done) => {
9802 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
9803 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
9804 done && done();
9805 };
9806 const finishLeave = (el, done) => {
9807 removeTransitionClass(el, leaveToClass);
9808 removeTransitionClass(el, leaveActiveClass);
9809 done && done();
9810 };
9811 const makeEnterHook = (isAppear) => {
9812 return (el, done) => {
9813 const hook = isAppear ? onAppear : onEnter;
9814 const resolve = () => finishEnter(el, isAppear, done);
9815 callHook$1(hook, [el, resolve]);
9816 nextFrame(() => {
9817 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
9818 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
9819 if (!hasExplicitCallback(hook)) {
9820 whenTransitionEnds(el, type, enterDuration, resolve);
9821 }
9822 });
9823 };
9824 };
9825 return extend(baseProps, {
9826 onBeforeEnter(el) {
9827 callHook$1(onBeforeEnter, [el]);
9828 addTransitionClass(el, enterFromClass);
9829 addTransitionClass(el, enterActiveClass);
9830 },
9831 onBeforeAppear(el) {
9832 callHook$1(onBeforeAppear, [el]);
9833 addTransitionClass(el, appearFromClass);
9834 addTransitionClass(el, appearActiveClass);
9835 },
9836 onEnter: makeEnterHook(false),
9837 onAppear: makeEnterHook(true),
9838 onLeave(el, done) {
9839 const resolve = () => finishLeave(el, done);
9840 addTransitionClass(el, leaveFromClass);
9841 // force reflow so *-leave-from classes immediately take effect (#2593)
9842 forceReflow();
9843 addTransitionClass(el, leaveActiveClass);
9844 nextFrame(() => {
9845 removeTransitionClass(el, leaveFromClass);
9846 addTransitionClass(el, leaveToClass);
9847 if (!hasExplicitCallback(onLeave)) {
9848 whenTransitionEnds(el, type, leaveDuration, resolve);
9849 }
9850 });
9851 callHook$1(onLeave, [el, resolve]);
9852 },
9853 onEnterCancelled(el) {
9854 finishEnter(el, false);
9855 callHook$1(onEnterCancelled, [el]);
9856 },
9857 onAppearCancelled(el) {
9858 finishEnter(el, true);
9859 callHook$1(onAppearCancelled, [el]);
9860 },
9861 onLeaveCancelled(el) {
9862 finishLeave(el);
9863 callHook$1(onLeaveCancelled, [el]);
9864 }
9865 });
9866}
9867function normalizeDuration(duration) {
9868 if (duration == null) {
9869 return null;
9870 }
9871 else if (isObject(duration)) {
9872 return [NumberOf(duration.enter), NumberOf(duration.leave)];
9873 }
9874 else {
9875 const n = NumberOf(duration);
9876 return [n, n];
9877 }
9878}
9879function NumberOf(val) {
9880 const res = toNumber(val);
9881 validateDuration(res);
9882 return res;
9883}
9884function validateDuration(val) {
9885 if (typeof val !== 'number') {
9886 warn$1(`<transition> explicit duration is not a valid number - ` +
9887 `got ${JSON.stringify(val)}.`);
9888 }
9889 else if (isNaN(val)) {
9890 warn$1(`<transition> explicit duration is NaN - ` +
9891 'the duration expression might be incorrect.');
9892 }
9893}
9894function addTransitionClass(el, cls) {
9895 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
9896 (el._vtc ||
9897 (el._vtc = new Set())).add(cls);
9898}
9899function removeTransitionClass(el, cls) {
9900 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
9901 const { _vtc } = el;
9902 if (_vtc) {
9903 _vtc.delete(cls);
9904 if (!_vtc.size) {
9905 el._vtc = undefined;
9906 }
9907 }
9908}
9909function nextFrame(cb) {
9910 requestAnimationFrame(() => {
9911 requestAnimationFrame(cb);
9912 });
9913}
9914let endId = 0;
9915function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
9916 const id = (el._endId = ++endId);
9917 const resolveIfNotStale = () => {
9918 if (id === el._endId) {
9919 resolve();
9920 }
9921 };
9922 if (explicitTimeout) {
9923 return setTimeout(resolveIfNotStale, explicitTimeout);
9924 }
9925 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
9926 if (!type) {
9927 return resolve();
9928 }
9929 const endEvent = type + 'end';
9930 let ended = 0;
9931 const end = () => {
9932 el.removeEventListener(endEvent, onEnd);
9933 resolveIfNotStale();
9934 };
9935 const onEnd = (e) => {
9936 if (e.target === el && ++ended >= propCount) {
9937 end();
9938 }
9939 };
9940 setTimeout(() => {
9941 if (ended < propCount) {
9942 end();
9943 }
9944 }, timeout + 1);
9945 el.addEventListener(endEvent, onEnd);
9946}
9947function getTransitionInfo(el, expectedType) {
9948 const styles = window.getComputedStyle(el);
9949 // JSDOM may return undefined for transition properties
9950 const getStyleProperties = (key) => (styles[key] || '').split(', ');
9951 const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
9952 const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
9953 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
9954 const animationDelays = getStyleProperties(ANIMATION + 'Delay');
9955 const animationDurations = getStyleProperties(ANIMATION + 'Duration');
9956 const animationTimeout = getTimeout(animationDelays, animationDurations);
9957 let type = null;
9958 let timeout = 0;
9959 let propCount = 0;
9960 /* istanbul ignore if */
9961 if (expectedType === TRANSITION) {
9962 if (transitionTimeout > 0) {
9963 type = TRANSITION;
9964 timeout = transitionTimeout;
9965 propCount = transitionDurations.length;
9966 }
9967 }
9968 else if (expectedType === ANIMATION) {
9969 if (animationTimeout > 0) {
9970 type = ANIMATION;
9971 timeout = animationTimeout;
9972 propCount = animationDurations.length;
9973 }
9974 }
9975 else {
9976 timeout = Math.max(transitionTimeout, animationTimeout);
9977 type =
9978 timeout > 0
9979 ? transitionTimeout > animationTimeout
9980 ? TRANSITION
9981 : ANIMATION
9982 : null;
9983 propCount = type
9984 ? type === TRANSITION
9985 ? transitionDurations.length
9986 : animationDurations.length
9987 : 0;
9988 }
9989 const hasTransform = type === TRANSITION &&
9990 /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
9991 return {
9992 type,
9993 timeout,
9994 propCount,
9995 hasTransform
9996 };
9997}
9998function getTimeout(delays, durations) {
9999 while (delays.length < durations.length) {
10000 delays = delays.concat(delays);
10001 }
10002 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
10003}
10004// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
10005// numbers in a locale-dependent way, using a comma instead of a dot.
10006// If comma is not replaced with a dot, the input will be rounded down
10007// (i.e. acting as a floor function) causing unexpected behaviors
10008function toMs(s) {
10009 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
10010}
10011// synchronously force layout to put elements into a certain state
10012function forceReflow() {
10013 return document.body.offsetHeight;
10014}
10015
10016const positionMap = new WeakMap();
10017const newPositionMap = new WeakMap();
10018const TransitionGroupImpl = {
10019 name: 'TransitionGroup',
10020 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
10021 tag: String,
10022 moveClass: String
10023 }),
10024 setup(props, { slots }) {
10025 const instance = getCurrentInstance();
10026 const state = useTransitionState();
10027 let prevChildren;
10028 let children;
10029 onUpdated(() => {
10030 // children is guaranteed to exist after initial render
10031 if (!prevChildren.length) {
10032 return;
10033 }
10034 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
10035 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
10036 return;
10037 }
10038 // we divide the work into three loops to avoid mixing DOM reads and writes
10039 // in each iteration - which helps prevent layout thrashing.
10040 prevChildren.forEach(callPendingCbs);
10041 prevChildren.forEach(recordPosition);
10042 const movedChildren = prevChildren.filter(applyTranslation);
10043 // force reflow to put everything in position
10044 forceReflow();
10045 movedChildren.forEach(c => {
10046 const el = c.el;
10047 const style = el.style;
10048 addTransitionClass(el, moveClass);
10049 style.transform = style.webkitTransform = style.transitionDuration = '';
10050 const cb = (el._moveCb = (e) => {
10051 if (e && e.target !== el) {
10052 return;
10053 }
10054 if (!e || /transform$/.test(e.propertyName)) {
10055 el.removeEventListener('transitionend', cb);
10056 el._moveCb = null;
10057 removeTransitionClass(el, moveClass);
10058 }
10059 });
10060 el.addEventListener('transitionend', cb);
10061 });
10062 });
10063 return () => {
10064 const rawProps = toRaw(props);
10065 const cssTransitionProps = resolveTransitionProps(rawProps);
10066 let tag = rawProps.tag || Fragment;
10067 prevChildren = children;
10068 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
10069 for (let i = 0; i < children.length; i++) {
10070 const child = children[i];
10071 if (child.key != null) {
10072 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10073 }
10074 else {
10075 warn$1(`<TransitionGroup> children must be keyed.`);
10076 }
10077 }
10078 if (prevChildren) {
10079 for (let i = 0; i < prevChildren.length; i++) {
10080 const child = prevChildren[i];
10081 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10082 positionMap.set(child, child.el.getBoundingClientRect());
10083 }
10084 }
10085 return createVNode(tag, null, children);
10086 };
10087 }
10088};
10089const TransitionGroup = TransitionGroupImpl;
10090function callPendingCbs(c) {
10091 const el = c.el;
10092 if (el._moveCb) {
10093 el._moveCb();
10094 }
10095 if (el._enterCb) {
10096 el._enterCb();
10097 }
10098}
10099function recordPosition(c) {
10100 newPositionMap.set(c, c.el.getBoundingClientRect());
10101}
10102function applyTranslation(c) {
10103 const oldPos = positionMap.get(c);
10104 const newPos = newPositionMap.get(c);
10105 const dx = oldPos.left - newPos.left;
10106 const dy = oldPos.top - newPos.top;
10107 if (dx || dy) {
10108 const s = c.el.style;
10109 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
10110 s.transitionDuration = '0s';
10111 return c;
10112 }
10113}
10114function hasCSSTransform(el, root, moveClass) {
10115 // Detect whether an element with the move class applied has
10116 // CSS transitions. Since the element may be inside an entering
10117 // transition at this very moment, we make a clone of it and remove
10118 // all other transition classes applied to ensure only the move class
10119 // is applied.
10120 const clone = el.cloneNode();
10121 if (el._vtc) {
10122 el._vtc.forEach(cls => {
10123 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
10124 });
10125 }
10126 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
10127 clone.style.display = 'none';
10128 const container = (root.nodeType === 1 ? root : root.parentNode);
10129 container.appendChild(clone);
10130 const { hasTransform } = getTransitionInfo(clone);
10131 container.removeChild(clone);
10132 return hasTransform;
10133}
10134
10135const getModelAssigner = (vnode) => {
10136 const fn = vnode.props['onUpdate:modelValue'];
10137 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
10138};
10139function onCompositionStart(e) {
10140 e.target.composing = true;
10141}
10142function onCompositionEnd(e) {
10143 const target = e.target;
10144 if (target.composing) {
10145 target.composing = false;
10146 trigger$1(target, 'input');
10147 }
10148}
10149function trigger$1(el, type) {
10150 const e = document.createEvent('HTMLEvents');
10151 e.initEvent(type, true, true);
10152 el.dispatchEvent(e);
10153}
10154// We are exporting the v-model runtime directly as vnode hooks so that it can
10155// be tree-shaken in case v-model is never used.
10156const vModelText = {
10157 created(el, { modifiers: { lazy, trim, number } }, vnode) {
10158 el._assign = getModelAssigner(vnode);
10159 const castToNumber = number || (vnode.props && vnode.props.type === 'number');
10160 addEventListener(el, lazy ? 'change' : 'input', e => {
10161 if (e.target.composing)
10162 return;
10163 let domValue = el.value;
10164 if (trim) {
10165 domValue = domValue.trim();
10166 }
10167 else if (castToNumber) {
10168 domValue = toNumber(domValue);
10169 }
10170 el._assign(domValue);
10171 });
10172 if (trim) {
10173 addEventListener(el, 'change', () => {
10174 el.value = el.value.trim();
10175 });
10176 }
10177 if (!lazy) {
10178 addEventListener(el, 'compositionstart', onCompositionStart);
10179 addEventListener(el, 'compositionend', onCompositionEnd);
10180 // Safari < 10.2 & UIWebView doesn't fire compositionend when
10181 // switching focus before confirming composition choice
10182 // this also fixes the issue where some browsers e.g. iOS Chrome
10183 // fires "change" instead of "input" on autocomplete.
10184 addEventListener(el, 'change', onCompositionEnd);
10185 }
10186 },
10187 // set value on mounted so it's after min/max for type="range"
10188 mounted(el, { value }) {
10189 el.value = value == null ? '' : value;
10190 },
10191 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
10192 el._assign = getModelAssigner(vnode);
10193 // avoid clearing unresolved text. #2302
10194 if (el.composing)
10195 return;
10196 if (document.activeElement === el) {
10197 if (lazy) {
10198 return;
10199 }
10200 if (trim && el.value.trim() === value) {
10201 return;
10202 }
10203 if ((number || el.type === 'number') && toNumber(el.value) === value) {
10204 return;
10205 }
10206 }
10207 const newValue = value == null ? '' : value;
10208 if (el.value !== newValue) {
10209 el.value = newValue;
10210 }
10211 }
10212};
10213const vModelCheckbox = {
10214 // #4096 array checkboxes need to be deep traversed
10215 deep: true,
10216 created(el, _, vnode) {
10217 el._assign = getModelAssigner(vnode);
10218 addEventListener(el, 'change', () => {
10219 const modelValue = el._modelValue;
10220 const elementValue = getValue(el);
10221 const checked = el.checked;
10222 const assign = el._assign;
10223 if (isArray(modelValue)) {
10224 const index = looseIndexOf(modelValue, elementValue);
10225 const found = index !== -1;
10226 if (checked && !found) {
10227 assign(modelValue.concat(elementValue));
10228 }
10229 else if (!checked && found) {
10230 const filtered = [...modelValue];
10231 filtered.splice(index, 1);
10232 assign(filtered);
10233 }
10234 }
10235 else if (isSet(modelValue)) {
10236 const cloned = new Set(modelValue);
10237 if (checked) {
10238 cloned.add(elementValue);
10239 }
10240 else {
10241 cloned.delete(elementValue);
10242 }
10243 assign(cloned);
10244 }
10245 else {
10246 assign(getCheckboxValue(el, checked));
10247 }
10248 });
10249 },
10250 // set initial checked on mount to wait for true-value/false-value
10251 mounted: setChecked,
10252 beforeUpdate(el, binding, vnode) {
10253 el._assign = getModelAssigner(vnode);
10254 setChecked(el, binding, vnode);
10255 }
10256};
10257function setChecked(el, { value, oldValue }, vnode) {
10258 el._modelValue = value;
10259 if (isArray(value)) {
10260 el.checked = looseIndexOf(value, vnode.props.value) > -1;
10261 }
10262 else if (isSet(value)) {
10263 el.checked = value.has(vnode.props.value);
10264 }
10265 else if (value !== oldValue) {
10266 el.checked = looseEqual(value, getCheckboxValue(el, true));
10267 }
10268}
10269const vModelRadio = {
10270 created(el, { value }, vnode) {
10271 el.checked = looseEqual(value, vnode.props.value);
10272 el._assign = getModelAssigner(vnode);
10273 addEventListener(el, 'change', () => {
10274 el._assign(getValue(el));
10275 });
10276 },
10277 beforeUpdate(el, { value, oldValue }, vnode) {
10278 el._assign = getModelAssigner(vnode);
10279 if (value !== oldValue) {
10280 el.checked = looseEqual(value, vnode.props.value);
10281 }
10282 }
10283};
10284const vModelSelect = {
10285 // <select multiple> value need to be deep traversed
10286 deep: true,
10287 created(el, { value, modifiers: { number } }, vnode) {
10288 const isSetModel = isSet(value);
10289 addEventListener(el, 'change', () => {
10290 const selectedVal = Array.prototype.filter
10291 .call(el.options, (o) => o.selected)
10292 .map((o) => number ? toNumber(getValue(o)) : getValue(o));
10293 el._assign(el.multiple
10294 ? isSetModel
10295 ? new Set(selectedVal)
10296 : selectedVal
10297 : selectedVal[0]);
10298 });
10299 el._assign = getModelAssigner(vnode);
10300 },
10301 // set value in mounted & updated because <select> relies on its children
10302 // <option>s.
10303 mounted(el, { value }) {
10304 setSelected(el, value);
10305 },
10306 beforeUpdate(el, _binding, vnode) {
10307 el._assign = getModelAssigner(vnode);
10308 },
10309 updated(el, { value }) {
10310 setSelected(el, value);
10311 }
10312};
10313function setSelected(el, value) {
10314 const isMultiple = el.multiple;
10315 if (isMultiple && !isArray(value) && !isSet(value)) {
10316 warn$1(`<select multiple v-model> expects an Array or Set value for its binding, ` +
10317 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
10318 return;
10319 }
10320 for (let i = 0, l = el.options.length; i < l; i++) {
10321 const option = el.options[i];
10322 const optionValue = getValue(option);
10323 if (isMultiple) {
10324 if (isArray(value)) {
10325 option.selected = looseIndexOf(value, optionValue) > -1;
10326 }
10327 else {
10328 option.selected = value.has(optionValue);
10329 }
10330 }
10331 else {
10332 if (looseEqual(getValue(option), value)) {
10333 if (el.selectedIndex !== i)
10334 el.selectedIndex = i;
10335 return;
10336 }
10337 }
10338 }
10339 if (!isMultiple && el.selectedIndex !== -1) {
10340 el.selectedIndex = -1;
10341 }
10342}
10343// retrieve raw value set via :value bindings
10344function getValue(el) {
10345 return '_value' in el ? el._value : el.value;
10346}
10347// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
10348function getCheckboxValue(el, checked) {
10349 const key = checked ? '_trueValue' : '_falseValue';
10350 return key in el ? el[key] : checked;
10351}
10352const vModelDynamic = {
10353 created(el, binding, vnode) {
10354 callModelHook(el, binding, vnode, null, 'created');
10355 },
10356 mounted(el, binding, vnode) {
10357 callModelHook(el, binding, vnode, null, 'mounted');
10358 },
10359 beforeUpdate(el, binding, vnode, prevVNode) {
10360 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
10361 },
10362 updated(el, binding, vnode, prevVNode) {
10363 callModelHook(el, binding, vnode, prevVNode, 'updated');
10364 }
10365};
10366function callModelHook(el, binding, vnode, prevVNode, hook) {
10367 let modelToUse;
10368 switch (el.tagName) {
10369 case 'SELECT':
10370 modelToUse = vModelSelect;
10371 break;
10372 case 'TEXTAREA':
10373 modelToUse = vModelText;
10374 break;
10375 default:
10376 switch (vnode.props && vnode.props.type) {
10377 case 'checkbox':
10378 modelToUse = vModelCheckbox;
10379 break;
10380 case 'radio':
10381 modelToUse = vModelRadio;
10382 break;
10383 default:
10384 modelToUse = vModelText;
10385 }
10386 }
10387 const fn = modelToUse[hook];
10388 fn && fn(el, binding, vnode, prevVNode);
10389}
10390
10391const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
10392const modifierGuards = {
10393 stop: e => e.stopPropagation(),
10394 prevent: e => e.preventDefault(),
10395 self: e => e.target !== e.currentTarget,
10396 ctrl: e => !e.ctrlKey,
10397 shift: e => !e.shiftKey,
10398 alt: e => !e.altKey,
10399 meta: e => !e.metaKey,
10400 left: e => 'button' in e && e.button !== 0,
10401 middle: e => 'button' in e && e.button !== 1,
10402 right: e => 'button' in e && e.button !== 2,
10403 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
10404};
10405/**
10406 * @private
10407 */
10408const withModifiers = (fn, modifiers) => {
10409 return (event, ...args) => {
10410 for (let i = 0; i < modifiers.length; i++) {
10411 const guard = modifierGuards[modifiers[i]];
10412 if (guard && guard(event, modifiers))
10413 return;
10414 }
10415 return fn(event, ...args);
10416 };
10417};
10418// Kept for 2.x compat.
10419// Note: IE11 compat for `spacebar` and `del` is removed for now.
10420const keyNames = {
10421 esc: 'escape',
10422 space: ' ',
10423 up: 'arrow-up',
10424 left: 'arrow-left',
10425 right: 'arrow-right',
10426 down: 'arrow-down',
10427 delete: 'backspace'
10428};
10429/**
10430 * @private
10431 */
10432const withKeys = (fn, modifiers) => {
10433 return (event) => {
10434 if (!('key' in event)) {
10435 return;
10436 }
10437 const eventKey = hyphenate(event.key);
10438 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
10439 return fn(event);
10440 }
10441 };
10442};
10443
10444const vShow = {
10445 beforeMount(el, { value }, { transition }) {
10446 el._vod = el.style.display === 'none' ? '' : el.style.display;
10447 if (transition && value) {
10448 transition.beforeEnter(el);
10449 }
10450 else {
10451 setDisplay(el, value);
10452 }
10453 },
10454 mounted(el, { value }, { transition }) {
10455 if (transition && value) {
10456 transition.enter(el);
10457 }
10458 },
10459 updated(el, { value, oldValue }, { transition }) {
10460 if (!value === !oldValue)
10461 return;
10462 if (transition) {
10463 if (value) {
10464 transition.beforeEnter(el);
10465 setDisplay(el, true);
10466 transition.enter(el);
10467 }
10468 else {
10469 transition.leave(el, () => {
10470 setDisplay(el, false);
10471 });
10472 }
10473 }
10474 else {
10475 setDisplay(el, value);
10476 }
10477 },
10478 beforeUnmount(el, { value }) {
10479 setDisplay(el, value);
10480 }
10481};
10482function setDisplay(el, value) {
10483 el.style.display = value ? el._vod : 'none';
10484}
10485
10486const rendererOptions = extend({ patchProp }, nodeOps);
10487// lazy create the renderer - this makes core renderer logic tree-shakable
10488// in case the user only imports reactivity utilities from Vue.
10489let renderer;
10490let enabledHydration = false;
10491function ensureRenderer() {
10492 return (renderer ||
10493 (renderer = createRenderer(rendererOptions)));
10494}
10495function ensureHydrationRenderer() {
10496 renderer = enabledHydration
10497 ? renderer
10498 : createHydrationRenderer(rendererOptions);
10499 enabledHydration = true;
10500 return renderer;
10501}
10502// use explicit type casts here to avoid import() calls in rolled-up d.ts
10503const render = ((...args) => {
10504 ensureRenderer().render(...args);
10505});
10506const hydrate = ((...args) => {
10507 ensureHydrationRenderer().hydrate(...args);
10508});
10509const createApp = ((...args) => {
10510 const app = ensureRenderer().createApp(...args);
10511 {
10512 injectNativeTagCheck(app);
10513 injectCompilerOptionsCheck(app);
10514 }
10515 const { mount } = app;
10516 app.mount = (containerOrSelector) => {
10517 const container = normalizeContainer(containerOrSelector);
10518 if (!container)
10519 return;
10520 const component = app._component;
10521 if (!isFunction(component) && !component.render && !component.template) {
10522 // __UNSAFE__
10523 // Reason: potential execution of JS expressions in in-DOM template.
10524 // The user must make sure the in-DOM template is trusted. If it's
10525 // rendered by the server, the template should not contain any user data.
10526 component.template = container.innerHTML;
10527 }
10528 // clear content before mounting
10529 container.innerHTML = '';
10530 const proxy = mount(container, false, container instanceof SVGElement);
10531 if (container instanceof Element) {
10532 container.removeAttribute('v-cloak');
10533 container.setAttribute('data-v-app', '');
10534 }
10535 return proxy;
10536 };
10537 return app;
10538});
10539const createSSRApp = ((...args) => {
10540 const app = ensureHydrationRenderer().createApp(...args);
10541 {
10542 injectNativeTagCheck(app);
10543 injectCompilerOptionsCheck(app);
10544 }
10545 const { mount } = app;
10546 app.mount = (containerOrSelector) => {
10547 const container = normalizeContainer(containerOrSelector);
10548 if (container) {
10549 return mount(container, true, container instanceof SVGElement);
10550 }
10551 };
10552 return app;
10553});
10554function injectNativeTagCheck(app) {
10555 // Inject `isNativeTag`
10556 // this is used for component name validation (dev only)
10557 Object.defineProperty(app.config, 'isNativeTag', {
10558 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
10559 writable: false
10560 });
10561}
10562// dev only
10563function injectCompilerOptionsCheck(app) {
10564 if (isRuntimeOnly()) {
10565 const isCustomElement = app.config.isCustomElement;
10566 Object.defineProperty(app.config, 'isCustomElement', {
10567 get() {
10568 return isCustomElement;
10569 },
10570 set() {
10571 warn$1(`The \`isCustomElement\` config option is deprecated. Use ` +
10572 `\`compilerOptions.isCustomElement\` instead.`);
10573 }
10574 });
10575 const compilerOptions = app.config.compilerOptions;
10576 const msg = `The \`compilerOptions\` config option is only respected when using ` +
10577 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
10578 `Since you are using the runtime-only build, \`compilerOptions\` ` +
10579 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
10580 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
10581 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
10582 `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom`;
10583 Object.defineProperty(app.config, 'compilerOptions', {
10584 get() {
10585 warn$1(msg);
10586 return compilerOptions;
10587 },
10588 set() {
10589 warn$1(msg);
10590 }
10591 });
10592 }
10593}
10594function normalizeContainer(container) {
10595 if (isString(container)) {
10596 const res = document.querySelector(container);
10597 if (!res) {
10598 warn$1(`Failed to mount app: mount target selector "${container}" returned null.`);
10599 }
10600 return res;
10601 }
10602 if (window.ShadowRoot &&
10603 container instanceof window.ShadowRoot &&
10604 container.mode === 'closed') {
10605 warn$1(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
10606 }
10607 return container;
10608}
10609/**
10610 * @internal
10611 */
10612const initDirectivesForSSR = NOOP;
10613
10614var runtimeDom = /*#__PURE__*/Object.freeze({
10615 __proto__: null,
10616 render: render,
10617 hydrate: hydrate,
10618 createApp: createApp,
10619 createSSRApp: createSSRApp,
10620 initDirectivesForSSR: initDirectivesForSSR,
10621 defineCustomElement: defineCustomElement,
10622 defineSSRCustomElement: defineSSRCustomElement,
10623 VueElement: VueElement,
10624 useCssModule: useCssModule,
10625 useCssVars: useCssVars,
10626 Transition: Transition,
10627 TransitionGroup: TransitionGroup,
10628 vModelText: vModelText,
10629 vModelCheckbox: vModelCheckbox,
10630 vModelRadio: vModelRadio,
10631 vModelSelect: vModelSelect,
10632 vModelDynamic: vModelDynamic,
10633 withModifiers: withModifiers,
10634 withKeys: withKeys,
10635 vShow: vShow,
10636 computed: computed,
10637 reactive: reactive,
10638 ref: ref,
10639 readonly: readonly,
10640 unref: unref,
10641 proxyRefs: proxyRefs,
10642 isRef: isRef,
10643 toRef: toRef,
10644 toRefs: toRefs,
10645 isProxy: isProxy,
10646 isReactive: isReactive,
10647 isReadonly: isReadonly,
10648 customRef: customRef,
10649 triggerRef: triggerRef,
10650 shallowRef: shallowRef,
10651 shallowReactive: shallowReactive,
10652 shallowReadonly: shallowReadonly,
10653 markRaw: markRaw,
10654 toRaw: toRaw,
10655 effect: effect,
10656 stop: stop,
10657 ReactiveEffect: ReactiveEffect,
10658 effectScope: effectScope,
10659 EffectScope: EffectScope,
10660 getCurrentScope: getCurrentScope,
10661 onScopeDispose: onScopeDispose,
10662 watch: watch,
10663 watchEffect: watchEffect,
10664 watchPostEffect: watchPostEffect,
10665 watchSyncEffect: watchSyncEffect,
10666 onBeforeMount: onBeforeMount,
10667 onMounted: onMounted,
10668 onBeforeUpdate: onBeforeUpdate,
10669 onUpdated: onUpdated,
10670 onBeforeUnmount: onBeforeUnmount,
10671 onUnmounted: onUnmounted,
10672 onActivated: onActivated,
10673 onDeactivated: onDeactivated,
10674 onRenderTracked: onRenderTracked,
10675 onRenderTriggered: onRenderTriggered,
10676 onErrorCaptured: onErrorCaptured,
10677 onServerPrefetch: onServerPrefetch,
10678 provide: provide,
10679 inject: inject,
10680 nextTick: nextTick,
10681 defineComponent: defineComponent,
10682 defineAsyncComponent: defineAsyncComponent,
10683 useAttrs: useAttrs,
10684 useSlots: useSlots,
10685 defineProps: defineProps,
10686 defineEmits: defineEmits,
10687 defineExpose: defineExpose,
10688 withDefaults: withDefaults,
10689 mergeDefaults: mergeDefaults,
10690 withAsyncContext: withAsyncContext,
10691 getCurrentInstance: getCurrentInstance,
10692 h: h,
10693 createVNode: createVNode,
10694 cloneVNode: cloneVNode,
10695 mergeProps: mergeProps,
10696 isVNode: isVNode,
10697 Fragment: Fragment,
10698 Text: Text,
10699 Comment: Comment,
10700 Static: Static,
10701 Teleport: Teleport,
10702 Suspense: Suspense,
10703 KeepAlive: KeepAlive,
10704 BaseTransition: BaseTransition,
10705 withDirectives: withDirectives,
10706 useSSRContext: useSSRContext,
10707 ssrContextKey: ssrContextKey,
10708 createRenderer: createRenderer,
10709 createHydrationRenderer: createHydrationRenderer,
10710 queuePostFlushCb: queuePostFlushCb,
10711 warn: warn$1,
10712 handleError: handleError,
10713 callWithErrorHandling: callWithErrorHandling,
10714 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
10715 resolveComponent: resolveComponent,
10716 resolveDirective: resolveDirective,
10717 resolveDynamicComponent: resolveDynamicComponent,
10718 registerRuntimeCompiler: registerRuntimeCompiler,
10719 isRuntimeOnly: isRuntimeOnly,
10720 useTransitionState: useTransitionState,
10721 resolveTransitionHooks: resolveTransitionHooks,
10722 setTransitionHooks: setTransitionHooks,
10723 getTransitionRawChildren: getTransitionRawChildren,
10724 initCustomFormatter: initCustomFormatter,
10725 get devtools () { return devtools; },
10726 setDevtoolsHook: setDevtoolsHook,
10727 withCtx: withCtx,
10728 pushScopeId: pushScopeId,
10729 popScopeId: popScopeId,
10730 withScopeId: withScopeId,
10731 renderList: renderList,
10732 toHandlers: toHandlers,
10733 renderSlot: renderSlot,
10734 createSlots: createSlots,
10735 withMemo: withMemo,
10736 isMemoSame: isMemoSame,
10737 openBlock: openBlock,
10738 createBlock: createBlock,
10739 setBlockTracking: setBlockTracking,
10740 createTextVNode: createTextVNode,
10741 createCommentVNode: createCommentVNode,
10742 createStaticVNode: createStaticVNode,
10743 createElementVNode: createBaseVNode,
10744 createElementBlock: createElementBlock,
10745 guardReactiveProps: guardReactiveProps,
10746 toDisplayString: toDisplayString,
10747 camelize: camelize,
10748 capitalize: capitalize,
10749 toHandlerKey: toHandlerKey,
10750 normalizeProps: normalizeProps,
10751 normalizeClass: normalizeClass,
10752 normalizeStyle: normalizeStyle,
10753 transformVNodeArgs: transformVNodeArgs,
10754 version: version,
10755 ssrUtils: ssrUtils,
10756 resolveFilter: resolveFilter,
10757 compatUtils: compatUtils
10758});
10759
10760function initDev() {
10761 {
10762 {
10763 console.info(`You are running a development build of Vue.\n` +
10764 `Make sure to use the production build (*.prod.js) when deploying for production.`);
10765 }
10766 initCustomFormatter();
10767 }
10768}
10769
10770function defaultOnError(error) {
10771 throw error;
10772}
10773function defaultOnWarn(msg) {
10774 console.warn(`[Vue warn] ${msg.message}`);
10775}
10776function createCompilerError(code, loc, messages, additionalMessage) {
10777 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
10778 ;
10779 const error = new SyntaxError(String(msg));
10780 error.code = code;
10781 error.loc = loc;
10782 return error;
10783}
10784const errorMessages = {
10785 // parse errors
10786 [0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
10787 [1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
10788 [2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
10789 [3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
10790 [4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
10791 [5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
10792 [6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
10793 [7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
10794 [8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
10795 [9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
10796 [10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
10797 [11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
10798 [12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
10799 [13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
10800 [14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
10801 [15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
10802 [16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
10803 [17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
10804 [18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
10805 [19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
10806 [21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
10807 [20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
10808 [22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
10809 // Vue-specific parse errors
10810 [23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
10811 [24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
10812 [25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
10813 [27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
10814 'Note that dynamic directive argument cannot contain spaces.',
10815 [26 /* X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
10816 // transform errors
10817 [28 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
10818 [29 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
10819 [30 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
10820 [31 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
10821 [32 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
10822 [33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
10823 [34 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
10824 [35 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
10825 [36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
10826 [37 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
10827 `When there are multiple named slots, all slots should use <template> ` +
10828 `syntax to avoid scope ambiguity.`,
10829 [38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
10830 [39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
10831 `default slot. These children will be ignored.`,
10832 [40 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
10833 [41 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
10834 [42 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
10835 [43 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
10836 [44 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
10837 [45 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
10838 // generic errors
10839 [46 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
10840 [47 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
10841 [48 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
10842 [49 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
10843 // just to fulfill types
10844 [50 /* __EXTEND_POINT__ */]: ``
10845};
10846
10847const FRAGMENT = Symbol(`Fragment` );
10848const TELEPORT = Symbol(`Teleport` );
10849const SUSPENSE = Symbol(`Suspense` );
10850const KEEP_ALIVE = Symbol(`KeepAlive` );
10851const BASE_TRANSITION = Symbol(`BaseTransition` );
10852const OPEN_BLOCK = Symbol(`openBlock` );
10853const CREATE_BLOCK = Symbol(`createBlock` );
10854const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` );
10855const CREATE_VNODE = Symbol(`createVNode` );
10856const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` );
10857const CREATE_COMMENT = Symbol(`createCommentVNode` );
10858const CREATE_TEXT = Symbol(`createTextVNode` );
10859const CREATE_STATIC = Symbol(`createStaticVNode` );
10860const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
10861const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
10862const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
10863const RESOLVE_FILTER = Symbol(`resolveFilter` );
10864const WITH_DIRECTIVES = Symbol(`withDirectives` );
10865const RENDER_LIST = Symbol(`renderList` );
10866const RENDER_SLOT = Symbol(`renderSlot` );
10867const CREATE_SLOTS = Symbol(`createSlots` );
10868const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
10869const MERGE_PROPS = Symbol(`mergeProps` );
10870const NORMALIZE_CLASS = Symbol(`normalizeClass` );
10871const NORMALIZE_STYLE = Symbol(`normalizeStyle` );
10872const NORMALIZE_PROPS = Symbol(`normalizeProps` );
10873const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` );
10874const TO_HANDLERS = Symbol(`toHandlers` );
10875const CAMELIZE = Symbol(`camelize` );
10876const CAPITALIZE = Symbol(`capitalize` );
10877const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
10878const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
10879const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
10880const POP_SCOPE_ID = Symbol(`popScopeId` );
10881const WITH_CTX = Symbol(`withCtx` );
10882const UNREF = Symbol(`unref` );
10883const IS_REF = Symbol(`isRef` );
10884const WITH_MEMO = Symbol(`withMemo` );
10885const IS_MEMO_SAME = Symbol(`isMemoSame` );
10886// Name mapping for runtime helpers that need to be imported from 'vue' in
10887// generated code. Make sure these are correctly exported in the runtime!
10888// Using `any` here because TS doesn't allow symbols as index type.
10889const helperNameMap = {
10890 [FRAGMENT]: `Fragment`,
10891 [TELEPORT]: `Teleport`,
10892 [SUSPENSE]: `Suspense`,
10893 [KEEP_ALIVE]: `KeepAlive`,
10894 [BASE_TRANSITION]: `BaseTransition`,
10895 [OPEN_BLOCK]: `openBlock`,
10896 [CREATE_BLOCK]: `createBlock`,
10897 [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
10898 [CREATE_VNODE]: `createVNode`,
10899 [CREATE_ELEMENT_VNODE]: `createElementVNode`,
10900 [CREATE_COMMENT]: `createCommentVNode`,
10901 [CREATE_TEXT]: `createTextVNode`,
10902 [CREATE_STATIC]: `createStaticVNode`,
10903 [RESOLVE_COMPONENT]: `resolveComponent`,
10904 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
10905 [RESOLVE_DIRECTIVE]: `resolveDirective`,
10906 [RESOLVE_FILTER]: `resolveFilter`,
10907 [WITH_DIRECTIVES]: `withDirectives`,
10908 [RENDER_LIST]: `renderList`,
10909 [RENDER_SLOT]: `renderSlot`,
10910 [CREATE_SLOTS]: `createSlots`,
10911 [TO_DISPLAY_STRING]: `toDisplayString`,
10912 [MERGE_PROPS]: `mergeProps`,
10913 [NORMALIZE_CLASS]: `normalizeClass`,
10914 [NORMALIZE_STYLE]: `normalizeStyle`,
10915 [NORMALIZE_PROPS]: `normalizeProps`,
10916 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
10917 [TO_HANDLERS]: `toHandlers`,
10918 [CAMELIZE]: `camelize`,
10919 [CAPITALIZE]: `capitalize`,
10920 [TO_HANDLER_KEY]: `toHandlerKey`,
10921 [SET_BLOCK_TRACKING]: `setBlockTracking`,
10922 [PUSH_SCOPE_ID]: `pushScopeId`,
10923 [POP_SCOPE_ID]: `popScopeId`,
10924 [WITH_CTX]: `withCtx`,
10925 [UNREF]: `unref`,
10926 [IS_REF]: `isRef`,
10927 [WITH_MEMO]: `withMemo`,
10928 [IS_MEMO_SAME]: `isMemoSame`
10929};
10930function registerRuntimeHelpers(helpers) {
10931 Object.getOwnPropertySymbols(helpers).forEach(s => {
10932 helperNameMap[s] = helpers[s];
10933 });
10934}
10935
10936// AST Utilities ---------------------------------------------------------------
10937// Some expressions, e.g. sequence and conditional expressions, are never
10938// associated with template nodes, so their source locations are just a stub.
10939// Container types like CompoundExpression also don't need a real location.
10940const locStub = {
10941 source: '',
10942 start: { line: 1, column: 1, offset: 0 },
10943 end: { line: 1, column: 1, offset: 0 }
10944};
10945function createRoot(children, loc = locStub) {
10946 return {
10947 type: 0 /* ROOT */,
10948 children,
10949 helpers: [],
10950 components: [],
10951 directives: [],
10952 hoists: [],
10953 imports: [],
10954 cached: 0,
10955 temps: 0,
10956 codegenNode: undefined,
10957 loc
10958 };
10959}
10960function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
10961 if (context) {
10962 if (isBlock) {
10963 context.helper(OPEN_BLOCK);
10964 context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
10965 }
10966 else {
10967 context.helper(getVNodeHelper(context.inSSR, isComponent));
10968 }
10969 if (directives) {
10970 context.helper(WITH_DIRECTIVES);
10971 }
10972 }
10973 return {
10974 type: 13 /* VNODE_CALL */,
10975 tag,
10976 props,
10977 children,
10978 patchFlag,
10979 dynamicProps,
10980 directives,
10981 isBlock,
10982 disableTracking,
10983 isComponent,
10984 loc
10985 };
10986}
10987function createArrayExpression(elements, loc = locStub) {
10988 return {
10989 type: 17 /* JS_ARRAY_EXPRESSION */,
10990 loc,
10991 elements
10992 };
10993}
10994function createObjectExpression(properties, loc = locStub) {
10995 return {
10996 type: 15 /* JS_OBJECT_EXPRESSION */,
10997 loc,
10998 properties
10999 };
11000}
11001function createObjectProperty(key, value) {
11002 return {
11003 type: 16 /* JS_PROPERTY */,
11004 loc: locStub,
11005 key: isString(key) ? createSimpleExpression(key, true) : key,
11006 value
11007 };
11008}
11009function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
11010 return {
11011 type: 4 /* SIMPLE_EXPRESSION */,
11012 loc,
11013 content,
11014 isStatic,
11015 constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
11016 };
11017}
11018function createCompoundExpression(children, loc = locStub) {
11019 return {
11020 type: 8 /* COMPOUND_EXPRESSION */,
11021 loc,
11022 children
11023 };
11024}
11025function createCallExpression(callee, args = [], loc = locStub) {
11026 return {
11027 type: 14 /* JS_CALL_EXPRESSION */,
11028 loc,
11029 callee,
11030 arguments: args
11031 };
11032}
11033function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
11034 return {
11035 type: 18 /* JS_FUNCTION_EXPRESSION */,
11036 params,
11037 returns,
11038 newline,
11039 isSlot,
11040 loc
11041 };
11042}
11043function createConditionalExpression(test, consequent, alternate, newline = true) {
11044 return {
11045 type: 19 /* JS_CONDITIONAL_EXPRESSION */,
11046 test,
11047 consequent,
11048 alternate,
11049 newline,
11050 loc: locStub
11051 };
11052}
11053function createCacheExpression(index, value, isVNode = false) {
11054 return {
11055 type: 20 /* JS_CACHE_EXPRESSION */,
11056 index,
11057 value,
11058 isVNode,
11059 loc: locStub
11060 };
11061}
11062function createBlockStatement(body) {
11063 return {
11064 type: 21 /* JS_BLOCK_STATEMENT */,
11065 body,
11066 loc: locStub
11067 };
11068}
11069
11070const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
11071const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
11072function isCoreComponent(tag) {
11073 if (isBuiltInType(tag, 'Teleport')) {
11074 return TELEPORT;
11075 }
11076 else if (isBuiltInType(tag, 'Suspense')) {
11077 return SUSPENSE;
11078 }
11079 else if (isBuiltInType(tag, 'KeepAlive')) {
11080 return KEEP_ALIVE;
11081 }
11082 else if (isBuiltInType(tag, 'BaseTransition')) {
11083 return BASE_TRANSITION;
11084 }
11085}
11086const nonIdentifierRE = /^\d|[^\$\w]/;
11087const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
11088const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
11089const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
11090const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
11091/**
11092 * Simple lexer to check if an expression is a member expression. This is
11093 * lax and only checks validity at the root level (i.e. does not validate exps
11094 * inside square brackets), but it's ok since these are only used on template
11095 * expressions and false positives are invalid expressions in the first place.
11096 */
11097const isMemberExpressionBrowser = (path) => {
11098 // remove whitespaces around . or [ first
11099 path = path.trim().replace(whitespaceRE, s => s.trim());
11100 let state = 0 /* inMemberExp */;
11101 let stateStack = [];
11102 let currentOpenBracketCount = 0;
11103 let currentOpenParensCount = 0;
11104 let currentStringType = null;
11105 for (let i = 0; i < path.length; i++) {
11106 const char = path.charAt(i);
11107 switch (state) {
11108 case 0 /* inMemberExp */:
11109 if (char === '[') {
11110 stateStack.push(state);
11111 state = 1 /* inBrackets */;
11112 currentOpenBracketCount++;
11113 }
11114 else if (char === '(') {
11115 stateStack.push(state);
11116 state = 2 /* inParens */;
11117 currentOpenParensCount++;
11118 }
11119 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
11120 return false;
11121 }
11122 break;
11123 case 1 /* inBrackets */:
11124 if (char === `'` || char === `"` || char === '`') {
11125 stateStack.push(state);
11126 state = 3 /* inString */;
11127 currentStringType = char;
11128 }
11129 else if (char === `[`) {
11130 currentOpenBracketCount++;
11131 }
11132 else if (char === `]`) {
11133 if (!--currentOpenBracketCount) {
11134 state = stateStack.pop();
11135 }
11136 }
11137 break;
11138 case 2 /* inParens */:
11139 if (char === `'` || char === `"` || char === '`') {
11140 stateStack.push(state);
11141 state = 3 /* inString */;
11142 currentStringType = char;
11143 }
11144 else if (char === `(`) {
11145 currentOpenParensCount++;
11146 }
11147 else if (char === `)`) {
11148 // if the exp ends as a call then it should not be considered valid
11149 if (i === path.length - 1) {
11150 return false;
11151 }
11152 if (!--currentOpenParensCount) {
11153 state = stateStack.pop();
11154 }
11155 }
11156 break;
11157 case 3 /* inString */:
11158 if (char === currentStringType) {
11159 state = stateStack.pop();
11160 currentStringType = null;
11161 }
11162 break;
11163 }
11164 }
11165 return !currentOpenBracketCount && !currentOpenParensCount;
11166};
11167const isMemberExpression = isMemberExpressionBrowser
11168 ;
11169function getInnerRange(loc, offset, length) {
11170 const source = loc.source.substr(offset, length);
11171 const newLoc = {
11172 source,
11173 start: advancePositionWithClone(loc.start, loc.source, offset),
11174 end: loc.end
11175 };
11176 if (length != null) {
11177 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
11178 }
11179 return newLoc;
11180}
11181function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
11182 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
11183}
11184// advance by mutation without cloning (for performance reasons), since this
11185// gets called a lot in the parser
11186function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
11187 let linesCount = 0;
11188 let lastNewLinePos = -1;
11189 for (let i = 0; i < numberOfCharacters; i++) {
11190 if (source.charCodeAt(i) === 10 /* newline char code */) {
11191 linesCount++;
11192 lastNewLinePos = i;
11193 }
11194 }
11195 pos.offset += numberOfCharacters;
11196 pos.line += linesCount;
11197 pos.column =
11198 lastNewLinePos === -1
11199 ? pos.column + numberOfCharacters
11200 : numberOfCharacters - lastNewLinePos;
11201 return pos;
11202}
11203function assert(condition, msg) {
11204 /* istanbul ignore if */
11205 if (!condition) {
11206 throw new Error(msg || `unexpected compiler condition`);
11207 }
11208}
11209function findDir(node, name, allowEmpty = false) {
11210 for (let i = 0; i < node.props.length; i++) {
11211 const p = node.props[i];
11212 if (p.type === 7 /* DIRECTIVE */ &&
11213 (allowEmpty || p.exp) &&
11214 (isString(name) ? p.name === name : name.test(p.name))) {
11215 return p;
11216 }
11217 }
11218}
11219function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11220 for (let i = 0; i < node.props.length; i++) {
11221 const p = node.props[i];
11222 if (p.type === 6 /* ATTRIBUTE */) {
11223 if (dynamicOnly)
11224 continue;
11225 if (p.name === name && (p.value || allowEmpty)) {
11226 return p;
11227 }
11228 }
11229 else if (p.name === 'bind' &&
11230 (p.exp || allowEmpty) &&
11231 isBindKey(p.arg, name)) {
11232 return p;
11233 }
11234 }
11235}
11236function isBindKey(arg, name) {
11237 return !!(arg && isStaticExp(arg) && arg.content === name);
11238}
11239function hasDynamicKeyVBind(node) {
11240 return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
11241 p.name === 'bind' &&
11242 (!p.arg || // v-bind="obj"
11243 p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
11244 !p.arg.isStatic) // v-bind:[foo]
11245 );
11246}
11247function isText(node) {
11248 return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
11249}
11250function isVSlot(p) {
11251 return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
11252}
11253function isTemplateNode(node) {
11254 return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
11255}
11256function isSlotOutlet(node) {
11257 return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
11258}
11259function getVNodeHelper(ssr, isComponent) {
11260 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
11261}
11262function getVNodeBlockHelper(ssr, isComponent) {
11263 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
11264}
11265const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
11266function getUnnormalizedProps(props, callPath = []) {
11267 if (props &&
11268 !isString(props) &&
11269 props.type === 14 /* JS_CALL_EXPRESSION */) {
11270 const callee = props.callee;
11271 if (!isString(callee) && propsHelperSet.has(callee)) {
11272 return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
11273 }
11274 }
11275 return [props, callPath];
11276}
11277function injectProp(node, prop, context) {
11278 let propsWithInjection;
11279 const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11280 /**
11281 * 1. mergeProps(...)
11282 * 2. toHandlers(...)
11283 * 3. normalizeProps(...)
11284 * 4. normalizeProps(guardReactiveProps(...))
11285 *
11286 * we need to get the real props before normalization
11287 */
11288 let props = originalProps;
11289 let callPath = [];
11290 let parentCall;
11291 if (props &&
11292 !isString(props) &&
11293 props.type === 14 /* JS_CALL_EXPRESSION */) {
11294 const ret = getUnnormalizedProps(props);
11295 props = ret[0];
11296 callPath = ret[1];
11297 parentCall = callPath[callPath.length - 1];
11298 }
11299 if (props == null || isString(props)) {
11300 propsWithInjection = createObjectExpression([prop]);
11301 }
11302 else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
11303 // merged props... add ours
11304 // only inject key to object literal if it's the first argument so that
11305 // if doesn't override user provided keys
11306 const first = props.arguments[0];
11307 if (!isString(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
11308 first.properties.unshift(prop);
11309 }
11310 else {
11311 if (props.callee === TO_HANDLERS) {
11312 // #2366
11313 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11314 createObjectExpression([prop]),
11315 props
11316 ]);
11317 }
11318 else {
11319 props.arguments.unshift(createObjectExpression([prop]));
11320 }
11321 }
11322 !propsWithInjection && (propsWithInjection = props);
11323 }
11324 else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
11325 let alreadyExists = false;
11326 // check existing key to avoid overriding user provided keys
11327 if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
11328 const propKeyName = prop.key.content;
11329 alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
11330 p.key.content === propKeyName);
11331 }
11332 if (!alreadyExists) {
11333 props.properties.unshift(prop);
11334 }
11335 propsWithInjection = props;
11336 }
11337 else {
11338 // single v-bind with expression, return a merged replacement
11339 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11340 createObjectExpression([prop]),
11341 props
11342 ]);
11343 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
11344 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
11345 // the `guardReactiveProps` will no longer be needed
11346 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
11347 parentCall = callPath[callPath.length - 2];
11348 }
11349 }
11350 if (node.type === 13 /* VNODE_CALL */) {
11351 if (parentCall) {
11352 parentCall.arguments[0] = propsWithInjection;
11353 }
11354 else {
11355 node.props = propsWithInjection;
11356 }
11357 }
11358 else {
11359 if (parentCall) {
11360 parentCall.arguments[0] = propsWithInjection;
11361 }
11362 else {
11363 node.arguments[2] = propsWithInjection;
11364 }
11365 }
11366}
11367function toValidAssetId(name, type) {
11368 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
11369 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
11370 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
11371 })}`;
11372}
11373function getMemoedVNodeCall(node) {
11374 if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
11375 return node.arguments[1].returns;
11376 }
11377 else {
11378 return node;
11379 }
11380}
11381function makeBlock(node, { helper, removeHelper, inSSR }) {
11382 if (!node.isBlock) {
11383 node.isBlock = true;
11384 removeHelper(getVNodeHelper(inSSR, node.isComponent));
11385 helper(OPEN_BLOCK);
11386 helper(getVNodeBlockHelper(inSSR, node.isComponent));
11387 }
11388}
11389
11390const deprecationData = {
11391 ["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
11392 message: `Platform-native elements with "is" prop will no longer be ` +
11393 `treated as components in Vue 3 unless the "is" value is explicitly ` +
11394 `prefixed with "vue:".`,
11395 link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
11396 },
11397 ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
11398 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
11399 `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
11400 `\`v-model:${key}\`.`,
11401 link: `https://v3.vuejs.org/guide/migration/v-model.html`
11402 },
11403 ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
11404 message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
11405 `Vue 3 will automatically set a binding as DOM property when appropriate.`
11406 },
11407 ["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
11408 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
11409 `object spread: it will now overwrite an existing non-mergeable attribute ` +
11410 `that appears before v-bind in the case of conflict. ` +
11411 `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
11412 `You can also suppress this warning if the usage is intended.`,
11413 link: `https://v3.vuejs.org/guide/migration/v-bind.html`
11414 },
11415 ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
11416 message: `.native modifier for v-on has been removed as is no longer necessary.`,
11417 link: `https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html`
11418 },
11419 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
11420 message: `v-if / v-for precedence when used on the same element has changed ` +
11421 `in Vue 3: v-if now takes higher precedence and will no longer have ` +
11422 `access to v-for scope variables. It is best to avoid the ambiguity ` +
11423 `with <template> tags or use a computed property that filters v-for ` +
11424 `data source.`,
11425 link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
11426 },
11427 ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
11428 message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
11429 `Consider using function refs or refactor to avoid ref usage altogether.`,
11430 link: `https://v3.vuejs.org/guide/migration/array-refs.html`
11431 },
11432 ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
11433 message: `<template> with no special directives will render as a native template ` +
11434 `element instead of its inner content in Vue 3.`
11435 },
11436 ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
11437 message: `"inline-template" has been removed in Vue 3.`,
11438 link: `https://v3.vuejs.org/guide/migration/inline-template-attribute.html`
11439 },
11440 ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
11441 message: `filters have been removed in Vue 3. ` +
11442 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
11443 `Use method calls or computed properties instead.`,
11444 link: `https://v3.vuejs.org/guide/migration/filters.html`
11445 }
11446};
11447function getCompatValue(key, context) {
11448 const config = context.options
11449 ? context.options.compatConfig
11450 : context.compatConfig;
11451 const value = config && config[key];
11452 if (key === 'MODE') {
11453 return value || 3; // compiler defaults to v3 behavior
11454 }
11455 else {
11456 return value;
11457 }
11458}
11459function isCompatEnabled(key, context) {
11460 const mode = getCompatValue('MODE', context);
11461 const value = getCompatValue(key, context);
11462 // in v3 mode, only enable if explicitly set to true
11463 // otherwise enable for any non-false value
11464 return mode === 3 ? value === true : value !== false;
11465}
11466function checkCompatEnabled(key, context, loc, ...args) {
11467 const enabled = isCompatEnabled(key, context);
11468 if (enabled) {
11469 warnDeprecation(key, context, loc, ...args);
11470 }
11471 return enabled;
11472}
11473function warnDeprecation(key, context, loc, ...args) {
11474 const val = getCompatValue(key, context);
11475 if (val === 'suppress-warning') {
11476 return;
11477 }
11478 const { message, link } = deprecationData[key];
11479 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
11480 const err = new SyntaxError(msg);
11481 err.code = key;
11482 if (loc)
11483 err.loc = loc;
11484 context.onWarn(err);
11485}
11486
11487// The default decoder only provides escapes for characters reserved as part of
11488// the template syntax, and is only used if the custom renderer did not provide
11489// a platform-specific decoder.
11490const decodeRE = /&(gt|lt|amp|apos|quot);/g;
11491const decodeMap = {
11492 gt: '>',
11493 lt: '<',
11494 amp: '&',
11495 apos: "'",
11496 quot: '"'
11497};
11498const defaultParserOptions = {
11499 delimiters: [`{{`, `}}`],
11500 getNamespace: () => 0 /* HTML */,
11501 getTextMode: () => 0 /* DATA */,
11502 isVoidTag: NO,
11503 isPreTag: NO,
11504 isCustomElement: NO,
11505 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
11506 onError: defaultOnError,
11507 onWarn: defaultOnWarn,
11508 comments: true
11509};
11510function baseParse(content, options = {}) {
11511 const context = createParserContext(content, options);
11512 const start = getCursor(context);
11513 return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
11514}
11515function createParserContext(content, rawOptions) {
11516 const options = extend({}, defaultParserOptions);
11517 let key;
11518 for (key in rawOptions) {
11519 // @ts-ignore
11520 options[key] =
11521 rawOptions[key] === undefined
11522 ? defaultParserOptions[key]
11523 : rawOptions[key];
11524 }
11525 return {
11526 options,
11527 column: 1,
11528 line: 1,
11529 offset: 0,
11530 originalSource: content,
11531 source: content,
11532 inPre: false,
11533 inVPre: false,
11534 onWarn: options.onWarn
11535 };
11536}
11537function parseChildren(context, mode, ancestors) {
11538 const parent = last(ancestors);
11539 const ns = parent ? parent.ns : 0 /* HTML */;
11540 const nodes = [];
11541 while (!isEnd(context, mode, ancestors)) {
11542 const s = context.source;
11543 let node = undefined;
11544 if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
11545 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
11546 // '{{'
11547 node = parseInterpolation(context, mode);
11548 }
11549 else if (mode === 0 /* DATA */ && s[0] === '<') {
11550 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
11551 if (s.length === 1) {
11552 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
11553 }
11554 else if (s[1] === '!') {
11555 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
11556 if (startsWith(s, '<!--')) {
11557 node = parseComment(context);
11558 }
11559 else if (startsWith(s, '<!DOCTYPE')) {
11560 // Ignore DOCTYPE by a limitation.
11561 node = parseBogusComment(context);
11562 }
11563 else if (startsWith(s, '<![CDATA[')) {
11564 if (ns !== 0 /* HTML */) {
11565 node = parseCDATA(context, ancestors);
11566 }
11567 else {
11568 emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
11569 node = parseBogusComment(context);
11570 }
11571 }
11572 else {
11573 emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
11574 node = parseBogusComment(context);
11575 }
11576 }
11577 else if (s[1] === '/') {
11578 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
11579 if (s.length === 2) {
11580 emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
11581 }
11582 else if (s[2] === '>') {
11583 emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
11584 advanceBy(context, 3);
11585 continue;
11586 }
11587 else if (/[a-z]/i.test(s[2])) {
11588 emitError(context, 23 /* X_INVALID_END_TAG */);
11589 parseTag(context, 1 /* End */, parent);
11590 continue;
11591 }
11592 else {
11593 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
11594 node = parseBogusComment(context);
11595 }
11596 }
11597 else if (/[a-z]/i.test(s[1])) {
11598 node = parseElement(context, ancestors);
11599 }
11600 else if (s[1] === '?') {
11601 emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
11602 node = parseBogusComment(context);
11603 }
11604 else {
11605 emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
11606 }
11607 }
11608 }
11609 if (!node) {
11610 node = parseText(context, mode);
11611 }
11612 if (isArray(node)) {
11613 for (let i = 0; i < node.length; i++) {
11614 pushNode(nodes, node[i]);
11615 }
11616 }
11617 else {
11618 pushNode(nodes, node);
11619 }
11620 }
11621 // Whitespace handling strategy like v2
11622 let removedWhitespace = false;
11623 if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
11624 const shouldCondense = context.options.whitespace !== 'preserve';
11625 for (let i = 0; i < nodes.length; i++) {
11626 const node = nodes[i];
11627 if (!context.inPre && node.type === 2 /* TEXT */) {
11628 if (!/[^\t\r\n\f ]/.test(node.content)) {
11629 const prev = nodes[i - 1];
11630 const next = nodes[i + 1];
11631 // Remove if:
11632 // - the whitespace is the first or last node, or:
11633 // - (condense mode) the whitespace is adjacent to a comment, or:
11634 // - (condense mode) the whitespace is between two elements AND contains newline
11635 if (!prev ||
11636 !next ||
11637 (shouldCondense &&
11638 (prev.type === 3 /* COMMENT */ ||
11639 next.type === 3 /* COMMENT */ ||
11640 (prev.type === 1 /* ELEMENT */ &&
11641 next.type === 1 /* ELEMENT */ &&
11642 /[\r\n]/.test(node.content))))) {
11643 removedWhitespace = true;
11644 nodes[i] = null;
11645 }
11646 else {
11647 // Otherwise, the whitespace is condensed into a single space
11648 node.content = ' ';
11649 }
11650 }
11651 else if (shouldCondense) {
11652 // in condense mode, consecutive whitespaces in text are condensed
11653 // down to a single space.
11654 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11655 }
11656 }
11657 // Remove comment nodes if desired by configuration.
11658 else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
11659 removedWhitespace = true;
11660 nodes[i] = null;
11661 }
11662 }
11663 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
11664 // remove leading newline per html spec
11665 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
11666 const first = nodes[0];
11667 if (first && first.type === 2 /* TEXT */) {
11668 first.content = first.content.replace(/^\r?\n/, '');
11669 }
11670 }
11671 }
11672 return removedWhitespace ? nodes.filter(Boolean) : nodes;
11673}
11674function pushNode(nodes, node) {
11675 if (node.type === 2 /* TEXT */) {
11676 const prev = last(nodes);
11677 // Merge if both this and the previous node are text and those are
11678 // consecutive. This happens for cases like "a < b".
11679 if (prev &&
11680 prev.type === 2 /* TEXT */ &&
11681 prev.loc.end.offset === node.loc.start.offset) {
11682 prev.content += node.content;
11683 prev.loc.end = node.loc.end;
11684 prev.loc.source += node.loc.source;
11685 return;
11686 }
11687 }
11688 nodes.push(node);
11689}
11690function parseCDATA(context, ancestors) {
11691 advanceBy(context, 9);
11692 const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
11693 if (context.source.length === 0) {
11694 emitError(context, 6 /* EOF_IN_CDATA */);
11695 }
11696 else {
11697 advanceBy(context, 3);
11698 }
11699 return nodes;
11700}
11701function parseComment(context) {
11702 const start = getCursor(context);
11703 let content;
11704 // Regular comment.
11705 const match = /--(\!)?>/.exec(context.source);
11706 if (!match) {
11707 content = context.source.slice(4);
11708 advanceBy(context, context.source.length);
11709 emitError(context, 7 /* EOF_IN_COMMENT */);
11710 }
11711 else {
11712 if (match.index <= 3) {
11713 emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
11714 }
11715 if (match[1]) {
11716 emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
11717 }
11718 content = context.source.slice(4, match.index);
11719 // Advancing with reporting nested comments.
11720 const s = context.source.slice(0, match.index);
11721 let prevIndex = 1, nestedIndex = 0;
11722 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
11723 advanceBy(context, nestedIndex - prevIndex + 1);
11724 if (nestedIndex + 4 < s.length) {
11725 emitError(context, 16 /* NESTED_COMMENT */);
11726 }
11727 prevIndex = nestedIndex + 1;
11728 }
11729 advanceBy(context, match.index + match[0].length - prevIndex + 1);
11730 }
11731 return {
11732 type: 3 /* COMMENT */,
11733 content,
11734 loc: getSelection(context, start)
11735 };
11736}
11737function parseBogusComment(context) {
11738 const start = getCursor(context);
11739 const contentStart = context.source[1] === '?' ? 1 : 2;
11740 let content;
11741 const closeIndex = context.source.indexOf('>');
11742 if (closeIndex === -1) {
11743 content = context.source.slice(contentStart);
11744 advanceBy(context, context.source.length);
11745 }
11746 else {
11747 content = context.source.slice(contentStart, closeIndex);
11748 advanceBy(context, closeIndex + 1);
11749 }
11750 return {
11751 type: 3 /* COMMENT */,
11752 content,
11753 loc: getSelection(context, start)
11754 };
11755}
11756function parseElement(context, ancestors) {
11757 // Start tag.
11758 const wasInPre = context.inPre;
11759 const wasInVPre = context.inVPre;
11760 const parent = last(ancestors);
11761 const element = parseTag(context, 0 /* Start */, parent);
11762 const isPreBoundary = context.inPre && !wasInPre;
11763 const isVPreBoundary = context.inVPre && !wasInVPre;
11764 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
11765 // #4030 self-closing <pre> tag
11766 if (isPreBoundary) {
11767 context.inPre = false;
11768 }
11769 if (isVPreBoundary) {
11770 context.inVPre = false;
11771 }
11772 return element;
11773 }
11774 // Children.
11775 ancestors.push(element);
11776 const mode = context.options.getTextMode(element, parent);
11777 const children = parseChildren(context, mode, ancestors);
11778 ancestors.pop();
11779 element.children = children;
11780 // End tag.
11781 if (startsWithEndTagOpen(context.source, element.tag)) {
11782 parseTag(context, 1 /* End */, parent);
11783 }
11784 else {
11785 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
11786 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
11787 const first = children[0];
11788 if (first && startsWith(first.loc.source, '<!--')) {
11789 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
11790 }
11791 }
11792 }
11793 element.loc = getSelection(context, element.loc.start);
11794 if (isPreBoundary) {
11795 context.inPre = false;
11796 }
11797 if (isVPreBoundary) {
11798 context.inVPre = false;
11799 }
11800 return element;
11801}
11802const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
11803function parseTag(context, type, parent) {
11804 // Tag open.
11805 const start = getCursor(context);
11806 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
11807 const tag = match[1];
11808 const ns = context.options.getNamespace(tag, parent);
11809 advanceBy(context, match[0].length);
11810 advanceSpaces(context);
11811 // save current state in case we need to re-parse attributes with v-pre
11812 const cursor = getCursor(context);
11813 const currentSource = context.source;
11814 // check <pre> tag
11815 if (context.options.isPreTag(tag)) {
11816 context.inPre = true;
11817 }
11818 // Attributes.
11819 let props = parseAttributes(context, type);
11820 // check v-pre
11821 if (type === 0 /* Start */ &&
11822 !context.inVPre &&
11823 props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
11824 context.inVPre = true;
11825 // reset context
11826 extend(context, cursor);
11827 context.source = currentSource;
11828 // re-parse attrs and filter out v-pre itself
11829 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
11830 }
11831 // Tag close.
11832 let isSelfClosing = false;
11833 if (context.source.length === 0) {
11834 emitError(context, 9 /* EOF_IN_TAG */);
11835 }
11836 else {
11837 isSelfClosing = startsWith(context.source, '/>');
11838 if (type === 1 /* End */ && isSelfClosing) {
11839 emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
11840 }
11841 advanceBy(context, isSelfClosing ? 2 : 1);
11842 }
11843 if (type === 1 /* End */) {
11844 return;
11845 }
11846 let tagType = 0 /* ELEMENT */;
11847 if (!context.inVPre) {
11848 if (tag === 'slot') {
11849 tagType = 2 /* SLOT */;
11850 }
11851 else if (tag === 'template') {
11852 if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
11853 tagType = 3 /* TEMPLATE */;
11854 }
11855 }
11856 else if (isComponent(tag, props, context)) {
11857 tagType = 1 /* COMPONENT */;
11858 }
11859 }
11860 return {
11861 type: 1 /* ELEMENT */,
11862 ns,
11863 tag,
11864 tagType,
11865 props,
11866 isSelfClosing,
11867 children: [],
11868 loc: getSelection(context, start),
11869 codegenNode: undefined // to be created during transform phase
11870 };
11871}
11872function isComponent(tag, props, context) {
11873 const options = context.options;
11874 if (options.isCustomElement(tag)) {
11875 return false;
11876 }
11877 if (tag === 'component' ||
11878 /^[A-Z]/.test(tag) ||
11879 isCoreComponent(tag) ||
11880 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
11881 (options.isNativeTag && !options.isNativeTag(tag))) {
11882 return true;
11883 }
11884 // at this point the tag should be a native tag, but check for potential "is"
11885 // casting
11886 for (let i = 0; i < props.length; i++) {
11887 const p = props[i];
11888 if (p.type === 6 /* ATTRIBUTE */) {
11889 if (p.name === 'is' && p.value) {
11890 if (p.value.content.startsWith('vue:')) {
11891 return true;
11892 }
11893 }
11894 }
11895 else {
11896 // directive
11897 // v-is (TODO Deprecate)
11898 if (p.name === 'is') {
11899 return true;
11900 }
11901 else if (
11902 // :is on plain element - only treat as component in compat mode
11903 p.name === 'bind' &&
11904 isBindKey(p.arg, 'is') &&
11905 false &&
11906 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
11907 return true;
11908 }
11909 }
11910 }
11911}
11912function parseAttributes(context, type) {
11913 const props = [];
11914 const attributeNames = new Set();
11915 while (context.source.length > 0 &&
11916 !startsWith(context.source, '>') &&
11917 !startsWith(context.source, '/>')) {
11918 if (startsWith(context.source, '/')) {
11919 emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
11920 advanceBy(context, 1);
11921 advanceSpaces(context);
11922 continue;
11923 }
11924 if (type === 1 /* End */) {
11925 emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
11926 }
11927 const attr = parseAttribute(context, attributeNames);
11928 // Trim whitespace between class
11929 // https://github.com/vuejs/vue-next/issues/4251
11930 if (attr.type === 6 /* ATTRIBUTE */ &&
11931 attr.value &&
11932 attr.name === 'class') {
11933 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
11934 }
11935 if (type === 0 /* Start */) {
11936 props.push(attr);
11937 }
11938 if (/^[^\t\r\n\f />]/.test(context.source)) {
11939 emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
11940 }
11941 advanceSpaces(context);
11942 }
11943 return props;
11944}
11945function parseAttribute(context, nameSet) {
11946 // Name.
11947 const start = getCursor(context);
11948 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
11949 const name = match[0];
11950 if (nameSet.has(name)) {
11951 emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
11952 }
11953 nameSet.add(name);
11954 if (name[0] === '=') {
11955 emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
11956 }
11957 {
11958 const pattern = /["'<]/g;
11959 let m;
11960 while ((m = pattern.exec(name))) {
11961 emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
11962 }
11963 }
11964 advanceBy(context, name.length);
11965 // Value
11966 let value = undefined;
11967 if (/^[\t\r\n\f ]*=/.test(context.source)) {
11968 advanceSpaces(context);
11969 advanceBy(context, 1);
11970 advanceSpaces(context);
11971 value = parseAttributeValue(context);
11972 if (!value) {
11973 emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
11974 }
11975 }
11976 const loc = getSelection(context, start);
11977 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
11978 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
11979 let isPropShorthand = startsWith(name, '.');
11980 let dirName = match[1] ||
11981 (isPropShorthand || startsWith(name, ':')
11982 ? 'bind'
11983 : startsWith(name, '@')
11984 ? 'on'
11985 : 'slot');
11986 let arg;
11987 if (match[2]) {
11988 const isSlot = dirName === 'slot';
11989 const startOffset = name.lastIndexOf(match[2]);
11990 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
11991 let content = match[2];
11992 let isStatic = true;
11993 if (content.startsWith('[')) {
11994 isStatic = false;
11995 if (!content.endsWith(']')) {
11996 emitError(context, 27 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
11997 content = content.substr(1);
11998 }
11999 else {
12000 content = content.substr(1, content.length - 2);
12001 }
12002 }
12003 else if (isSlot) {
12004 // #1241 special case for v-slot: vuetify relies extensively on slot
12005 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
12006 // supports such usage so we are keeping it consistent with 2.x.
12007 content += match[3] || '';
12008 }
12009 arg = {
12010 type: 4 /* SIMPLE_EXPRESSION */,
12011 content,
12012 isStatic,
12013 constType: isStatic
12014 ? 3 /* CAN_STRINGIFY */
12015 : 0 /* NOT_CONSTANT */,
12016 loc
12017 };
12018 }
12019 if (value && value.isQuoted) {
12020 const valueLoc = value.loc;
12021 valueLoc.start.offset++;
12022 valueLoc.start.column++;
12023 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
12024 valueLoc.source = valueLoc.source.slice(1, -1);
12025 }
12026 const modifiers = match[3] ? match[3].substr(1).split('.') : [];
12027 if (isPropShorthand)
12028 modifiers.push('prop');
12029 return {
12030 type: 7 /* DIRECTIVE */,
12031 name: dirName,
12032 exp: value && {
12033 type: 4 /* SIMPLE_EXPRESSION */,
12034 content: value.content,
12035 isStatic: false,
12036 // Treat as non-constant by default. This can be potentially set to
12037 // other values by `transformExpression` to make it eligible for hoisting.
12038 constType: 0 /* NOT_CONSTANT */,
12039 loc: value.loc
12040 },
12041 arg,
12042 modifiers,
12043 loc
12044 };
12045 }
12046 // missing directive name or illegal directive name
12047 if (!context.inVPre && startsWith(name, 'v-')) {
12048 emitError(context, 26 /* X_MISSING_DIRECTIVE_NAME */);
12049 }
12050 return {
12051 type: 6 /* ATTRIBUTE */,
12052 name,
12053 value: value && {
12054 type: 2 /* TEXT */,
12055 content: value.content,
12056 loc: value.loc
12057 },
12058 loc
12059 };
12060}
12061function parseAttributeValue(context) {
12062 const start = getCursor(context);
12063 let content;
12064 const quote = context.source[0];
12065 const isQuoted = quote === `"` || quote === `'`;
12066 if (isQuoted) {
12067 // Quoted value.
12068 advanceBy(context, 1);
12069 const endIndex = context.source.indexOf(quote);
12070 if (endIndex === -1) {
12071 content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
12072 }
12073 else {
12074 content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
12075 advanceBy(context, 1);
12076 }
12077 }
12078 else {
12079 // Unquoted
12080 const match = /^[^\t\r\n\f >]+/.exec(context.source);
12081 if (!match) {
12082 return undefined;
12083 }
12084 const unexpectedChars = /["'<=`]/g;
12085 let m;
12086 while ((m = unexpectedChars.exec(match[0]))) {
12087 emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
12088 }
12089 content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
12090 }
12091 return { content, isQuoted, loc: getSelection(context, start) };
12092}
12093function parseInterpolation(context, mode) {
12094 const [open, close] = context.options.delimiters;
12095 const closeIndex = context.source.indexOf(close, open.length);
12096 if (closeIndex === -1) {
12097 emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
12098 return undefined;
12099 }
12100 const start = getCursor(context);
12101 advanceBy(context, open.length);
12102 const innerStart = getCursor(context);
12103 const innerEnd = getCursor(context);
12104 const rawContentLength = closeIndex - open.length;
12105 const rawContent = context.source.slice(0, rawContentLength);
12106 const preTrimContent = parseTextData(context, rawContentLength, mode);
12107 const content = preTrimContent.trim();
12108 const startOffset = preTrimContent.indexOf(content);
12109 if (startOffset > 0) {
12110 advancePositionWithMutation(innerStart, rawContent, startOffset);
12111 }
12112 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
12113 advancePositionWithMutation(innerEnd, rawContent, endOffset);
12114 advanceBy(context, close.length);
12115 return {
12116 type: 5 /* INTERPOLATION */,
12117 content: {
12118 type: 4 /* SIMPLE_EXPRESSION */,
12119 isStatic: false,
12120 // Set `isConstant` to false by default and will decide in transformExpression
12121 constType: 0 /* NOT_CONSTANT */,
12122 content,
12123 loc: getSelection(context, innerStart, innerEnd)
12124 },
12125 loc: getSelection(context, start)
12126 };
12127}
12128function parseText(context, mode) {
12129 const endTokens = mode === 3 /* CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
12130 let endIndex = context.source.length;
12131 for (let i = 0; i < endTokens.length; i++) {
12132 const index = context.source.indexOf(endTokens[i], 1);
12133 if (index !== -1 && endIndex > index) {
12134 endIndex = index;
12135 }
12136 }
12137 const start = getCursor(context);
12138 const content = parseTextData(context, endIndex, mode);
12139 return {
12140 type: 2 /* TEXT */,
12141 content,
12142 loc: getSelection(context, start)
12143 };
12144}
12145/**
12146 * Get text data with a given length from the current location.
12147 * This translates HTML entities in the text data.
12148 */
12149function parseTextData(context, length, mode) {
12150 const rawText = context.source.slice(0, length);
12151 advanceBy(context, length);
12152 if (mode === 2 /* RAWTEXT */ ||
12153 mode === 3 /* CDATA */ ||
12154 rawText.indexOf('&') === -1) {
12155 return rawText;
12156 }
12157 else {
12158 // DATA or RCDATA containing "&"". Entity decoding required.
12159 return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
12160 }
12161}
12162function getCursor(context) {
12163 const { column, line, offset } = context;
12164 return { column, line, offset };
12165}
12166function getSelection(context, start, end) {
12167 end = end || getCursor(context);
12168 return {
12169 start,
12170 end,
12171 source: context.originalSource.slice(start.offset, end.offset)
12172 };
12173}
12174function last(xs) {
12175 return xs[xs.length - 1];
12176}
12177function startsWith(source, searchString) {
12178 return source.startsWith(searchString);
12179}
12180function advanceBy(context, numberOfCharacters) {
12181 const { source } = context;
12182 advancePositionWithMutation(context, source, numberOfCharacters);
12183 context.source = source.slice(numberOfCharacters);
12184}
12185function advanceSpaces(context) {
12186 const match = /^[\t\r\n\f ]+/.exec(context.source);
12187 if (match) {
12188 advanceBy(context, match[0].length);
12189 }
12190}
12191function getNewPosition(context, start, numberOfCharacters) {
12192 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
12193}
12194function emitError(context, code, offset, loc = getCursor(context)) {
12195 if (offset) {
12196 loc.offset += offset;
12197 loc.column += offset;
12198 }
12199 context.options.onError(createCompilerError(code, {
12200 start: loc,
12201 end: loc,
12202 source: ''
12203 }));
12204}
12205function isEnd(context, mode, ancestors) {
12206 const s = context.source;
12207 switch (mode) {
12208 case 0 /* DATA */:
12209 if (startsWith(s, '</')) {
12210 // TODO: probably bad performance
12211 for (let i = ancestors.length - 1; i >= 0; --i) {
12212 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
12213 return true;
12214 }
12215 }
12216 }
12217 break;
12218 case 1 /* RCDATA */:
12219 case 2 /* RAWTEXT */: {
12220 const parent = last(ancestors);
12221 if (parent && startsWithEndTagOpen(s, parent.tag)) {
12222 return true;
12223 }
12224 break;
12225 }
12226 case 3 /* CDATA */:
12227 if (startsWith(s, ']]>')) {
12228 return true;
12229 }
12230 break;
12231 }
12232 return !s;
12233}
12234function startsWithEndTagOpen(source, tag) {
12235 return (startsWith(source, '</') &&
12236 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
12237 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
12238}
12239
12240function hoistStatic(root, context) {
12241 walk(root, context,
12242 // Root node is unfortunately non-hoistable due to potential parent
12243 // fallthrough attributes.
12244 isSingleElementRoot(root, root.children[0]));
12245}
12246function isSingleElementRoot(root, child) {
12247 const { children } = root;
12248 return (children.length === 1 &&
12249 child.type === 1 /* ELEMENT */ &&
12250 !isSlotOutlet(child));
12251}
12252function walk(node, context, doNotHoistNode = false) {
12253 // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
12254 // static bindings with expressions. These expressions are guaranteed to be
12255 // constant so they are still eligible for hoisting, but they are only
12256 // available at runtime and therefore cannot be evaluated ahead of time.
12257 // This is only a concern for pre-stringification (via transformHoist by
12258 // @vue/compiler-dom), but doing it here allows us to perform only one full
12259 // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
12260 // stringification threshold is met.
12261 let canStringify = true;
12262 const { children } = node;
12263 const originalCount = children.length;
12264 let hoistedCount = 0;
12265 for (let i = 0; i < children.length; i++) {
12266 const child = children[i];
12267 // only plain elements & text calls are eligible for hoisting.
12268 if (child.type === 1 /* ELEMENT */ &&
12269 child.tagType === 0 /* ELEMENT */) {
12270 const constantType = doNotHoistNode
12271 ? 0 /* NOT_CONSTANT */
12272 : getConstantType(child, context);
12273 if (constantType > 0 /* NOT_CONSTANT */) {
12274 if (constantType < 3 /* CAN_STRINGIFY */) {
12275 canStringify = false;
12276 }
12277 if (constantType >= 2 /* CAN_HOIST */) {
12278 child.codegenNode.patchFlag =
12279 -1 /* HOISTED */ + (` /* HOISTED */` );
12280 child.codegenNode = context.hoist(child.codegenNode);
12281 hoistedCount++;
12282 continue;
12283 }
12284 }
12285 else {
12286 // node may contain dynamic children, but its props may be eligible for
12287 // hoisting.
12288 const codegenNode = child.codegenNode;
12289 if (codegenNode.type === 13 /* VNODE_CALL */) {
12290 const flag = getPatchFlag(codegenNode);
12291 if ((!flag ||
12292 flag === 512 /* NEED_PATCH */ ||
12293 flag === 1 /* TEXT */) &&
12294 getGeneratedPropsConstantType(child, context) >=
12295 2 /* CAN_HOIST */) {
12296 const props = getNodeProps(child);
12297 if (props) {
12298 codegenNode.props = context.hoist(props);
12299 }
12300 }
12301 if (codegenNode.dynamicProps) {
12302 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
12303 }
12304 }
12305 }
12306 }
12307 else if (child.type === 12 /* TEXT_CALL */) {
12308 const contentType = getConstantType(child.content, context);
12309 if (contentType > 0) {
12310 if (contentType < 3 /* CAN_STRINGIFY */) {
12311 canStringify = false;
12312 }
12313 if (contentType >= 2 /* CAN_HOIST */) {
12314 child.codegenNode = context.hoist(child.codegenNode);
12315 hoistedCount++;
12316 }
12317 }
12318 }
12319 // walk further
12320 if (child.type === 1 /* ELEMENT */) {
12321 const isComponent = child.tagType === 1 /* COMPONENT */;
12322 if (isComponent) {
12323 context.scopes.vSlot++;
12324 }
12325 walk(child, context);
12326 if (isComponent) {
12327 context.scopes.vSlot--;
12328 }
12329 }
12330 else if (child.type === 11 /* FOR */) {
12331 // Do not hoist v-for single child because it has to be a block
12332 walk(child, context, child.children.length === 1);
12333 }
12334 else if (child.type === 9 /* IF */) {
12335 for (let i = 0; i < child.branches.length; i++) {
12336 // Do not hoist v-if single child because it has to be a block
12337 walk(child.branches[i], context, child.branches[i].children.length === 1);
12338 }
12339 }
12340 }
12341 if (canStringify && hoistedCount && context.transformHoist) {
12342 context.transformHoist(children, context, node);
12343 }
12344 // all children were hoisted - the entire children array is hoistable.
12345 if (hoistedCount &&
12346 hoistedCount === originalCount &&
12347 node.type === 1 /* ELEMENT */ &&
12348 node.tagType === 0 /* ELEMENT */ &&
12349 node.codegenNode &&
12350 node.codegenNode.type === 13 /* VNODE_CALL */ &&
12351 isArray(node.codegenNode.children)) {
12352 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
12353 }
12354}
12355function getConstantType(node, context) {
12356 const { constantCache } = context;
12357 switch (node.type) {
12358 case 1 /* ELEMENT */:
12359 if (node.tagType !== 0 /* ELEMENT */) {
12360 return 0 /* NOT_CONSTANT */;
12361 }
12362 const cached = constantCache.get(node);
12363 if (cached !== undefined) {
12364 return cached;
12365 }
12366 const codegenNode = node.codegenNode;
12367 if (codegenNode.type !== 13 /* VNODE_CALL */) {
12368 return 0 /* NOT_CONSTANT */;
12369 }
12370 const flag = getPatchFlag(codegenNode);
12371 if (!flag) {
12372 let returnType = 3 /* CAN_STRINGIFY */;
12373 // Element itself has no patch flag. However we still need to check:
12374 // 1. Even for a node with no patch flag, it is possible for it to contain
12375 // non-hoistable expressions that refers to scope variables, e.g. compiler
12376 // injected keys or cached event handlers. Therefore we need to always
12377 // check the codegenNode's props to be sure.
12378 const generatedPropsType = getGeneratedPropsConstantType(node, context);
12379 if (generatedPropsType === 0 /* NOT_CONSTANT */) {
12380 constantCache.set(node, 0 /* NOT_CONSTANT */);
12381 return 0 /* NOT_CONSTANT */;
12382 }
12383 if (generatedPropsType < returnType) {
12384 returnType = generatedPropsType;
12385 }
12386 // 2. its children.
12387 for (let i = 0; i < node.children.length; i++) {
12388 const childType = getConstantType(node.children[i], context);
12389 if (childType === 0 /* NOT_CONSTANT */) {
12390 constantCache.set(node, 0 /* NOT_CONSTANT */);
12391 return 0 /* NOT_CONSTANT */;
12392 }
12393 if (childType < returnType) {
12394 returnType = childType;
12395 }
12396 }
12397 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
12398 // type, check if any of the props can cause the type to be lowered
12399 // we can skip can_patch because it's guaranteed by the absence of a
12400 // patchFlag.
12401 if (returnType > 1 /* CAN_SKIP_PATCH */) {
12402 for (let i = 0; i < node.props.length; i++) {
12403 const p = node.props[i];
12404 if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
12405 const expType = getConstantType(p.exp, context);
12406 if (expType === 0 /* NOT_CONSTANT */) {
12407 constantCache.set(node, 0 /* NOT_CONSTANT */);
12408 return 0 /* NOT_CONSTANT */;
12409 }
12410 if (expType < returnType) {
12411 returnType = expType;
12412 }
12413 }
12414 }
12415 }
12416 // only svg/foreignObject could be block here, however if they are
12417 // static then they don't need to be blocks since there will be no
12418 // nested updates.
12419 if (codegenNode.isBlock) {
12420 context.removeHelper(OPEN_BLOCK);
12421 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
12422 codegenNode.isBlock = false;
12423 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
12424 }
12425 constantCache.set(node, returnType);
12426 return returnType;
12427 }
12428 else {
12429 constantCache.set(node, 0 /* NOT_CONSTANT */);
12430 return 0 /* NOT_CONSTANT */;
12431 }
12432 case 2 /* TEXT */:
12433 case 3 /* COMMENT */:
12434 return 3 /* CAN_STRINGIFY */;
12435 case 9 /* IF */:
12436 case 11 /* FOR */:
12437 case 10 /* IF_BRANCH */:
12438 return 0 /* NOT_CONSTANT */;
12439 case 5 /* INTERPOLATION */:
12440 case 12 /* TEXT_CALL */:
12441 return getConstantType(node.content, context);
12442 case 4 /* SIMPLE_EXPRESSION */:
12443 return node.constType;
12444 case 8 /* COMPOUND_EXPRESSION */:
12445 let returnType = 3 /* CAN_STRINGIFY */;
12446 for (let i = 0; i < node.children.length; i++) {
12447 const child = node.children[i];
12448 if (isString(child) || isSymbol(child)) {
12449 continue;
12450 }
12451 const childType = getConstantType(child, context);
12452 if (childType === 0 /* NOT_CONSTANT */) {
12453 return 0 /* NOT_CONSTANT */;
12454 }
12455 else if (childType < returnType) {
12456 returnType = childType;
12457 }
12458 }
12459 return returnType;
12460 default:
12461 return 0 /* NOT_CONSTANT */;
12462 }
12463}
12464const allowHoistedHelperSet = new Set([
12465 NORMALIZE_CLASS,
12466 NORMALIZE_STYLE,
12467 NORMALIZE_PROPS,
12468 GUARD_REACTIVE_PROPS
12469]);
12470function getConstantTypeOfHelperCall(value, context) {
12471 if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
12472 !isString(value.callee) &&
12473 allowHoistedHelperSet.has(value.callee)) {
12474 const arg = value.arguments[0];
12475 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
12476 return getConstantType(arg, context);
12477 }
12478 else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
12479 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
12480 return getConstantTypeOfHelperCall(arg, context);
12481 }
12482 }
12483 return 0 /* NOT_CONSTANT */;
12484}
12485function getGeneratedPropsConstantType(node, context) {
12486 let returnType = 3 /* CAN_STRINGIFY */;
12487 const props = getNodeProps(node);
12488 if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
12489 const { properties } = props;
12490 for (let i = 0; i < properties.length; i++) {
12491 const { key, value } = properties[i];
12492 const keyType = getConstantType(key, context);
12493 if (keyType === 0 /* NOT_CONSTANT */) {
12494 return keyType;
12495 }
12496 if (keyType < returnType) {
12497 returnType = keyType;
12498 }
12499 let valueType;
12500 if (value.type === 4 /* SIMPLE_EXPRESSION */) {
12501 valueType = getConstantType(value, context);
12502 }
12503 else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12504 // some helper calls can be hoisted,
12505 // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12506 // in this case we need to respect the ConstantType of the helper's argments
12507 valueType = getConstantTypeOfHelperCall(value, context);
12508 }
12509 else {
12510 valueType = 0 /* NOT_CONSTANT */;
12511 }
12512 if (valueType === 0 /* NOT_CONSTANT */) {
12513 return valueType;
12514 }
12515 if (valueType < returnType) {
12516 returnType = valueType;
12517 }
12518 }
12519 }
12520 return returnType;
12521}
12522function getNodeProps(node) {
12523 const codegenNode = node.codegenNode;
12524 if (codegenNode.type === 13 /* VNODE_CALL */) {
12525 return codegenNode.props;
12526 }
12527}
12528function getPatchFlag(node) {
12529 const flag = node.patchFlag;
12530 return flag ? parseInt(flag, 10) : undefined;
12531}
12532
12533function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = NOOP, isCustomElement = NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
12534 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
12535 const context = {
12536 // options
12537 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
12538 prefixIdentifiers,
12539 hoistStatic,
12540 cacheHandlers,
12541 nodeTransforms,
12542 directiveTransforms,
12543 transformHoist,
12544 isBuiltInComponent,
12545 isCustomElement,
12546 expressionPlugins,
12547 scopeId,
12548 slotted,
12549 ssr,
12550 inSSR,
12551 ssrCssVars,
12552 bindingMetadata,
12553 inline,
12554 isTS,
12555 onError,
12556 onWarn,
12557 compatConfig,
12558 // state
12559 root,
12560 helpers: new Map(),
12561 components: new Set(),
12562 directives: new Set(),
12563 hoists: [],
12564 imports: [],
12565 constantCache: new Map(),
12566 temps: 0,
12567 cached: 0,
12568 identifiers: Object.create(null),
12569 scopes: {
12570 vFor: 0,
12571 vSlot: 0,
12572 vPre: 0,
12573 vOnce: 0
12574 },
12575 parent: null,
12576 currentNode: root,
12577 childIndex: 0,
12578 inVOnce: false,
12579 // methods
12580 helper(name) {
12581 const count = context.helpers.get(name) || 0;
12582 context.helpers.set(name, count + 1);
12583 return name;
12584 },
12585 removeHelper(name) {
12586 const count = context.helpers.get(name);
12587 if (count) {
12588 const currentCount = count - 1;
12589 if (!currentCount) {
12590 context.helpers.delete(name);
12591 }
12592 else {
12593 context.helpers.set(name, currentCount);
12594 }
12595 }
12596 },
12597 helperString(name) {
12598 return `_${helperNameMap[context.helper(name)]}`;
12599 },
12600 replaceNode(node) {
12601 /* istanbul ignore if */
12602 {
12603 if (!context.currentNode) {
12604 throw new Error(`Node being replaced is already removed.`);
12605 }
12606 if (!context.parent) {
12607 throw new Error(`Cannot replace root node.`);
12608 }
12609 }
12610 context.parent.children[context.childIndex] = context.currentNode = node;
12611 },
12612 removeNode(node) {
12613 if (!context.parent) {
12614 throw new Error(`Cannot remove root node.`);
12615 }
12616 const list = context.parent.children;
12617 const removalIndex = node
12618 ? list.indexOf(node)
12619 : context.currentNode
12620 ? context.childIndex
12621 : -1;
12622 /* istanbul ignore if */
12623 if (removalIndex < 0) {
12624 throw new Error(`node being removed is not a child of current parent`);
12625 }
12626 if (!node || node === context.currentNode) {
12627 // current node removed
12628 context.currentNode = null;
12629 context.onNodeRemoved();
12630 }
12631 else {
12632 // sibling node removed
12633 if (context.childIndex > removalIndex) {
12634 context.childIndex--;
12635 context.onNodeRemoved();
12636 }
12637 }
12638 context.parent.children.splice(removalIndex, 1);
12639 },
12640 onNodeRemoved: () => { },
12641 addIdentifiers(exp) {
12642 },
12643 removeIdentifiers(exp) {
12644 },
12645 hoist(exp) {
12646 if (isString(exp))
12647 exp = createSimpleExpression(exp);
12648 context.hoists.push(exp);
12649 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
12650 identifier.hoisted = exp;
12651 return identifier;
12652 },
12653 cache(exp, isVNode = false) {
12654 return createCacheExpression(context.cached++, exp, isVNode);
12655 }
12656 };
12657 return context;
12658}
12659function transform(root, options) {
12660 const context = createTransformContext(root, options);
12661 traverseNode(root, context);
12662 if (options.hoistStatic) {
12663 hoistStatic(root, context);
12664 }
12665 if (!options.ssr) {
12666 createRootCodegen(root, context);
12667 }
12668 // finalize meta information
12669 root.helpers = [...context.helpers.keys()];
12670 root.components = [...context.components];
12671 root.directives = [...context.directives];
12672 root.imports = context.imports;
12673 root.hoists = context.hoists;
12674 root.temps = context.temps;
12675 root.cached = context.cached;
12676}
12677function createRootCodegen(root, context) {
12678 const { helper } = context;
12679 const { children } = root;
12680 if (children.length === 1) {
12681 const child = children[0];
12682 // if the single child is an element, turn it into a block.
12683 if (isSingleElementRoot(root, child) && child.codegenNode) {
12684 // single element root is never hoisted so codegenNode will never be
12685 // SimpleExpressionNode
12686 const codegenNode = child.codegenNode;
12687 if (codegenNode.type === 13 /* VNODE_CALL */) {
12688 makeBlock(codegenNode, context);
12689 }
12690 root.codegenNode = codegenNode;
12691 }
12692 else {
12693 // - single <slot/>, IfNode, ForNode: already blocks.
12694 // - single text node: always patched.
12695 // root codegen falls through via genNode()
12696 root.codegenNode = child;
12697 }
12698 }
12699 else if (children.length > 1) {
12700 // root has multiple nodes - return a fragment block.
12701 let patchFlag = 64 /* STABLE_FRAGMENT */;
12702 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
12703 // check if the fragment actually contains a single valid child with
12704 // the rest being comments
12705 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
12706 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
12707 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
12708 }
12709 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);
12710 }
12711 else ;
12712}
12713function traverseChildren(parent, context) {
12714 let i = 0;
12715 const nodeRemoved = () => {
12716 i--;
12717 };
12718 for (; i < parent.children.length; i++) {
12719 const child = parent.children[i];
12720 if (isString(child))
12721 continue;
12722 context.parent = parent;
12723 context.childIndex = i;
12724 context.onNodeRemoved = nodeRemoved;
12725 traverseNode(child, context);
12726 }
12727}
12728function traverseNode(node, context) {
12729 context.currentNode = node;
12730 // apply transform plugins
12731 const { nodeTransforms } = context;
12732 const exitFns = [];
12733 for (let i = 0; i < nodeTransforms.length; i++) {
12734 const onExit = nodeTransforms[i](node, context);
12735 if (onExit) {
12736 if (isArray(onExit)) {
12737 exitFns.push(...onExit);
12738 }
12739 else {
12740 exitFns.push(onExit);
12741 }
12742 }
12743 if (!context.currentNode) {
12744 // node was removed
12745 return;
12746 }
12747 else {
12748 // node may have been replaced
12749 node = context.currentNode;
12750 }
12751 }
12752 switch (node.type) {
12753 case 3 /* COMMENT */:
12754 if (!context.ssr) {
12755 // inject import for the Comment symbol, which is needed for creating
12756 // comment nodes with `createVNode`
12757 context.helper(CREATE_COMMENT);
12758 }
12759 break;
12760 case 5 /* INTERPOLATION */:
12761 // no need to traverse, but we need to inject toString helper
12762 if (!context.ssr) {
12763 context.helper(TO_DISPLAY_STRING);
12764 }
12765 break;
12766 // for container types, further traverse downwards
12767 case 9 /* IF */:
12768 for (let i = 0; i < node.branches.length; i++) {
12769 traverseNode(node.branches[i], context);
12770 }
12771 break;
12772 case 10 /* IF_BRANCH */:
12773 case 11 /* FOR */:
12774 case 1 /* ELEMENT */:
12775 case 0 /* ROOT */:
12776 traverseChildren(node, context);
12777 break;
12778 }
12779 // exit transforms
12780 context.currentNode = node;
12781 let i = exitFns.length;
12782 while (i--) {
12783 exitFns[i]();
12784 }
12785}
12786function createStructuralDirectiveTransform(name, fn) {
12787 const matches = isString(name)
12788 ? (n) => n === name
12789 : (n) => name.test(n);
12790 return (node, context) => {
12791 if (node.type === 1 /* ELEMENT */) {
12792 const { props } = node;
12793 // structural directive transforms are not concerned with slots
12794 // as they are handled separately in vSlot.ts
12795 if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
12796 return;
12797 }
12798 const exitFns = [];
12799 for (let i = 0; i < props.length; i++) {
12800 const prop = props[i];
12801 if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
12802 // structural directives are removed to avoid infinite recursion
12803 // also we remove them *before* applying so that it can further
12804 // traverse itself in case it moves the node around
12805 props.splice(i, 1);
12806 i--;
12807 const onExit = fn(node, prop, context);
12808 if (onExit)
12809 exitFns.push(onExit);
12810 }
12811 }
12812 return exitFns;
12813 }
12814 };
12815}
12816
12817const PURE_ANNOTATION = `/*#__PURE__*/`;
12818function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {
12819 const context = {
12820 mode,
12821 prefixIdentifiers,
12822 sourceMap,
12823 filename,
12824 scopeId,
12825 optimizeImports,
12826 runtimeGlobalName,
12827 runtimeModuleName,
12828 ssrRuntimeModuleName,
12829 ssr,
12830 isTS,
12831 inSSR,
12832 source: ast.loc.source,
12833 code: ``,
12834 column: 1,
12835 line: 1,
12836 offset: 0,
12837 indentLevel: 0,
12838 pure: false,
12839 map: undefined,
12840 helper(key) {
12841 return `_${helperNameMap[key]}`;
12842 },
12843 push(code, node) {
12844 context.code += code;
12845 },
12846 indent() {
12847 newline(++context.indentLevel);
12848 },
12849 deindent(withoutNewLine = false) {
12850 if (withoutNewLine) {
12851 --context.indentLevel;
12852 }
12853 else {
12854 newline(--context.indentLevel);
12855 }
12856 },
12857 newline() {
12858 newline(context.indentLevel);
12859 }
12860 };
12861 function newline(n) {
12862 context.push('\n' + ` `.repeat(n));
12863 }
12864 return context;
12865}
12866function generate(ast, options = {}) {
12867 const context = createCodegenContext(ast, options);
12868 if (options.onContextCreated)
12869 options.onContextCreated(context);
12870 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
12871 const hasHelpers = ast.helpers.length > 0;
12872 const useWithBlock = !prefixIdentifiers && mode !== 'module';
12873 // preambles
12874 // in setup() inline mode, the preamble is generated in a sub context
12875 // and returned separately.
12876 const preambleContext = context;
12877 {
12878 genFunctionPreamble(ast, preambleContext);
12879 }
12880 // enter render function
12881 const functionName = ssr ? `ssrRender` : `render`;
12882 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
12883 const signature = args.join(', ');
12884 {
12885 push(`function ${functionName}(${signature}) {`);
12886 }
12887 indent();
12888 if (useWithBlock) {
12889 push(`with (_ctx) {`);
12890 indent();
12891 // function mode const declarations should be inside with block
12892 // also they should be renamed to avoid collision with user properties
12893 if (hasHelpers) {
12894 push(`const { ${ast.helpers
12895 .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
12896 .join(', ')} } = _Vue`);
12897 push(`\n`);
12898 newline();
12899 }
12900 }
12901 // generate asset resolution statements
12902 if (ast.components.length) {
12903 genAssets(ast.components, 'component', context);
12904 if (ast.directives.length || ast.temps > 0) {
12905 newline();
12906 }
12907 }
12908 if (ast.directives.length) {
12909 genAssets(ast.directives, 'directive', context);
12910 if (ast.temps > 0) {
12911 newline();
12912 }
12913 }
12914 if (ast.temps > 0) {
12915 push(`let `);
12916 for (let i = 0; i < ast.temps; i++) {
12917 push(`${i > 0 ? `, ` : ``}_temp${i}`);
12918 }
12919 }
12920 if (ast.components.length || ast.directives.length || ast.temps) {
12921 push(`\n`);
12922 newline();
12923 }
12924 // generate the VNode tree expression
12925 if (!ssr) {
12926 push(`return `);
12927 }
12928 if (ast.codegenNode) {
12929 genNode(ast.codegenNode, context);
12930 }
12931 else {
12932 push(`null`);
12933 }
12934 if (useWithBlock) {
12935 deindent();
12936 push(`}`);
12937 }
12938 deindent();
12939 push(`}`);
12940 return {
12941 ast,
12942 code: context.code,
12943 preamble: ``,
12944 // SourceMapGenerator does have toJSON() method but it's not in the types
12945 map: context.map ? context.map.toJSON() : undefined
12946 };
12947}
12948function genFunctionPreamble(ast, context) {
12949 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
12950 const VueBinding = runtimeGlobalName;
12951 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
12952 // Generate const declaration for helpers
12953 // In prefix mode, we place the const declaration at top so it's done
12954 // only once; But if we not prefixing, we place the declaration inside the
12955 // with block so it doesn't incur the `in` check cost for every helper access.
12956 if (ast.helpers.length > 0) {
12957 {
12958 // "with" mode.
12959 // save Vue in a separate variable to avoid collision
12960 push(`const _Vue = ${VueBinding}\n`);
12961 // in "with" mode, helpers are declared inside the with block to avoid
12962 // has check cost, but hoists are lifted out of the function - we need
12963 // to provide the helper here.
12964 if (ast.hoists.length) {
12965 const staticHelpers = [
12966 CREATE_VNODE,
12967 CREATE_ELEMENT_VNODE,
12968 CREATE_COMMENT,
12969 CREATE_TEXT,
12970 CREATE_STATIC
12971 ]
12972 .filter(helper => ast.helpers.includes(helper))
12973 .map(aliasHelper)
12974 .join(', ');
12975 push(`const { ${staticHelpers} } = _Vue\n`);
12976 }
12977 }
12978 }
12979 genHoists(ast.hoists, context);
12980 newline();
12981 push(`return `);
12982}
12983function genAssets(assets, type, { helper, push, newline, isTS }) {
12984 const resolver = helper(type === 'component'
12985 ? RESOLVE_COMPONENT
12986 : RESOLVE_DIRECTIVE);
12987 for (let i = 0; i < assets.length; i++) {
12988 let id = assets[i];
12989 // potential component implicit self-reference inferred from SFC filename
12990 const maybeSelfReference = id.endsWith('__self');
12991 if (maybeSelfReference) {
12992 id = id.slice(0, -6);
12993 }
12994 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
12995 if (i < assets.length - 1) {
12996 newline();
12997 }
12998 }
12999}
13000function genHoists(hoists, context) {
13001 if (!hoists.length) {
13002 return;
13003 }
13004 context.pure = true;
13005 const { push, newline, helper, scopeId, mode } = context;
13006 newline();
13007 for (let i = 0; i < hoists.length; i++) {
13008 const exp = hoists[i];
13009 if (exp) {
13010 push(`const _hoisted_${i + 1} = ${``}`);
13011 genNode(exp, context);
13012 newline();
13013 }
13014 }
13015 context.pure = false;
13016}
13017function isText$1(n) {
13018 return (isString(n) ||
13019 n.type === 4 /* SIMPLE_EXPRESSION */ ||
13020 n.type === 2 /* TEXT */ ||
13021 n.type === 5 /* INTERPOLATION */ ||
13022 n.type === 8 /* COMPOUND_EXPRESSION */);
13023}
13024function genNodeListAsArray(nodes, context) {
13025 const multilines = nodes.length > 3 ||
13026 (nodes.some(n => isArray(n) || !isText$1(n)));
13027 context.push(`[`);
13028 multilines && context.indent();
13029 genNodeList(nodes, context, multilines);
13030 multilines && context.deindent();
13031 context.push(`]`);
13032}
13033function genNodeList(nodes, context, multilines = false, comma = true) {
13034 const { push, newline } = context;
13035 for (let i = 0; i < nodes.length; i++) {
13036 const node = nodes[i];
13037 if (isString(node)) {
13038 push(node);
13039 }
13040 else if (isArray(node)) {
13041 genNodeListAsArray(node, context);
13042 }
13043 else {
13044 genNode(node, context);
13045 }
13046 if (i < nodes.length - 1) {
13047 if (multilines) {
13048 comma && push(',');
13049 newline();
13050 }
13051 else {
13052 comma && push(', ');
13053 }
13054 }
13055 }
13056}
13057function genNode(node, context) {
13058 if (isString(node)) {
13059 context.push(node);
13060 return;
13061 }
13062 if (isSymbol(node)) {
13063 context.push(context.helper(node));
13064 return;
13065 }
13066 switch (node.type) {
13067 case 1 /* ELEMENT */:
13068 case 9 /* IF */:
13069 case 11 /* FOR */:
13070 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
13071 `Apply appropriate transforms first.`);
13072 genNode(node.codegenNode, context);
13073 break;
13074 case 2 /* TEXT */:
13075 genText(node, context);
13076 break;
13077 case 4 /* SIMPLE_EXPRESSION */:
13078 genExpression(node, context);
13079 break;
13080 case 5 /* INTERPOLATION */:
13081 genInterpolation(node, context);
13082 break;
13083 case 12 /* TEXT_CALL */:
13084 genNode(node.codegenNode, context);
13085 break;
13086 case 8 /* COMPOUND_EXPRESSION */:
13087 genCompoundExpression(node, context);
13088 break;
13089 case 3 /* COMMENT */:
13090 genComment(node, context);
13091 break;
13092 case 13 /* VNODE_CALL */:
13093 genVNodeCall(node, context);
13094 break;
13095 case 14 /* JS_CALL_EXPRESSION */:
13096 genCallExpression(node, context);
13097 break;
13098 case 15 /* JS_OBJECT_EXPRESSION */:
13099 genObjectExpression(node, context);
13100 break;
13101 case 17 /* JS_ARRAY_EXPRESSION */:
13102 genArrayExpression(node, context);
13103 break;
13104 case 18 /* JS_FUNCTION_EXPRESSION */:
13105 genFunctionExpression(node, context);
13106 break;
13107 case 19 /* JS_CONDITIONAL_EXPRESSION */:
13108 genConditionalExpression(node, context);
13109 break;
13110 case 20 /* JS_CACHE_EXPRESSION */:
13111 genCacheExpression(node, context);
13112 break;
13113 case 21 /* JS_BLOCK_STATEMENT */:
13114 genNodeList(node.body, context, true, false);
13115 break;
13116 // SSR only types
13117 case 22 /* JS_TEMPLATE_LITERAL */:
13118 break;
13119 case 23 /* JS_IF_STATEMENT */:
13120 break;
13121 case 24 /* JS_ASSIGNMENT_EXPRESSION */:
13122 break;
13123 case 25 /* JS_SEQUENCE_EXPRESSION */:
13124 break;
13125 case 26 /* JS_RETURN_STATEMENT */:
13126 break;
13127 /* istanbul ignore next */
13128 case 10 /* IF_BRANCH */:
13129 // noop
13130 break;
13131 default:
13132 {
13133 assert(false, `unhandled codegen node type: ${node.type}`);
13134 // make sure we exhaust all possible types
13135 const exhaustiveCheck = node;
13136 return exhaustiveCheck;
13137 }
13138 }
13139}
13140function genText(node, context) {
13141 context.push(JSON.stringify(node.content), node);
13142}
13143function genExpression(node, context) {
13144 const { content, isStatic } = node;
13145 context.push(isStatic ? JSON.stringify(content) : content, node);
13146}
13147function genInterpolation(node, context) {
13148 const { push, helper, pure } = context;
13149 if (pure)
13150 push(PURE_ANNOTATION);
13151 push(`${helper(TO_DISPLAY_STRING)}(`);
13152 genNode(node.content, context);
13153 push(`)`);
13154}
13155function genCompoundExpression(node, context) {
13156 for (let i = 0; i < node.children.length; i++) {
13157 const child = node.children[i];
13158 if (isString(child)) {
13159 context.push(child);
13160 }
13161 else {
13162 genNode(child, context);
13163 }
13164 }
13165}
13166function genExpressionAsPropertyKey(node, context) {
13167 const { push } = context;
13168 if (node.type === 8 /* COMPOUND_EXPRESSION */) {
13169 push(`[`);
13170 genCompoundExpression(node, context);
13171 push(`]`);
13172 }
13173 else if (node.isStatic) {
13174 // only quote keys if necessary
13175 const text = isSimpleIdentifier(node.content)
13176 ? node.content
13177 : JSON.stringify(node.content);
13178 push(text, node);
13179 }
13180 else {
13181 push(`[${node.content}]`, node);
13182 }
13183}
13184function genComment(node, context) {
13185 const { push, helper, pure } = context;
13186 if (pure) {
13187 push(PURE_ANNOTATION);
13188 }
13189 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
13190}
13191function genVNodeCall(node, context) {
13192 const { push, helper, pure } = context;
13193 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
13194 if (directives) {
13195 push(helper(WITH_DIRECTIVES) + `(`);
13196 }
13197 if (isBlock) {
13198 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
13199 }
13200 if (pure) {
13201 push(PURE_ANNOTATION);
13202 }
13203 const callHelper = isBlock
13204 ? getVNodeBlockHelper(context.inSSR, isComponent)
13205 : getVNodeHelper(context.inSSR, isComponent);
13206 push(helper(callHelper) + `(`, node);
13207 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
13208 push(`)`);
13209 if (isBlock) {
13210 push(`)`);
13211 }
13212 if (directives) {
13213 push(`, `);
13214 genNode(directives, context);
13215 push(`)`);
13216 }
13217}
13218function genNullableArgs(args) {
13219 let i = args.length;
13220 while (i--) {
13221 if (args[i] != null)
13222 break;
13223 }
13224 return args.slice(0, i + 1).map(arg => arg || `null`);
13225}
13226// JavaScript
13227function genCallExpression(node, context) {
13228 const { push, helper, pure } = context;
13229 const callee = isString(node.callee) ? node.callee : helper(node.callee);
13230 if (pure) {
13231 push(PURE_ANNOTATION);
13232 }
13233 push(callee + `(`, node);
13234 genNodeList(node.arguments, context);
13235 push(`)`);
13236}
13237function genObjectExpression(node, context) {
13238 const { push, indent, deindent, newline } = context;
13239 const { properties } = node;
13240 if (!properties.length) {
13241 push(`{}`, node);
13242 return;
13243 }
13244 const multilines = properties.length > 1 ||
13245 (properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
13246 push(multilines ? `{` : `{ `);
13247 multilines && indent();
13248 for (let i = 0; i < properties.length; i++) {
13249 const { key, value } = properties[i];
13250 // key
13251 genExpressionAsPropertyKey(key, context);
13252 push(`: `);
13253 // value
13254 genNode(value, context);
13255 if (i < properties.length - 1) {
13256 // will only reach this if it's multilines
13257 push(`,`);
13258 newline();
13259 }
13260 }
13261 multilines && deindent();
13262 push(multilines ? `}` : ` }`);
13263}
13264function genArrayExpression(node, context) {
13265 genNodeListAsArray(node.elements, context);
13266}
13267function genFunctionExpression(node, context) {
13268 const { push, indent, deindent } = context;
13269 const { params, returns, body, newline, isSlot } = node;
13270 if (isSlot) {
13271 // wrap slot functions with owner context
13272 push(`_${helperNameMap[WITH_CTX]}(`);
13273 }
13274 push(`(`, node);
13275 if (isArray(params)) {
13276 genNodeList(params, context);
13277 }
13278 else if (params) {
13279 genNode(params, context);
13280 }
13281 push(`) => `);
13282 if (newline || body) {
13283 push(`{`);
13284 indent();
13285 }
13286 if (returns) {
13287 if (newline) {
13288 push(`return `);
13289 }
13290 if (isArray(returns)) {
13291 genNodeListAsArray(returns, context);
13292 }
13293 else {
13294 genNode(returns, context);
13295 }
13296 }
13297 else if (body) {
13298 genNode(body, context);
13299 }
13300 if (newline || body) {
13301 deindent();
13302 push(`}`);
13303 }
13304 if (isSlot) {
13305 push(`)`);
13306 }
13307}
13308function genConditionalExpression(node, context) {
13309 const { test, consequent, alternate, newline: needNewline } = node;
13310 const { push, indent, deindent, newline } = context;
13311 if (test.type === 4 /* SIMPLE_EXPRESSION */) {
13312 const needsParens = !isSimpleIdentifier(test.content);
13313 needsParens && push(`(`);
13314 genExpression(test, context);
13315 needsParens && push(`)`);
13316 }
13317 else {
13318 push(`(`);
13319 genNode(test, context);
13320 push(`)`);
13321 }
13322 needNewline && indent();
13323 context.indentLevel++;
13324 needNewline || push(` `);
13325 push(`? `);
13326 genNode(consequent, context);
13327 context.indentLevel--;
13328 needNewline && newline();
13329 needNewline || push(` `);
13330 push(`: `);
13331 const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
13332 if (!isNested) {
13333 context.indentLevel++;
13334 }
13335 genNode(alternate, context);
13336 if (!isNested) {
13337 context.indentLevel--;
13338 }
13339 needNewline && deindent(true /* without newline */);
13340}
13341function genCacheExpression(node, context) {
13342 const { push, helper, indent, deindent, newline } = context;
13343 push(`_cache[${node.index}] || (`);
13344 if (node.isVNode) {
13345 indent();
13346 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
13347 newline();
13348 }
13349 push(`_cache[${node.index}] = `);
13350 genNode(node.value, context);
13351 if (node.isVNode) {
13352 push(`,`);
13353 newline();
13354 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
13355 newline();
13356 push(`_cache[${node.index}]`);
13357 deindent();
13358 }
13359 push(`)`);
13360}
13361
13362// these keywords should not appear inside expressions, but operators like
13363// typeof, instanceof and in are allowed
13364const prohibitedKeywordRE = new RegExp('\\b' +
13365 ('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
13366 'super,throw,while,yield,delete,export,import,return,switch,default,' +
13367 'extends,finally,continue,debugger,function,arguments,typeof,void')
13368 .split(',')
13369 .join('\\b|\\b') +
13370 '\\b');
13371// strip strings in expressions
13372const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
13373/**
13374 * Validate a non-prefixed expression.
13375 * This is only called when using the in-browser runtime compiler since it
13376 * doesn't prefix expressions.
13377 */
13378function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
13379 const exp = node.content;
13380 // empty expressions are validated per-directive since some directives
13381 // do allow empty expressions.
13382 if (!exp.trim()) {
13383 return;
13384 }
13385 try {
13386 new Function(asRawStatements
13387 ? ` ${exp} `
13388 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
13389 }
13390 catch (e) {
13391 let message = e.message;
13392 const keywordMatch = exp
13393 .replace(stripStringRE, '')
13394 .match(prohibitedKeywordRE);
13395 if (keywordMatch) {
13396 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
13397 }
13398 context.onError(createCompilerError(44 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
13399 }
13400}
13401
13402const transformExpression = (node, context) => {
13403 if (node.type === 5 /* INTERPOLATION */) {
13404 node.content = processExpression(node.content, context);
13405 }
13406 else if (node.type === 1 /* ELEMENT */) {
13407 // handle directives on element
13408 for (let i = 0; i < node.props.length; i++) {
13409 const dir = node.props[i];
13410 // do not process for v-on & v-for since they are special handled
13411 if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
13412 const exp = dir.exp;
13413 const arg = dir.arg;
13414 // do not process exp if this is v-on:arg - we need special handling
13415 // for wrapping inline statements.
13416 if (exp &&
13417 exp.type === 4 /* SIMPLE_EXPRESSION */ &&
13418 !(dir.name === 'on' && arg)) {
13419 dir.exp = processExpression(exp, context,
13420 // slot args must be processed as function params
13421 dir.name === 'slot');
13422 }
13423 if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
13424 dir.arg = processExpression(arg, context);
13425 }
13426 }
13427 }
13428 }
13429};
13430// Important: since this function uses Node.js only dependencies, it should
13431// always be used with a leading !true check so that it can be
13432// tree-shaken from the browser build.
13433function processExpression(node, context,
13434// some expressions like v-slot props & v-for aliases should be parsed as
13435// function params
13436asParams = false,
13437// v-on handler values may contain multiple statements
13438asRawStatements = false, localVars = Object.create(context.identifiers)) {
13439 {
13440 {
13441 // simple in-browser validation (same logic in 2.x)
13442 validateBrowserExpression(node, context, asParams, asRawStatements);
13443 }
13444 return node;
13445 }
13446}
13447
13448const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
13449 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
13450 // #1587: We need to dynamically increment the key based on the current
13451 // node's sibling nodes, since chained v-if/else branches are
13452 // rendered at the same depth
13453 const siblings = context.parent.children;
13454 let i = siblings.indexOf(ifNode);
13455 let key = 0;
13456 while (i-- >= 0) {
13457 const sibling = siblings[i];
13458 if (sibling && sibling.type === 9 /* IF */) {
13459 key += sibling.branches.length;
13460 }
13461 }
13462 // Exit callback. Complete the codegenNode when all children have been
13463 // transformed.
13464 return () => {
13465 if (isRoot) {
13466 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
13467 }
13468 else {
13469 // attach this branch's codegen node to the v-if root.
13470 const parentCondition = getParentCondition(ifNode.codegenNode);
13471 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
13472 }
13473 };
13474 });
13475});
13476// target-agnostic transform used for both Client and SSR
13477function processIf(node, dir, context, processCodegen) {
13478 if (dir.name !== 'else' &&
13479 (!dir.exp || !dir.exp.content.trim())) {
13480 const loc = dir.exp ? dir.exp.loc : node.loc;
13481 context.onError(createCompilerError(28 /* X_V_IF_NO_EXPRESSION */, dir.loc));
13482 dir.exp = createSimpleExpression(`true`, false, loc);
13483 }
13484 if (dir.exp) {
13485 validateBrowserExpression(dir.exp, context);
13486 }
13487 if (dir.name === 'if') {
13488 const branch = createIfBranch(node, dir);
13489 const ifNode = {
13490 type: 9 /* IF */,
13491 loc: node.loc,
13492 branches: [branch]
13493 };
13494 context.replaceNode(ifNode);
13495 if (processCodegen) {
13496 return processCodegen(ifNode, branch, true);
13497 }
13498 }
13499 else {
13500 // locate the adjacent v-if
13501 const siblings = context.parent.children;
13502 const comments = [];
13503 let i = siblings.indexOf(node);
13504 while (i-- >= -1) {
13505 const sibling = siblings[i];
13506 if (sibling && sibling.type === 3 /* COMMENT */) {
13507 context.removeNode(sibling);
13508 comments.unshift(sibling);
13509 continue;
13510 }
13511 if (sibling &&
13512 sibling.type === 2 /* TEXT */ &&
13513 !sibling.content.trim().length) {
13514 context.removeNode(sibling);
13515 continue;
13516 }
13517 if (sibling && sibling.type === 9 /* IF */) {
13518 // Check if v-else was followed by v-else-if
13519 if (dir.name === 'else-if' &&
13520 sibling.branches[sibling.branches.length - 1].condition === undefined) {
13521 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13522 }
13523 // move the node to the if node's branches
13524 context.removeNode();
13525 const branch = createIfBranch(node, dir);
13526 if (comments.length &&
13527 // #3619 ignore comments if the v-if is direct child of <transition>
13528 !(context.parent &&
13529 context.parent.type === 1 /* ELEMENT */ &&
13530 isBuiltInType(context.parent.tag, 'transition'))) {
13531 branch.children = [...comments, ...branch.children];
13532 }
13533 // check if user is forcing same key on different branches
13534 {
13535 const key = branch.userKey;
13536 if (key) {
13537 sibling.branches.forEach(({ userKey }) => {
13538 if (isSameKey(userKey, key)) {
13539 context.onError(createCompilerError(29 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
13540 }
13541 });
13542 }
13543 }
13544 sibling.branches.push(branch);
13545 const onExit = processCodegen && processCodegen(sibling, branch, false);
13546 // since the branch was removed, it will not be traversed.
13547 // make sure to traverse here.
13548 traverseNode(branch, context);
13549 // call on exit
13550 if (onExit)
13551 onExit();
13552 // make sure to reset currentNode after traversal to indicate this
13553 // node has been removed.
13554 context.currentNode = null;
13555 }
13556 else {
13557 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13558 }
13559 break;
13560 }
13561 }
13562}
13563function createIfBranch(node, dir) {
13564 return {
13565 type: 10 /* IF_BRANCH */,
13566 loc: node.loc,
13567 condition: dir.name === 'else' ? undefined : dir.exp,
13568 children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
13569 ? node.children
13570 : [node],
13571 userKey: findProp(node, `key`)
13572 };
13573}
13574function createCodegenNodeForBranch(branch, keyIndex, context) {
13575 if (branch.condition) {
13576 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
13577 // make sure to pass in asBlock: true so that the comment node call
13578 // closes the current block.
13579 createCallExpression(context.helper(CREATE_COMMENT), [
13580 '"v-if"' ,
13581 'true'
13582 ]));
13583 }
13584 else {
13585 return createChildrenCodegenNode(branch, keyIndex, context);
13586 }
13587}
13588function createChildrenCodegenNode(branch, keyIndex, context) {
13589 const { helper } = context;
13590 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
13591 const { children } = branch;
13592 const firstChild = children[0];
13593 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
13594 if (needFragmentWrapper) {
13595 if (children.length === 1 && firstChild.type === 11 /* FOR */) {
13596 // optimize away nested fragments when child is a ForNode
13597 const vnodeCall = firstChild.codegenNode;
13598 injectProp(vnodeCall, keyProperty, context);
13599 return vnodeCall;
13600 }
13601 else {
13602 let patchFlag = 64 /* STABLE_FRAGMENT */;
13603 let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
13604 // check if the fragment actually contains a single valid child with
13605 // the rest being comments
13606 if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
13607 patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
13608 patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
13609 }
13610 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);
13611 }
13612 }
13613 else {
13614 const ret = firstChild.codegenNode;
13615 const vnodeCall = getMemoedVNodeCall(ret);
13616 // Change createVNode to createBlock.
13617 if (vnodeCall.type === 13 /* VNODE_CALL */) {
13618 makeBlock(vnodeCall, context);
13619 }
13620 // inject branch key
13621 injectProp(vnodeCall, keyProperty, context);
13622 return ret;
13623 }
13624}
13625function isSameKey(a, b) {
13626 if (!a || a.type !== b.type) {
13627 return false;
13628 }
13629 if (a.type === 6 /* ATTRIBUTE */) {
13630 if (a.value.content !== b.value.content) {
13631 return false;
13632 }
13633 }
13634 else {
13635 // directive
13636 const exp = a.exp;
13637 const branchExp = b.exp;
13638 if (exp.type !== branchExp.type) {
13639 return false;
13640 }
13641 if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
13642 exp.isStatic !== branchExp.isStatic ||
13643 exp.content !== branchExp.content) {
13644 return false;
13645 }
13646 }
13647 return true;
13648}
13649function getParentCondition(node) {
13650 while (true) {
13651 if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13652 if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13653 node = node.alternate;
13654 }
13655 else {
13656 return node;
13657 }
13658 }
13659 else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
13660 node = node.value;
13661 }
13662 }
13663}
13664
13665const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
13666 const { helper, removeHelper } = context;
13667 return processFor(node, dir, context, forNode => {
13668 // create the loop render function expression now, and add the
13669 // iterator on exit after all children have been traversed
13670 const renderExp = createCallExpression(helper(RENDER_LIST), [
13671 forNode.source
13672 ]);
13673 const memo = findDir(node, 'memo');
13674 const keyProp = findProp(node, `key`);
13675 const keyExp = keyProp &&
13676 (keyProp.type === 6 /* ATTRIBUTE */
13677 ? createSimpleExpression(keyProp.value.content, true)
13678 : keyProp.exp);
13679 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
13680 const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
13681 forNode.source.constType > 0 /* NOT_CONSTANT */;
13682 const fragmentFlag = isStableFragment
13683 ? 64 /* STABLE_FRAGMENT */
13684 : keyProp
13685 ? 128 /* KEYED_FRAGMENT */
13686 : 256 /* UNKEYED_FRAGMENT */;
13687 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
13688 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
13689 return () => {
13690 // finish the codegen now that all children have been traversed
13691 let childBlock;
13692 const isTemplate = isTemplateNode(node);
13693 const { children } = forNode;
13694 // check <template v-for> key placement
13695 if (isTemplate) {
13696 node.children.some(c => {
13697 if (c.type === 1 /* ELEMENT */) {
13698 const key = findProp(c, 'key');
13699 if (key) {
13700 context.onError(createCompilerError(33 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
13701 return true;
13702 }
13703 }
13704 });
13705 }
13706 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
13707 const slotOutlet = isSlotOutlet(node)
13708 ? node
13709 : isTemplate &&
13710 node.children.length === 1 &&
13711 isSlotOutlet(node.children[0])
13712 ? node.children[0] // api-extractor somehow fails to infer this
13713 : null;
13714 if (slotOutlet) {
13715 // <slot v-for="..."> or <template v-for="..."><slot/></template>
13716 childBlock = slotOutlet.codegenNode;
13717 if (isTemplate && keyProperty) {
13718 // <template v-for="..." :key="..."><slot/></template>
13719 // we need to inject the key to the renderSlot() call.
13720 // the props for renderSlot is passed as the 3rd argument.
13721 injectProp(childBlock, keyProperty, context);
13722 }
13723 }
13724 else if (needFragmentWrapper) {
13725 // <template v-for="..."> with text or multi-elements
13726 // should generate a fragment block for each loop
13727 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
13728 (` /* ${PatchFlagNames[64 /* STABLE_FRAGMENT */]} */`
13729 ), undefined, undefined, true, undefined, false /* isComponent */);
13730 }
13731 else {
13732 // Normal element v-for. Directly use the child's codegenNode
13733 // but mark it as a block.
13734 childBlock = children[0]
13735 .codegenNode;
13736 if (isTemplate && keyProperty) {
13737 injectProp(childBlock, keyProperty, context);
13738 }
13739 if (childBlock.isBlock !== !isStableFragment) {
13740 if (childBlock.isBlock) {
13741 // switch from block to vnode
13742 removeHelper(OPEN_BLOCK);
13743 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
13744 }
13745 else {
13746 // switch from vnode to block
13747 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
13748 }
13749 }
13750 childBlock.isBlock = !isStableFragment;
13751 if (childBlock.isBlock) {
13752 helper(OPEN_BLOCK);
13753 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
13754 }
13755 else {
13756 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
13757 }
13758 }
13759 if (memo) {
13760 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
13761 createSimpleExpression(`_cached`)
13762 ]));
13763 loop.body = createBlockStatement([
13764 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
13765 createCompoundExpression([
13766 `if (_cached`,
13767 ...(keyExp ? [` && _cached.key === `, keyExp] : []),
13768 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
13769 ]),
13770 createCompoundExpression([`const _item = `, childBlock]),
13771 createSimpleExpression(`_item.memo = _memo`),
13772 createSimpleExpression(`return _item`)
13773 ]);
13774 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
13775 }
13776 else {
13777 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
13778 }
13779 };
13780 });
13781});
13782// target-agnostic transform used for both Client and SSR
13783function processFor(node, dir, context, processCodegen) {
13784 if (!dir.exp) {
13785 context.onError(createCompilerError(31 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
13786 return;
13787 }
13788 const parseResult = parseForExpression(
13789 // can only be simple expression because vFor transform is applied
13790 // before expression transform.
13791 dir.exp, context);
13792 if (!parseResult) {
13793 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
13794 return;
13795 }
13796 const { addIdentifiers, removeIdentifiers, scopes } = context;
13797 const { source, value, key, index } = parseResult;
13798 const forNode = {
13799 type: 11 /* FOR */,
13800 loc: dir.loc,
13801 source,
13802 valueAlias: value,
13803 keyAlias: key,
13804 objectIndexAlias: index,
13805 parseResult,
13806 children: isTemplateNode(node) ? node.children : [node]
13807 };
13808 context.replaceNode(forNode);
13809 // bookkeeping
13810 scopes.vFor++;
13811 const onExit = processCodegen && processCodegen(forNode);
13812 return () => {
13813 scopes.vFor--;
13814 if (onExit)
13815 onExit();
13816 };
13817}
13818const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
13819// This regex doesn't cover the case if key or index aliases have destructuring,
13820// but those do not make sense in the first place, so this works in practice.
13821const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
13822const stripParensRE = /^\(|\)$/g;
13823function parseForExpression(input, context) {
13824 const loc = input.loc;
13825 const exp = input.content;
13826 const inMatch = exp.match(forAliasRE);
13827 if (!inMatch)
13828 return;
13829 const [, LHS, RHS] = inMatch;
13830 const result = {
13831 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
13832 value: undefined,
13833 key: undefined,
13834 index: undefined
13835 };
13836 {
13837 validateBrowserExpression(result.source, context);
13838 }
13839 let valueContent = LHS.trim().replace(stripParensRE, '').trim();
13840 const trimmedOffset = LHS.indexOf(valueContent);
13841 const iteratorMatch = valueContent.match(forIteratorRE);
13842 if (iteratorMatch) {
13843 valueContent = valueContent.replace(forIteratorRE, '').trim();
13844 const keyContent = iteratorMatch[1].trim();
13845 let keyOffset;
13846 if (keyContent) {
13847 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
13848 result.key = createAliasExpression(loc, keyContent, keyOffset);
13849 {
13850 validateBrowserExpression(result.key, context, true);
13851 }
13852 }
13853 if (iteratorMatch[2]) {
13854 const indexContent = iteratorMatch[2].trim();
13855 if (indexContent) {
13856 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
13857 ? keyOffset + keyContent.length
13858 : trimmedOffset + valueContent.length));
13859 {
13860 validateBrowserExpression(result.index, context, true);
13861 }
13862 }
13863 }
13864 }
13865 if (valueContent) {
13866 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
13867 {
13868 validateBrowserExpression(result.value, context, true);
13869 }
13870 }
13871 return result;
13872}
13873function createAliasExpression(range, content, offset) {
13874 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
13875}
13876function createForLoopParams({ value, key, index }, memoArgs = []) {
13877 return createParamsList([value, key, index, ...memoArgs]);
13878}
13879function createParamsList(args) {
13880 let i = args.length;
13881 while (i--) {
13882 if (args[i])
13883 break;
13884 }
13885 return args
13886 .slice(0, i + 1)
13887 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
13888}
13889
13890const defaultFallback = createSimpleExpression(`undefined`, false);
13891// A NodeTransform that:
13892// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
13893// by transformExpression. This is only applied in non-browser builds with
13894// { prefixIdentifiers: true }.
13895// 2. Track v-slot depths so that we know a slot is inside another slot.
13896// Note the exit callback is executed before buildSlots() on the same node,
13897// so only nested slots see positive numbers.
13898const trackSlotScopes = (node, context) => {
13899 if (node.type === 1 /* ELEMENT */ &&
13900 (node.tagType === 1 /* COMPONENT */ ||
13901 node.tagType === 3 /* TEMPLATE */)) {
13902 // We are only checking non-empty v-slot here
13903 // since we only care about slots that introduce scope variables.
13904 const vSlot = findDir(node, 'slot');
13905 if (vSlot) {
13906 vSlot.exp;
13907 context.scopes.vSlot++;
13908 return () => {
13909 context.scopes.vSlot--;
13910 };
13911 }
13912 }
13913};
13914const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
13915// Instead of being a DirectiveTransform, v-slot processing is called during
13916// transformElement to build the slots object for a component.
13917function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
13918 context.helper(WITH_CTX);
13919 const { children, loc } = node;
13920 const slotsProperties = [];
13921 const dynamicSlots = [];
13922 // If the slot is inside a v-for or another v-slot, force it to be dynamic
13923 // since it likely uses a scope variable.
13924 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
13925 // 1. Check for slot with slotProps on component itself.
13926 // <Comp v-slot="{ prop }"/>
13927 const onComponentSlot = findDir(node, 'slot', true);
13928 if (onComponentSlot) {
13929 const { arg, exp } = onComponentSlot;
13930 if (arg && !isStaticExp(arg)) {
13931 hasDynamicSlots = true;
13932 }
13933 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
13934 }
13935 // 2. Iterate through children and check for template slots
13936 // <template v-slot:foo="{ prop }">
13937 let hasTemplateSlots = false;
13938 let hasNamedDefaultSlot = false;
13939 const implicitDefaultChildren = [];
13940 const seenSlotNames = new Set();
13941 for (let i = 0; i < children.length; i++) {
13942 const slotElement = children[i];
13943 let slotDir;
13944 if (!isTemplateNode(slotElement) ||
13945 !(slotDir = findDir(slotElement, 'slot', true))) {
13946 // not a <template v-slot>, skip.
13947 if (slotElement.type !== 3 /* COMMENT */) {
13948 implicitDefaultChildren.push(slotElement);
13949 }
13950 continue;
13951 }
13952 if (onComponentSlot) {
13953 // already has on-component slot - this is incorrect usage.
13954 context.onError(createCompilerError(37 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
13955 break;
13956 }
13957 hasTemplateSlots = true;
13958 const { children: slotChildren, loc: slotLoc } = slotElement;
13959 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
13960 // check if name is dynamic.
13961 let staticSlotName;
13962 if (isStaticExp(slotName)) {
13963 staticSlotName = slotName ? slotName.content : `default`;
13964 }
13965 else {
13966 hasDynamicSlots = true;
13967 }
13968 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
13969 // check if this slot is conditional (v-if/v-for)
13970 let vIf;
13971 let vElse;
13972 let vFor;
13973 if ((vIf = findDir(slotElement, 'if'))) {
13974 hasDynamicSlots = true;
13975 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
13976 }
13977 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
13978 // find adjacent v-if
13979 let j = i;
13980 let prev;
13981 while (j--) {
13982 prev = children[j];
13983 if (prev.type !== 3 /* COMMENT */) {
13984 break;
13985 }
13986 }
13987 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
13988 // remove node
13989 children.splice(i, 1);
13990 i--;
13991 // attach this slot to previous conditional
13992 let conditional = dynamicSlots[dynamicSlots.length - 1];
13993 while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
13994 conditional = conditional.alternate;
13995 }
13996 conditional.alternate = vElse.exp
13997 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
13998 : buildDynamicSlot(slotName, slotFunction);
13999 }
14000 else {
14001 context.onError(createCompilerError(30 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
14002 }
14003 }
14004 else if ((vFor = findDir(slotElement, 'for'))) {
14005 hasDynamicSlots = true;
14006 const parseResult = vFor.parseResult ||
14007 parseForExpression(vFor.exp, context);
14008 if (parseResult) {
14009 // Render the dynamic slots as an array and add it to the createSlot()
14010 // args. The runtime knows how to handle it appropriately.
14011 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
14012 parseResult.source,
14013 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
14014 ]));
14015 }
14016 else {
14017 context.onError(createCompilerError(32 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
14018 }
14019 }
14020 else {
14021 // check duplicate static names
14022 if (staticSlotName) {
14023 if (seenSlotNames.has(staticSlotName)) {
14024 context.onError(createCompilerError(38 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
14025 continue;
14026 }
14027 seenSlotNames.add(staticSlotName);
14028 if (staticSlotName === 'default') {
14029 hasNamedDefaultSlot = true;
14030 }
14031 }
14032 slotsProperties.push(createObjectProperty(slotName, slotFunction));
14033 }
14034 }
14035 if (!onComponentSlot) {
14036 const buildDefaultSlotProperty = (props, children) => {
14037 const fn = buildSlotFn(props, children, loc);
14038 return createObjectProperty(`default`, fn);
14039 };
14040 if (!hasTemplateSlots) {
14041 // implicit default slot (on component)
14042 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
14043 }
14044 else if (implicitDefaultChildren.length &&
14045 // #3766
14046 // with whitespace: 'preserve', whitespaces between slots will end up in
14047 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
14048 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
14049 // implicit default slot (mixed with named slots)
14050 if (hasNamedDefaultSlot) {
14051 context.onError(createCompilerError(39 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
14052 }
14053 else {
14054 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
14055 }
14056 }
14057 }
14058 const slotFlag = hasDynamicSlots
14059 ? 2 /* DYNAMIC */
14060 : hasForwardedSlots(node.children)
14061 ? 3 /* FORWARDED */
14062 : 1 /* STABLE */;
14063 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
14064 // 2 = compiled but dynamic = can skip normalization, but must run diff
14065 // 1 = compiled and static = can skip normalization AND diff as optimized
14066 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
14067 if (dynamicSlots.length) {
14068 slots = createCallExpression(context.helper(CREATE_SLOTS), [
14069 slots,
14070 createArrayExpression(dynamicSlots)
14071 ]);
14072 }
14073 return {
14074 slots,
14075 hasDynamicSlots
14076 };
14077}
14078function buildDynamicSlot(name, fn) {
14079 return createObjectExpression([
14080 createObjectProperty(`name`, name),
14081 createObjectProperty(`fn`, fn)
14082 ]);
14083}
14084function hasForwardedSlots(children) {
14085 for (let i = 0; i < children.length; i++) {
14086 const child = children[i];
14087 switch (child.type) {
14088 case 1 /* ELEMENT */:
14089 if (child.tagType === 2 /* SLOT */ ||
14090 hasForwardedSlots(child.children)) {
14091 return true;
14092 }
14093 break;
14094 case 9 /* IF */:
14095 if (hasForwardedSlots(child.branches))
14096 return true;
14097 break;
14098 case 10 /* IF_BRANCH */:
14099 case 11 /* FOR */:
14100 if (hasForwardedSlots(child.children))
14101 return true;
14102 break;
14103 }
14104 }
14105 return false;
14106}
14107function isNonWhitespaceContent(node) {
14108 if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
14109 return true;
14110 return node.type === 2 /* TEXT */
14111 ? !!node.content.trim()
14112 : isNonWhitespaceContent(node.content);
14113}
14114
14115// some directive transforms (e.g. v-model) may return a symbol for runtime
14116// import, which should be used instead of a resolveDirective call.
14117const directiveImportMap = new WeakMap();
14118// generate a JavaScript AST for this element's codegen
14119const transformElement = (node, context) => {
14120 // perform the work on exit, after all child expressions have been
14121 // processed and merged.
14122 return function postTransformElement() {
14123 node = context.currentNode;
14124 if (!(node.type === 1 /* ELEMENT */ &&
14125 (node.tagType === 0 /* ELEMENT */ ||
14126 node.tagType === 1 /* COMPONENT */))) {
14127 return;
14128 }
14129 const { tag, props } = node;
14130 const isComponent = node.tagType === 1 /* COMPONENT */;
14131 // The goal of the transform is to create a codegenNode implementing the
14132 // VNodeCall interface.
14133 let vnodeTag = isComponent
14134 ? resolveComponentType(node, context)
14135 : `"${tag}"`;
14136 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
14137 let vnodeProps;
14138 let vnodeChildren;
14139 let vnodePatchFlag;
14140 let patchFlag = 0;
14141 let vnodeDynamicProps;
14142 let dynamicPropNames;
14143 let vnodeDirectives;
14144 let shouldUseBlock =
14145 // dynamic component may resolve to plain elements
14146 isDynamicComponent ||
14147 vnodeTag === TELEPORT ||
14148 vnodeTag === SUSPENSE ||
14149 (!isComponent &&
14150 // <svg> and <foreignObject> must be forced into blocks so that block
14151 // updates inside get proper isSVG flag at runtime. (#639, #643)
14152 // This is technically web-specific, but splitting the logic out of core
14153 // leads to too much unnecessary complexity.
14154 (tag === 'svg' ||
14155 tag === 'foreignObject' ||
14156 // #938: elements with dynamic keys should be forced into blocks
14157 findProp(node, 'key', true)));
14158 // props
14159 if (props.length > 0) {
14160 const propsBuildResult = buildProps(node, context);
14161 vnodeProps = propsBuildResult.props;
14162 patchFlag = propsBuildResult.patchFlag;
14163 dynamicPropNames = propsBuildResult.dynamicPropNames;
14164 const directives = propsBuildResult.directives;
14165 vnodeDirectives =
14166 directives && directives.length
14167 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14168 : undefined;
14169 }
14170 // children
14171 if (node.children.length > 0) {
14172 if (vnodeTag === KEEP_ALIVE) {
14173 // Although a built-in component, we compile KeepAlive with raw children
14174 // instead of slot functions so that it can be used inside Transition
14175 // or other Transition-wrapping HOCs.
14176 // To ensure correct updates with block optimizations, we need to:
14177 // 1. Force keep-alive into a block. This avoids its children being
14178 // collected by a parent block.
14179 shouldUseBlock = true;
14180 // 2. Force keep-alive to always be updated, since it uses raw children.
14181 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14182 if (node.children.length > 1) {
14183 context.onError(createCompilerError(45 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
14184 start: node.children[0].loc.start,
14185 end: node.children[node.children.length - 1].loc.end,
14186 source: ''
14187 }));
14188 }
14189 }
14190 const shouldBuildAsSlots = isComponent &&
14191 // Teleport is not a real component and has dedicated runtime handling
14192 vnodeTag !== TELEPORT &&
14193 // explained above.
14194 vnodeTag !== KEEP_ALIVE;
14195 if (shouldBuildAsSlots) {
14196 const { slots, hasDynamicSlots } = buildSlots(node, context);
14197 vnodeChildren = slots;
14198 if (hasDynamicSlots) {
14199 patchFlag |= 1024 /* DYNAMIC_SLOTS */;
14200 }
14201 }
14202 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
14203 const child = node.children[0];
14204 const type = child.type;
14205 // check for dynamic text children
14206 const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
14207 type === 8 /* COMPOUND_EXPRESSION */;
14208 if (hasDynamicTextChild &&
14209 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
14210 patchFlag |= 1 /* TEXT */;
14211 }
14212 // pass directly if the only child is a text node
14213 // (plain / interpolation / expression)
14214 if (hasDynamicTextChild || type === 2 /* TEXT */) {
14215 vnodeChildren = child;
14216 }
14217 else {
14218 vnodeChildren = node.children;
14219 }
14220 }
14221 else {
14222 vnodeChildren = node.children;
14223 }
14224 }
14225 // patchFlag & dynamicPropNames
14226 if (patchFlag !== 0) {
14227 {
14228 if (patchFlag < 0) {
14229 // special flags (negative and mutually exclusive)
14230 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
14231 }
14232 else {
14233 // bitwise flags
14234 const flagNames = Object.keys(PatchFlagNames)
14235 .map(Number)
14236 .filter(n => n > 0 && patchFlag & n)
14237 .map(n => PatchFlagNames[n])
14238 .join(`, `);
14239 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
14240 }
14241 }
14242 if (dynamicPropNames && dynamicPropNames.length) {
14243 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
14244 }
14245 }
14246 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
14247 };
14248};
14249function resolveComponentType(node, context, ssr = false) {
14250 let { tag } = node;
14251 // 1. dynamic component
14252 const isExplicitDynamic = isComponentTag(tag);
14253 const isProp = findProp(node, 'is');
14254 if (isProp) {
14255 if (isExplicitDynamic ||
14256 (false )) {
14257 const exp = isProp.type === 6 /* ATTRIBUTE */
14258 ? isProp.value && createSimpleExpression(isProp.value.content, true)
14259 : isProp.exp;
14260 if (exp) {
14261 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14262 exp
14263 ]);
14264 }
14265 }
14266 else if (isProp.type === 6 /* ATTRIBUTE */ &&
14267 isProp.value.content.startsWith('vue:')) {
14268 // <button is="vue:xxx">
14269 // if not <component>, only is value that starts with "vue:" will be
14270 // treated as component by the parse phase and reach here, unless it's
14271 // compat mode where all is values are considered components
14272 tag = isProp.value.content.slice(4);
14273 }
14274 }
14275 // 1.5 v-is (TODO: Deprecate)
14276 const isDir = !isExplicitDynamic && findDir(node, 'is');
14277 if (isDir && isDir.exp) {
14278 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14279 isDir.exp
14280 ]);
14281 }
14282 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
14283 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
14284 if (builtIn) {
14285 // built-ins are simply fallthroughs / have special handling during ssr
14286 // so we don't need to import their runtime equivalents
14287 if (!ssr)
14288 context.helper(builtIn);
14289 return builtIn;
14290 }
14291 // 5. user component (resolve)
14292 context.helper(RESOLVE_COMPONENT);
14293 context.components.add(tag);
14294 return toValidAssetId(tag, `component`);
14295}
14296function buildProps(node, context, props = node.props, ssr = false) {
14297 const { tag, loc: elementLoc } = node;
14298 const isComponent = node.tagType === 1 /* COMPONENT */;
14299 let properties = [];
14300 const mergeArgs = [];
14301 const runtimeDirectives = [];
14302 // patchFlag analysis
14303 let patchFlag = 0;
14304 let hasRef = false;
14305 let hasClassBinding = false;
14306 let hasStyleBinding = false;
14307 let hasHydrationEventBinding = false;
14308 let hasDynamicKeys = false;
14309 let hasVnodeHook = false;
14310 const dynamicPropNames = [];
14311 const analyzePatchFlag = ({ key, value }) => {
14312 if (isStaticExp(key)) {
14313 const name = key.content;
14314 const isEventHandler = isOn(name);
14315 if (!isComponent &&
14316 isEventHandler &&
14317 // omit the flag for click handlers because hydration gives click
14318 // dedicated fast path.
14319 name.toLowerCase() !== 'onclick' &&
14320 // omit v-model handlers
14321 name !== 'onUpdate:modelValue' &&
14322 // omit onVnodeXXX hooks
14323 !isReservedProp(name)) {
14324 hasHydrationEventBinding = true;
14325 }
14326 if (isEventHandler && isReservedProp(name)) {
14327 hasVnodeHook = true;
14328 }
14329 if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
14330 ((value.type === 4 /* SIMPLE_EXPRESSION */ ||
14331 value.type === 8 /* COMPOUND_EXPRESSION */) &&
14332 getConstantType(value, context) > 0)) {
14333 // skip if the prop is a cached handler or has constant value
14334 return;
14335 }
14336 if (name === 'ref') {
14337 hasRef = true;
14338 }
14339 else if (name === 'class') {
14340 hasClassBinding = true;
14341 }
14342 else if (name === 'style') {
14343 hasStyleBinding = true;
14344 }
14345 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
14346 dynamicPropNames.push(name);
14347 }
14348 // treat the dynamic class and style binding of the component as dynamic props
14349 if (isComponent &&
14350 (name === 'class' || name === 'style') &&
14351 !dynamicPropNames.includes(name)) {
14352 dynamicPropNames.push(name);
14353 }
14354 }
14355 else {
14356 hasDynamicKeys = true;
14357 }
14358 };
14359 for (let i = 0; i < props.length; i++) {
14360 // static attribute
14361 const prop = props[i];
14362 if (prop.type === 6 /* ATTRIBUTE */) {
14363 const { loc, name, value } = prop;
14364 let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
14365 if (name === 'ref') {
14366 hasRef = true;
14367 }
14368 // skip is on <component>, or is="vue:xxx"
14369 if (name === 'is' &&
14370 (isComponentTag(tag) ||
14371 (value && value.content.startsWith('vue:')) ||
14372 (false ))) {
14373 continue;
14374 }
14375 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
14376 }
14377 else {
14378 // directives
14379 const { name, arg, exp, loc } = prop;
14380 const isVBind = name === 'bind';
14381 const isVOn = name === 'on';
14382 // skip v-slot - it is handled by its dedicated transform.
14383 if (name === 'slot') {
14384 if (!isComponent) {
14385 context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, loc));
14386 }
14387 continue;
14388 }
14389 // skip v-once/v-memo - they are handled by dedicated transforms.
14390 if (name === 'once' || name === 'memo') {
14391 continue;
14392 }
14393 // skip v-is and :is on <component>
14394 if (name === 'is' ||
14395 (isVBind &&
14396 isBindKey(arg, 'is') &&
14397 (isComponentTag(tag) ||
14398 (false )))) {
14399 continue;
14400 }
14401 // skip v-on in SSR compilation
14402 if (isVOn && ssr) {
14403 continue;
14404 }
14405 // special case for v-bind and v-on with no argument
14406 if (!arg && (isVBind || isVOn)) {
14407 hasDynamicKeys = true;
14408 if (exp) {
14409 if (properties.length) {
14410 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14411 properties = [];
14412 }
14413 if (isVBind) {
14414 mergeArgs.push(exp);
14415 }
14416 else {
14417 // v-on="obj" -> toHandlers(obj)
14418 mergeArgs.push({
14419 type: 14 /* JS_CALL_EXPRESSION */,
14420 loc,
14421 callee: context.helper(TO_HANDLERS),
14422 arguments: [exp]
14423 });
14424 }
14425 }
14426 else {
14427 context.onError(createCompilerError(isVBind
14428 ? 34 /* X_V_BIND_NO_EXPRESSION */
14429 : 35 /* X_V_ON_NO_EXPRESSION */, loc));
14430 }
14431 continue;
14432 }
14433 const directiveTransform = context.directiveTransforms[name];
14434 if (directiveTransform) {
14435 // has built-in directive transform.
14436 const { props, needRuntime } = directiveTransform(prop, node, context);
14437 !ssr && props.forEach(analyzePatchFlag);
14438 properties.push(...props);
14439 if (needRuntime) {
14440 runtimeDirectives.push(prop);
14441 if (isSymbol(needRuntime)) {
14442 directiveImportMap.set(prop, needRuntime);
14443 }
14444 }
14445 }
14446 else {
14447 // no built-in transform, this is a user custom directive.
14448 runtimeDirectives.push(prop);
14449 }
14450 }
14451 }
14452 let propsExpression = undefined;
14453 // has v-bind="object" or v-on="object", wrap with mergeProps
14454 if (mergeArgs.length) {
14455 if (properties.length) {
14456 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14457 }
14458 if (mergeArgs.length > 1) {
14459 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
14460 }
14461 else {
14462 // single v-bind with nothing else - no need for a mergeProps call
14463 propsExpression = mergeArgs[0];
14464 }
14465 }
14466 else if (properties.length) {
14467 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
14468 }
14469 // patchFlag analysis
14470 if (hasDynamicKeys) {
14471 patchFlag |= 16 /* FULL_PROPS */;
14472 }
14473 else {
14474 if (hasClassBinding && !isComponent) {
14475 patchFlag |= 2 /* CLASS */;
14476 }
14477 if (hasStyleBinding && !isComponent) {
14478 patchFlag |= 4 /* STYLE */;
14479 }
14480 if (dynamicPropNames.length) {
14481 patchFlag |= 8 /* PROPS */;
14482 }
14483 if (hasHydrationEventBinding) {
14484 patchFlag |= 32 /* HYDRATE_EVENTS */;
14485 }
14486 }
14487 if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14488 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14489 patchFlag |= 512 /* NEED_PATCH */;
14490 }
14491 // pre-normalize props, SSR is skipped for now
14492 if (!context.inSSR && propsExpression) {
14493 switch (propsExpression.type) {
14494 case 15 /* JS_OBJECT_EXPRESSION */:
14495 // means that there is no v-bind,
14496 // but still need to deal with dynamic key binding
14497 let classKeyIndex = -1;
14498 let styleKeyIndex = -1;
14499 let hasDynamicKey = false;
14500 for (let i = 0; i < propsExpression.properties.length; i++) {
14501 const key = propsExpression.properties[i].key;
14502 if (isStaticExp(key)) {
14503 if (key.content === 'class') {
14504 classKeyIndex = i;
14505 }
14506 else if (key.content === 'style') {
14507 styleKeyIndex = i;
14508 }
14509 }
14510 else if (!key.isHandlerKey) {
14511 hasDynamicKey = true;
14512 }
14513 }
14514 const classProp = propsExpression.properties[classKeyIndex];
14515 const styleProp = propsExpression.properties[styleKeyIndex];
14516 // no dynamic key
14517 if (!hasDynamicKey) {
14518 if (classProp && !isStaticExp(classProp.value)) {
14519 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
14520 }
14521 if (styleProp &&
14522 !isStaticExp(styleProp.value) &&
14523 // the static style is compiled into an object,
14524 // so use `hasStyleBinding` to ensure that it is a dynamic style binding
14525 (hasStyleBinding ||
14526 // v-bind:style and style both exist,
14527 // v-bind:style with static literal object
14528 styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
14529 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
14530 }
14531 }
14532 else {
14533 // dynamic key binding, wrap with `normalizeProps`
14534 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
14535 }
14536 break;
14537 case 14 /* JS_CALL_EXPRESSION */:
14538 // mergeProps call, do nothing
14539 break;
14540 default:
14541 // single v-bind
14542 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
14543 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
14544 propsExpression
14545 ])
14546 ]);
14547 break;
14548 }
14549 }
14550 return {
14551 props: propsExpression,
14552 directives: runtimeDirectives,
14553 patchFlag,
14554 dynamicPropNames
14555 };
14556}
14557// Dedupe props in an object literal.
14558// Literal duplicated attributes would have been warned during the parse phase,
14559// however, it's possible to encounter duplicated `onXXX` handlers with different
14560// modifiers. We also need to merge static and dynamic class / style attributes.
14561// - onXXX handlers / style: merge into array
14562// - class: merge into single expression with concatenation
14563function dedupeProperties(properties) {
14564 const knownProps = new Map();
14565 const deduped = [];
14566 for (let i = 0; i < properties.length; i++) {
14567 const prop = properties[i];
14568 // dynamic keys are always allowed
14569 if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
14570 deduped.push(prop);
14571 continue;
14572 }
14573 const name = prop.key.content;
14574 const existing = knownProps.get(name);
14575 if (existing) {
14576 if (name === 'style' || name === 'class' || isOn(name)) {
14577 mergeAsArray$1(existing, prop);
14578 }
14579 // unexpected duplicate, should have emitted error during parse
14580 }
14581 else {
14582 knownProps.set(name, prop);
14583 deduped.push(prop);
14584 }
14585 }
14586 return deduped;
14587}
14588function mergeAsArray$1(existing, incoming) {
14589 if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
14590 existing.value.elements.push(incoming.value);
14591 }
14592 else {
14593 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
14594 }
14595}
14596function buildDirectiveArgs(dir, context) {
14597 const dirArgs = [];
14598 const runtime = directiveImportMap.get(dir);
14599 if (runtime) {
14600 // built-in directive with runtime
14601 dirArgs.push(context.helperString(runtime));
14602 }
14603 else {
14604 {
14605 // inject statement for resolving directive
14606 context.helper(RESOLVE_DIRECTIVE);
14607 context.directives.add(dir.name);
14608 dirArgs.push(toValidAssetId(dir.name, `directive`));
14609 }
14610 }
14611 const { loc } = dir;
14612 if (dir.exp)
14613 dirArgs.push(dir.exp);
14614 if (dir.arg) {
14615 if (!dir.exp) {
14616 dirArgs.push(`void 0`);
14617 }
14618 dirArgs.push(dir.arg);
14619 }
14620 if (Object.keys(dir.modifiers).length) {
14621 if (!dir.arg) {
14622 if (!dir.exp) {
14623 dirArgs.push(`void 0`);
14624 }
14625 dirArgs.push(`void 0`);
14626 }
14627 const trueExpression = createSimpleExpression(`true`, false, loc);
14628 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
14629 }
14630 return createArrayExpression(dirArgs, dir.loc);
14631}
14632function stringifyDynamicPropNames(props) {
14633 let propsNamesString = `[`;
14634 for (let i = 0, l = props.length; i < l; i++) {
14635 propsNamesString += JSON.stringify(props[i]);
14636 if (i < l - 1)
14637 propsNamesString += ', ';
14638 }
14639 return propsNamesString + `]`;
14640}
14641function isComponentTag(tag) {
14642 return tag[0].toLowerCase() + tag.slice(1) === 'component';
14643}
14644
14645const transformSlotOutlet = (node, context) => {
14646 if (isSlotOutlet(node)) {
14647 const { children, loc } = node;
14648 const { slotName, slotProps } = processSlotOutlet(node, context);
14649 const slotArgs = [
14650 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
14651 slotName,
14652 '{}',
14653 'undefined',
14654 'true'
14655 ];
14656 let expectedLen = 2;
14657 if (slotProps) {
14658 slotArgs[2] = slotProps;
14659 expectedLen = 3;
14660 }
14661 if (children.length) {
14662 slotArgs[3] = createFunctionExpression([], children, false, false, loc);
14663 expectedLen = 4;
14664 }
14665 if (context.scopeId && !context.slotted) {
14666 expectedLen = 5;
14667 }
14668 slotArgs.splice(expectedLen); // remove unused arguments
14669 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
14670 }
14671};
14672function processSlotOutlet(node, context) {
14673 let slotName = `"default"`;
14674 let slotProps = undefined;
14675 const nonNameProps = [];
14676 for (let i = 0; i < node.props.length; i++) {
14677 const p = node.props[i];
14678 if (p.type === 6 /* ATTRIBUTE */) {
14679 if (p.value) {
14680 if (p.name === 'name') {
14681 slotName = JSON.stringify(p.value.content);
14682 }
14683 else {
14684 p.name = camelize(p.name);
14685 nonNameProps.push(p);
14686 }
14687 }
14688 }
14689 else {
14690 if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
14691 if (p.exp)
14692 slotName = p.exp;
14693 }
14694 else {
14695 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
14696 p.arg.content = camelize(p.arg.content);
14697 }
14698 nonNameProps.push(p);
14699 }
14700 }
14701 }
14702 if (nonNameProps.length > 0) {
14703 const { props, directives } = buildProps(node, context, nonNameProps);
14704 slotProps = props;
14705 if (directives.length) {
14706 context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
14707 }
14708 }
14709 return {
14710 slotName,
14711 slotProps
14712 };
14713}
14714
14715const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
14716const transformOn = (dir, node, context, augmentor) => {
14717 const { loc, modifiers, arg } = dir;
14718 if (!dir.exp && !modifiers.length) {
14719 context.onError(createCompilerError(35 /* X_V_ON_NO_EXPRESSION */, loc));
14720 }
14721 let eventName;
14722 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14723 if (arg.isStatic) {
14724 const rawName = arg.content;
14725 // for all event listeners, auto convert it to camelCase. See issue #2249
14726 eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
14727 }
14728 else {
14729 // #2388
14730 eventName = createCompoundExpression([
14731 `${context.helperString(TO_HANDLER_KEY)}(`,
14732 arg,
14733 `)`
14734 ]);
14735 }
14736 }
14737 else {
14738 // already a compound expression.
14739 eventName = arg;
14740 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
14741 eventName.children.push(`)`);
14742 }
14743 // handler processing
14744 let exp = dir.exp;
14745 if (exp && !exp.content.trim()) {
14746 exp = undefined;
14747 }
14748 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
14749 if (exp) {
14750 const isMemberExp = isMemberExpression(exp.content);
14751 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
14752 const hasMultipleStatements = exp.content.includes(`;`);
14753 {
14754 validateBrowserExpression(exp, context, false, hasMultipleStatements);
14755 }
14756 if (isInlineStatement || (shouldCache && isMemberExp)) {
14757 // wrap inline statement in a function expression
14758 exp = createCompoundExpression([
14759 `${isInlineStatement
14760 ? `$event`
14761 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
14762 exp,
14763 hasMultipleStatements ? `}` : `)`
14764 ]);
14765 }
14766 }
14767 let ret = {
14768 props: [
14769 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
14770 ]
14771 };
14772 // apply extended compiler augmentor
14773 if (augmentor) {
14774 ret = augmentor(ret);
14775 }
14776 if (shouldCache) {
14777 // cache handlers so that it's always the same handler being passed down.
14778 // this avoids unnecessary re-renders when users use inline handlers on
14779 // components.
14780 ret.props[0].value = context.cache(ret.props[0].value);
14781 }
14782 // mark the key as handler for props normalization check
14783 ret.props.forEach(p => (p.key.isHandlerKey = true));
14784 return ret;
14785};
14786
14787// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
14788// codegen for the entire props object. This transform here is only for v-bind
14789// *with* args.
14790const transformBind = (dir, _node, context) => {
14791 const { exp, modifiers, loc } = dir;
14792 const arg = dir.arg;
14793 if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
14794 arg.children.unshift(`(`);
14795 arg.children.push(`) || ""`);
14796 }
14797 else if (!arg.isStatic) {
14798 arg.content = `${arg.content} || ""`;
14799 }
14800 // .sync is replaced by v-model:arg
14801 if (modifiers.includes('camel')) {
14802 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14803 if (arg.isStatic) {
14804 arg.content = camelize(arg.content);
14805 }
14806 else {
14807 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
14808 }
14809 }
14810 else {
14811 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
14812 arg.children.push(`)`);
14813 }
14814 }
14815 if (!context.inSSR) {
14816 if (modifiers.includes('prop')) {
14817 injectPrefix(arg, '.');
14818 }
14819 if (modifiers.includes('attr')) {
14820 injectPrefix(arg, '^');
14821 }
14822 }
14823 if (!exp ||
14824 (exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
14825 context.onError(createCompilerError(34 /* X_V_BIND_NO_EXPRESSION */, loc));
14826 return {
14827 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
14828 };
14829 }
14830 return {
14831 props: [createObjectProperty(arg, exp)]
14832 };
14833};
14834const injectPrefix = (arg, prefix) => {
14835 if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14836 if (arg.isStatic) {
14837 arg.content = prefix + arg.content;
14838 }
14839 else {
14840 arg.content = `\`${prefix}\${${arg.content}}\``;
14841 }
14842 }
14843 else {
14844 arg.children.unshift(`'${prefix}' + (`);
14845 arg.children.push(`)`);
14846 }
14847};
14848
14849// Merge adjacent text nodes and expressions into a single expression
14850// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
14851const transformText = (node, context) => {
14852 if (node.type === 0 /* ROOT */ ||
14853 node.type === 1 /* ELEMENT */ ||
14854 node.type === 11 /* FOR */ ||
14855 node.type === 10 /* IF_BRANCH */) {
14856 // perform the transform on node exit so that all expressions have already
14857 // been processed.
14858 return () => {
14859 const children = node.children;
14860 let currentContainer = undefined;
14861 let hasText = false;
14862 for (let i = 0; i < children.length; i++) {
14863 const child = children[i];
14864 if (isText(child)) {
14865 hasText = true;
14866 for (let j = i + 1; j < children.length; j++) {
14867 const next = children[j];
14868 if (isText(next)) {
14869 if (!currentContainer) {
14870 currentContainer = children[i] = {
14871 type: 8 /* COMPOUND_EXPRESSION */,
14872 loc: child.loc,
14873 children: [child]
14874 };
14875 }
14876 // merge adjacent text node into current
14877 currentContainer.children.push(` + `, next);
14878 children.splice(j, 1);
14879 j--;
14880 }
14881 else {
14882 currentContainer = undefined;
14883 break;
14884 }
14885 }
14886 }
14887 }
14888 if (!hasText ||
14889 // if this is a plain element with a single text child, leave it
14890 // as-is since the runtime has dedicated fast path for this by directly
14891 // setting textContent of the element.
14892 // for component root it's always normalized anyway.
14893 (children.length === 1 &&
14894 (node.type === 0 /* ROOT */ ||
14895 (node.type === 1 /* ELEMENT */ &&
14896 node.tagType === 0 /* ELEMENT */ &&
14897 // #3756
14898 // custom directives can potentially add DOM elements arbitrarily,
14899 // we need to avoid setting textContent of the element at runtime
14900 // to avoid accidentally overwriting the DOM elements added
14901 // by the user through custom directives.
14902 !node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
14903 !context.directiveTransforms[p.name]) &&
14904 // in compat mode, <template> tags with no special directives
14905 // will be rendered as a fragment so its children must be
14906 // converted into vnodes.
14907 !(false ))))) {
14908 return;
14909 }
14910 // pre-convert text nodes into createTextVNode(text) calls to avoid
14911 // runtime normalization.
14912 for (let i = 0; i < children.length; i++) {
14913 const child = children[i];
14914 if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
14915 const callArgs = [];
14916 // createTextVNode defaults to single whitespace, so if it is a
14917 // single space the code could be an empty call to save bytes.
14918 if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
14919 callArgs.push(child);
14920 }
14921 // mark dynamic text with flag so it gets patched inside a block
14922 if (!context.ssr &&
14923 getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
14924 callArgs.push(1 /* TEXT */ +
14925 (` /* ${PatchFlagNames[1 /* TEXT */]} */` ));
14926 }
14927 children[i] = {
14928 type: 12 /* TEXT_CALL */,
14929 content: child,
14930 loc: child.loc,
14931 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
14932 };
14933 }
14934 }
14935 };
14936 }
14937};
14938
14939const seen = new WeakSet();
14940const transformOnce = (node, context) => {
14941 if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
14942 if (seen.has(node) || context.inVOnce) {
14943 return;
14944 }
14945 seen.add(node);
14946 context.inVOnce = true;
14947 context.helper(SET_BLOCK_TRACKING);
14948 return () => {
14949 context.inVOnce = false;
14950 const cur = context.currentNode;
14951 if (cur.codegenNode) {
14952 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
14953 }
14954 };
14955 }
14956};
14957
14958const transformModel = (dir, node, context) => {
14959 const { exp, arg } = dir;
14960 if (!exp) {
14961 context.onError(createCompilerError(41 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
14962 return createTransformProps();
14963 }
14964 const rawExp = exp.loc.source;
14965 const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
14966 // im SFC <script setup> inline mode, the exp may have been transformed into
14967 // _unref(exp)
14968 context.bindingMetadata[rawExp];
14969 const maybeRef = !true /* SETUP_CONST */;
14970 if (!expString.trim() ||
14971 (!isMemberExpression(expString) && !maybeRef)) {
14972 context.onError(createCompilerError(42 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
14973 return createTransformProps();
14974 }
14975 const propName = arg ? arg : createSimpleExpression('modelValue', true);
14976 const eventName = arg
14977 ? isStaticExp(arg)
14978 ? `onUpdate:${arg.content}`
14979 : createCompoundExpression(['"onUpdate:" + ', arg])
14980 : `onUpdate:modelValue`;
14981 let assignmentExp;
14982 const eventArg = context.isTS ? `($event: any)` : `$event`;
14983 {
14984 assignmentExp = createCompoundExpression([
14985 `${eventArg} => ((`,
14986 exp,
14987 `) = $event)`
14988 ]);
14989 }
14990 const props = [
14991 // modelValue: foo
14992 createObjectProperty(propName, dir.exp),
14993 // "onUpdate:modelValue": $event => (foo = $event)
14994 createObjectProperty(eventName, assignmentExp)
14995 ];
14996 // modelModifiers: { foo: true, "bar-baz": true }
14997 if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
14998 const modifiers = dir.modifiers
14999 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
15000 .join(`, `);
15001 const modifiersKey = arg
15002 ? isStaticExp(arg)
15003 ? `${arg.content}Modifiers`
15004 : createCompoundExpression([arg, ' + "Modifiers"'])
15005 : `modelModifiers`;
15006 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
15007 }
15008 return createTransformProps(props);
15009};
15010function createTransformProps(props = []) {
15011 return { props };
15012}
15013
15014const seen$1 = new WeakSet();
15015const transformMemo = (node, context) => {
15016 if (node.type === 1 /* ELEMENT */) {
15017 const dir = findDir(node, 'memo');
15018 if (!dir || seen$1.has(node)) {
15019 return;
15020 }
15021 seen$1.add(node);
15022 return () => {
15023 const codegenNode = node.codegenNode ||
15024 context.currentNode.codegenNode;
15025 if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
15026 // non-component sub tree should be turned into a block
15027 if (node.tagType !== 1 /* COMPONENT */) {
15028 makeBlock(codegenNode, context);
15029 }
15030 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
15031 dir.exp,
15032 createFunctionExpression(undefined, codegenNode),
15033 `_cache`,
15034 String(context.cached++)
15035 ]);
15036 }
15037 };
15038 }
15039};
15040
15041function getBaseTransformPreset(prefixIdentifiers) {
15042 return [
15043 [
15044 transformOnce,
15045 transformIf,
15046 transformMemo,
15047 transformFor,
15048 ...([]),
15049 ...([transformExpression]
15050 ),
15051 transformSlotOutlet,
15052 transformElement,
15053 trackSlotScopes,
15054 transformText
15055 ],
15056 {
15057 on: transformOn,
15058 bind: transformBind,
15059 model: transformModel
15060 }
15061 ];
15062}
15063// we name it `baseCompile` so that higher order compilers like
15064// @vue/compiler-dom can export `compile` while re-exporting everything else.
15065function baseCompile(template, options = {}) {
15066 const onError = options.onError || defaultOnError;
15067 const isModuleMode = options.mode === 'module';
15068 /* istanbul ignore if */
15069 {
15070 if (options.prefixIdentifiers === true) {
15071 onError(createCompilerError(46 /* X_PREFIX_ID_NOT_SUPPORTED */));
15072 }
15073 else if (isModuleMode) {
15074 onError(createCompilerError(47 /* X_MODULE_MODE_NOT_SUPPORTED */));
15075 }
15076 }
15077 const prefixIdentifiers = !true ;
15078 if (options.cacheHandlers) {
15079 onError(createCompilerError(48 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
15080 }
15081 if (options.scopeId && !isModuleMode) {
15082 onError(createCompilerError(49 /* X_SCOPE_ID_NOT_SUPPORTED */));
15083 }
15084 const ast = isString(template) ? baseParse(template, options) : template;
15085 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
15086 transform(ast, extend({}, options, {
15087 prefixIdentifiers,
15088 nodeTransforms: [
15089 ...nodeTransforms,
15090 ...(options.nodeTransforms || []) // user transforms
15091 ],
15092 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
15093 )
15094 }));
15095 return generate(ast, extend({}, options, {
15096 prefixIdentifiers
15097 }));
15098}
15099
15100const noopDirectiveTransform = () => ({ props: [] });
15101
15102const V_MODEL_RADIO = Symbol(`vModelRadio` );
15103const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
15104const V_MODEL_TEXT = Symbol(`vModelText` );
15105const V_MODEL_SELECT = Symbol(`vModelSelect` );
15106const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
15107const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
15108const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
15109const V_SHOW = Symbol(`vShow` );
15110const TRANSITION$1 = Symbol(`Transition` );
15111const TRANSITION_GROUP = Symbol(`TransitionGroup` );
15112registerRuntimeHelpers({
15113 [V_MODEL_RADIO]: `vModelRadio`,
15114 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
15115 [V_MODEL_TEXT]: `vModelText`,
15116 [V_MODEL_SELECT]: `vModelSelect`,
15117 [V_MODEL_DYNAMIC]: `vModelDynamic`,
15118 [V_ON_WITH_MODIFIERS]: `withModifiers`,
15119 [V_ON_WITH_KEYS]: `withKeys`,
15120 [V_SHOW]: `vShow`,
15121 [TRANSITION$1]: `Transition`,
15122 [TRANSITION_GROUP]: `TransitionGroup`
15123});
15124
15125/* eslint-disable no-restricted-globals */
15126let decoder;
15127function decodeHtmlBrowser(raw, asAttr = false) {
15128 if (!decoder) {
15129 decoder = document.createElement('div');
15130 }
15131 if (asAttr) {
15132 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
15133 return decoder.children[0].getAttribute('foo');
15134 }
15135 else {
15136 decoder.innerHTML = raw;
15137 return decoder.textContent;
15138 }
15139}
15140
15141const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
15142const parserOptions = {
15143 isVoidTag,
15144 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
15145 isPreTag: tag => tag === 'pre',
15146 decodeEntities: decodeHtmlBrowser ,
15147 isBuiltInComponent: (tag) => {
15148 if (isBuiltInType(tag, `Transition`)) {
15149 return TRANSITION$1;
15150 }
15151 else if (isBuiltInType(tag, `TransitionGroup`)) {
15152 return TRANSITION_GROUP;
15153 }
15154 },
15155 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
15156 getNamespace(tag, parent) {
15157 let ns = parent ? parent.ns : 0 /* HTML */;
15158 if (parent && ns === 2 /* MATH_ML */) {
15159 if (parent.tag === 'annotation-xml') {
15160 if (tag === 'svg') {
15161 return 1 /* SVG */;
15162 }
15163 if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
15164 a.name === 'encoding' &&
15165 a.value != null &&
15166 (a.value.content === 'text/html' ||
15167 a.value.content === 'application/xhtml+xml'))) {
15168 ns = 0 /* HTML */;
15169 }
15170 }
15171 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
15172 tag !== 'mglyph' &&
15173 tag !== 'malignmark') {
15174 ns = 0 /* HTML */;
15175 }
15176 }
15177 else if (parent && ns === 1 /* SVG */) {
15178 if (parent.tag === 'foreignObject' ||
15179 parent.tag === 'desc' ||
15180 parent.tag === 'title') {
15181 ns = 0 /* HTML */;
15182 }
15183 }
15184 if (ns === 0 /* HTML */) {
15185 if (tag === 'svg') {
15186 return 1 /* SVG */;
15187 }
15188 if (tag === 'math') {
15189 return 2 /* MATH_ML */;
15190 }
15191 }
15192 return ns;
15193 },
15194 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
15195 getTextMode({ tag, ns }) {
15196 if (ns === 0 /* HTML */) {
15197 if (tag === 'textarea' || tag === 'title') {
15198 return 1 /* RCDATA */;
15199 }
15200 if (isRawTextContainer(tag)) {
15201 return 2 /* RAWTEXT */;
15202 }
15203 }
15204 return 0 /* DATA */;
15205 }
15206};
15207
15208// Parse inline CSS strings for static style attributes into an object.
15209// This is a NodeTransform since it works on the static `style` attribute and
15210// converts it into a dynamic equivalent:
15211// style="color: red" -> :style='{ "color": "red" }'
15212// It is then processed by `transformElement` and included in the generated
15213// props.
15214const transformStyle = node => {
15215 if (node.type === 1 /* ELEMENT */) {
15216 node.props.forEach((p, i) => {
15217 if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
15218 // replace p with an expression node
15219 node.props[i] = {
15220 type: 7 /* DIRECTIVE */,
15221 name: `bind`,
15222 arg: createSimpleExpression(`style`, true, p.loc),
15223 exp: parseInlineCSS(p.value.content, p.loc),
15224 modifiers: [],
15225 loc: p.loc
15226 };
15227 }
15228 });
15229 }
15230};
15231const parseInlineCSS = (cssText, loc) => {
15232 const normalized = parseStringStyle(cssText);
15233 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
15234};
15235
15236function createDOMCompilerError(code, loc) {
15237 return createCompilerError(code, loc, DOMErrorMessages );
15238}
15239const DOMErrorMessages = {
15240 [50 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
15241 [51 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
15242 [52 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
15243 [53 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
15244 [54 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
15245 [55 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
15246 [56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
15247 [57 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
15248 [58 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
15249 [59 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
15250 [60 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
15251};
15252
15253const transformVHtml = (dir, node, context) => {
15254 const { exp, loc } = dir;
15255 if (!exp) {
15256 context.onError(createDOMCompilerError(50 /* X_V_HTML_NO_EXPRESSION */, loc));
15257 }
15258 if (node.children.length) {
15259 context.onError(createDOMCompilerError(51 /* X_V_HTML_WITH_CHILDREN */, loc));
15260 node.children.length = 0;
15261 }
15262 return {
15263 props: [
15264 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
15265 ]
15266 };
15267};
15268
15269const transformVText = (dir, node, context) => {
15270 const { exp, loc } = dir;
15271 if (!exp) {
15272 context.onError(createDOMCompilerError(52 /* X_V_TEXT_NO_EXPRESSION */, loc));
15273 }
15274 if (node.children.length) {
15275 context.onError(createDOMCompilerError(53 /* X_V_TEXT_WITH_CHILDREN */, loc));
15276 node.children.length = 0;
15277 }
15278 return {
15279 props: [
15280 createObjectProperty(createSimpleExpression(`textContent`, true), exp
15281 ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
15282 : createSimpleExpression('', true))
15283 ]
15284 };
15285};
15286
15287const transformModel$1 = (dir, node, context) => {
15288 const baseResult = transformModel(dir, node, context);
15289 // base transform has errors OR component v-model (only need props)
15290 if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
15291 return baseResult;
15292 }
15293 if (dir.arg) {
15294 context.onError(createDOMCompilerError(55 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
15295 }
15296 function checkDuplicatedValue() {
15297 const value = findProp(node, 'value');
15298 if (value) {
15299 context.onError(createDOMCompilerError(57 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
15300 }
15301 }
15302 const { tag } = node;
15303 const isCustomElement = context.isCustomElement(tag);
15304 if (tag === 'input' ||
15305 tag === 'textarea' ||
15306 tag === 'select' ||
15307 isCustomElement) {
15308 let directiveToUse = V_MODEL_TEXT;
15309 let isInvalidType = false;
15310 if (tag === 'input' || isCustomElement) {
15311 const type = findProp(node, `type`);
15312 if (type) {
15313 if (type.type === 7 /* DIRECTIVE */) {
15314 // :type="foo"
15315 directiveToUse = V_MODEL_DYNAMIC;
15316 }
15317 else if (type.value) {
15318 switch (type.value.content) {
15319 case 'radio':
15320 directiveToUse = V_MODEL_RADIO;
15321 break;
15322 case 'checkbox':
15323 directiveToUse = V_MODEL_CHECKBOX;
15324 break;
15325 case 'file':
15326 isInvalidType = true;
15327 context.onError(createDOMCompilerError(56 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
15328 break;
15329 default:
15330 // text type
15331 checkDuplicatedValue();
15332 break;
15333 }
15334 }
15335 }
15336 else if (hasDynamicKeyVBind(node)) {
15337 // element has bindings with dynamic keys, which can possibly contain
15338 // "type".
15339 directiveToUse = V_MODEL_DYNAMIC;
15340 }
15341 else {
15342 // text type
15343 checkDuplicatedValue();
15344 }
15345 }
15346 else if (tag === 'select') {
15347 directiveToUse = V_MODEL_SELECT;
15348 }
15349 else {
15350 // textarea
15351 checkDuplicatedValue();
15352 }
15353 // inject runtime directive
15354 // by returning the helper symbol via needRuntime
15355 // the import will replaced a resolveDirective call.
15356 if (!isInvalidType) {
15357 baseResult.needRuntime = context.helper(directiveToUse);
15358 }
15359 }
15360 else {
15361 context.onError(createDOMCompilerError(54 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
15362 }
15363 // native vmodel doesn't need the `modelValue` props since they are also
15364 // passed to the runtime as `binding.value`. removing it reduces code size.
15365 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
15366 p.key.content === 'modelValue'));
15367 return baseResult;
15368};
15369
15370const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
15371const isNonKeyModifier = /*#__PURE__*/ makeMap(
15372// event propagation management
15373`stop,prevent,self,` +
15374 // system modifiers + exact
15375 `ctrl,shift,alt,meta,exact,` +
15376 // mouse
15377 `middle`);
15378// left & right could be mouse or key modifiers based on event type
15379const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
15380const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
15381const resolveModifiers = (key, modifiers, context, loc) => {
15382 const keyModifiers = [];
15383 const nonKeyModifiers = [];
15384 const eventOptionModifiers = [];
15385 for (let i = 0; i < modifiers.length; i++) {
15386 const modifier = modifiers[i];
15387 if (isEventOptionModifier(modifier)) {
15388 // eventOptionModifiers: modifiers for addEventListener() options,
15389 // e.g. .passive & .capture
15390 eventOptionModifiers.push(modifier);
15391 }
15392 else {
15393 // runtimeModifiers: modifiers that needs runtime guards
15394 if (maybeKeyModifier(modifier)) {
15395 if (isStaticExp(key)) {
15396 if (isKeyboardEvent(key.content)) {
15397 keyModifiers.push(modifier);
15398 }
15399 else {
15400 nonKeyModifiers.push(modifier);
15401 }
15402 }
15403 else {
15404 keyModifiers.push(modifier);
15405 nonKeyModifiers.push(modifier);
15406 }
15407 }
15408 else {
15409 if (isNonKeyModifier(modifier)) {
15410 nonKeyModifiers.push(modifier);
15411 }
15412 else {
15413 keyModifiers.push(modifier);
15414 }
15415 }
15416 }
15417 }
15418 return {
15419 keyModifiers,
15420 nonKeyModifiers,
15421 eventOptionModifiers
15422 };
15423};
15424const transformClick = (key, event) => {
15425 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
15426 return isStaticClick
15427 ? createSimpleExpression(event, true)
15428 : key.type !== 4 /* SIMPLE_EXPRESSION */
15429 ? createCompoundExpression([
15430 `(`,
15431 key,
15432 `) === "onClick" ? "${event}" : (`,
15433 key,
15434 `)`
15435 ])
15436 : key;
15437};
15438const transformOn$1 = (dir, node, context) => {
15439 return transformOn(dir, node, context, baseResult => {
15440 const { modifiers } = dir;
15441 if (!modifiers.length)
15442 return baseResult;
15443 let { key, value: handlerExp } = baseResult.props[0];
15444 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
15445 // normalize click.right and click.middle since they don't actually fire
15446 if (nonKeyModifiers.includes('right')) {
15447 key = transformClick(key, `onContextmenu`);
15448 }
15449 if (nonKeyModifiers.includes('middle')) {
15450 key = transformClick(key, `onMouseup`);
15451 }
15452 if (nonKeyModifiers.length) {
15453 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
15454 handlerExp,
15455 JSON.stringify(nonKeyModifiers)
15456 ]);
15457 }
15458 if (keyModifiers.length &&
15459 // if event name is dynamic, always wrap with keys guard
15460 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
15461 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
15462 handlerExp,
15463 JSON.stringify(keyModifiers)
15464 ]);
15465 }
15466 if (eventOptionModifiers.length) {
15467 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
15468 key = isStaticExp(key)
15469 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
15470 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
15471 }
15472 return {
15473 props: [createObjectProperty(key, handlerExp)]
15474 };
15475 });
15476};
15477
15478const transformShow = (dir, node, context) => {
15479 const { exp, loc } = dir;
15480 if (!exp) {
15481 context.onError(createDOMCompilerError(58 /* X_V_SHOW_NO_EXPRESSION */, loc));
15482 }
15483 return {
15484 props: [],
15485 needRuntime: context.helper(V_SHOW)
15486 };
15487};
15488
15489const warnTransitionChildren = (node, context) => {
15490 if (node.type === 1 /* ELEMENT */ &&
15491 node.tagType === 1 /* COMPONENT */) {
15492 const component = context.isBuiltInComponent(node.tag);
15493 if (component === TRANSITION$1) {
15494 return () => {
15495 if (node.children.length && hasMultipleChildren(node)) {
15496 context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
15497 start: node.children[0].loc.start,
15498 end: node.children[node.children.length - 1].loc.end,
15499 source: ''
15500 }));
15501 }
15502 };
15503 }
15504 }
15505};
15506function hasMultipleChildren(node) {
15507 // #1352 filter out potential comment nodes.
15508 const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */ &&
15509 !(c.type === 2 /* TEXT */ && !c.content.trim())));
15510 const child = children[0];
15511 return (children.length !== 1 ||
15512 child.type === 11 /* FOR */ ||
15513 (child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
15514}
15515
15516const ignoreSideEffectTags = (node, context) => {
15517 if (node.type === 1 /* ELEMENT */ &&
15518 node.tagType === 0 /* ELEMENT */ &&
15519 (node.tag === 'script' || node.tag === 'style')) {
15520 context.onError(createDOMCompilerError(60 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
15521 context.removeNode();
15522 }
15523};
15524
15525const DOMNodeTransforms = [
15526 transformStyle,
15527 ...([warnTransitionChildren] )
15528];
15529const DOMDirectiveTransforms = {
15530 cloak: noopDirectiveTransform,
15531 html: transformVHtml,
15532 text: transformVText,
15533 model: transformModel$1,
15534 on: transformOn$1,
15535 show: transformShow
15536};
15537function compile$1(template, options = {}) {
15538 return baseCompile(template, extend({}, parserOptions, options, {
15539 nodeTransforms: [
15540 // ignore <script> and <tag>
15541 // this is not put inside DOMNodeTransforms because that list is used
15542 // by compiler-ssr to generate vnode fallback branches
15543 ignoreSideEffectTags,
15544 ...DOMNodeTransforms,
15545 ...(options.nodeTransforms || [])
15546 ],
15547 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
15548 transformHoist: null
15549 }));
15550}
15551
15552// This entry is the "full-build" that includes both the runtime
15553{
15554 initDev();
15555}
15556const compileCache = Object.create(null);
15557function compileToFunction(template, options) {
15558 if (!isString(template)) {
15559 if (template.nodeType) {
15560 template = template.innerHTML;
15561 }
15562 else {
15563 warn$1(`invalid template option: `, template);
15564 return NOOP;
15565 }
15566 }
15567 const key = template;
15568 const cached = compileCache[key];
15569 if (cached) {
15570 return cached;
15571 }
15572 if (template[0] === '#') {
15573 const el = document.querySelector(template);
15574 if (!el) {
15575 warn$1(`Template element not found or is empty: ${template}`);
15576 }
15577 // __UNSAFE__
15578 // Reason: potential execution of JS expressions in in-DOM template.
15579 // The user must make sure the in-DOM template is trusted. If it's rendered
15580 // by the server, the template should not contain any user data.
15581 template = el ? el.innerHTML : ``;
15582 }
15583 const { code } = compile$1(template, extend({
15584 hoistStatic: true,
15585 onError: onError ,
15586 onWarn: e => onError(e, true)
15587 }, options));
15588 function onError(err, asWarning = false) {
15589 const message = asWarning
15590 ? err.message
15591 : `Template compilation error: ${err.message}`;
15592 const codeFrame = err.loc &&
15593 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
15594 warn$1(codeFrame ? `${message}\n${codeFrame}` : message);
15595 }
15596 // The wildcard import results in a huge object with every export
15597 // with keys that cannot be mangled, and can be quite heavy size-wise.
15598 // In the global build we know `Vue` is available globally so we can avoid
15599 // the wildcard object.
15600 const render = (new Function('Vue', code)(runtimeDom));
15601 render._rc = true;
15602 return (compileCache[key] = render);
15603}
15604registerRuntimeCompiler(compileToFunction);
15605
15606export { BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compileToFunction as compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createBaseVNode as createElementVNode, createHydrationRenderer, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId };