UNPKG

613 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 /* PatchFlags.TEXT */]: `TEXT`,
22 [2 /* PatchFlags.CLASS */]: `CLASS`,
23 [4 /* PatchFlags.STYLE */]: `STYLE`,
24 [8 /* PatchFlags.PROPS */]: `PROPS`,
25 [16 /* PatchFlags.FULL_PROPS */]: `FULL_PROPS`,
26 [32 /* PatchFlags.HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
27 [64 /* PatchFlags.STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
28 [128 /* PatchFlags.KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
29 [256 /* PatchFlags.UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
30 [512 /* PatchFlags.NEED_PATCH */]: `NEED_PATCH`,
31 [1024 /* PatchFlags.DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
32 [2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
33 [-1 /* PatchFlags.HOISTED */]: `HOISTED`,
34 [-2 /* PatchFlags.BAIL */]: `BAIL`
35};
36
37/**
38 * Dev only
39 */
40const slotFlagsText = {
41 [1 /* SlotFlags.STABLE */]: 'STABLE',
42 [2 /* SlotFlags.DYNAMIC */]: 'DYNAMIC',
43 [3 /* SlotFlags.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
95function normalizeStyle(value) {
96 if (isArray(value)) {
97 const res = {};
98 for (let i = 0; i < value.length; i++) {
99 const item = value[i];
100 const normalized = isString(item)
101 ? parseStringStyle(item)
102 : normalizeStyle(item);
103 if (normalized) {
104 for (const key in normalized) {
105 res[key] = normalized[key];
106 }
107 }
108 }
109 return res;
110 }
111 else if (isString(value)) {
112 return value;
113 }
114 else if (isObject(value)) {
115 return value;
116 }
117}
118const listDelimiterRE = /;(?![^(]*\))/g;
119const propertyDelimiterRE = /:([^]+)/;
120const styleCommentRE = /\/\*.*?\*\//gs;
121function parseStringStyle(cssText) {
122 const ret = {};
123 cssText
124 .replace(styleCommentRE, '')
125 .split(listDelimiterRE)
126 .forEach(item => {
127 if (item) {
128 const tmp = item.split(propertyDelimiterRE);
129 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
130 }
131 });
132 return ret;
133}
134function normalizeClass(value) {
135 let res = '';
136 if (isString(value)) {
137 res = value;
138 }
139 else if (isArray(value)) {
140 for (let i = 0; i < value.length; i++) {
141 const normalized = normalizeClass(value[i]);
142 if (normalized) {
143 res += normalized + ' ';
144 }
145 }
146 }
147 else if (isObject(value)) {
148 for (const name in value) {
149 if (value[name]) {
150 res += name + ' ';
151 }
152 }
153 }
154 return res.trim();
155}
156function normalizeProps(props) {
157 if (!props)
158 return null;
159 let { class: klass, style } = props;
160 if (klass && !isString(klass)) {
161 props.class = normalizeClass(klass);
162 }
163 if (style) {
164 props.style = normalizeStyle(style);
165 }
166 return props;
167}
168
169// These tag configs are shared between compiler-dom and runtime-dom, so they
170// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
171const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
172 'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
173 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
174 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
175 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
176 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
177 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
178 'option,output,progress,select,textarea,details,dialog,menu,' +
179 'summary,template,blockquote,iframe,tfoot';
180// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
181const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
182 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
183 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
184 'feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
185 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
186 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
187 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
188 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
189 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
190 'text,textPath,title,tspan,unknown,use,view';
191const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
192/**
193 * Compiler only.
194 * Do NOT use in runtime code paths unless behind `true` flag.
195 */
196const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
197/**
198 * Compiler only.
199 * Do NOT use in runtime code paths unless behind `true` flag.
200 */
201const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
202/**
203 * Compiler only.
204 * Do NOT use in runtime code paths unless behind `true` flag.
205 */
206const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
207
208/**
209 * On the client we only need to offer special cases for boolean attributes that
210 * have different names from their corresponding dom properties:
211 * - itemscope -> N/A
212 * - allowfullscreen -> allowFullscreen
213 * - formnovalidate -> formNoValidate
214 * - ismap -> isMap
215 * - nomodule -> noModule
216 * - novalidate -> noValidate
217 * - readonly -> readOnly
218 */
219const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
220const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
221/**
222 * Boolean attributes should be included if the value is truthy or ''.
223 * e.g. `<select multiple>` compiles to `{ multiple: '' }`
224 */
225function includeBooleanAttr(value) {
226 return !!value || value === '';
227}
228
229function looseCompareArrays(a, b) {
230 if (a.length !== b.length)
231 return false;
232 let equal = true;
233 for (let i = 0; equal && i < a.length; i++) {
234 equal = looseEqual(a[i], b[i]);
235 }
236 return equal;
237}
238function looseEqual(a, b) {
239 if (a === b)
240 return true;
241 let aValidType = isDate(a);
242 let bValidType = isDate(b);
243 if (aValidType || bValidType) {
244 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
245 }
246 aValidType = isSymbol(a);
247 bValidType = isSymbol(b);
248 if (aValidType || bValidType) {
249 return a === b;
250 }
251 aValidType = isArray(a);
252 bValidType = isArray(b);
253 if (aValidType || bValidType) {
254 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
255 }
256 aValidType = isObject(a);
257 bValidType = isObject(b);
258 if (aValidType || bValidType) {
259 /* istanbul ignore if: this if will probably never be called */
260 if (!aValidType || !bValidType) {
261 return false;
262 }
263 const aKeysCount = Object.keys(a).length;
264 const bKeysCount = Object.keys(b).length;
265 if (aKeysCount !== bKeysCount) {
266 return false;
267 }
268 for (const key in a) {
269 const aHasKey = a.hasOwnProperty(key);
270 const bHasKey = b.hasOwnProperty(key);
271 if ((aHasKey && !bHasKey) ||
272 (!aHasKey && bHasKey) ||
273 !looseEqual(a[key], b[key])) {
274 return false;
275 }
276 }
277 }
278 return String(a) === String(b);
279}
280function looseIndexOf(arr, val) {
281 return arr.findIndex(item => looseEqual(item, val));
282}
283
284/**
285 * For converting {{ interpolation }} values to displayed strings.
286 * @private
287 */
288const toDisplayString = (val) => {
289 return isString(val)
290 ? val
291 : val == null
292 ? ''
293 : isArray(val) ||
294 (isObject(val) &&
295 (val.toString === objectToString || !isFunction(val.toString)))
296 ? JSON.stringify(val, replacer, 2)
297 : String(val);
298};
299const replacer = (_key, val) => {
300 // can't use isRef here since @vue/shared has no deps
301 if (val && val.__v_isRef) {
302 return replacer(_key, val.value);
303 }
304 else if (isMap(val)) {
305 return {
306 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
307 entries[`${key} =>`] = val;
308 return entries;
309 }, {})
310 };
311 }
312 else if (isSet(val)) {
313 return {
314 [`Set(${val.size})`]: [...val.values()]
315 };
316 }
317 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
318 return String(val);
319 }
320 return val;
321};
322
323const EMPTY_OBJ = Object.freeze({})
324 ;
325const EMPTY_ARR = Object.freeze([]) ;
326const NOOP = () => { };
327/**
328 * Always return false.
329 */
330const NO = () => false;
331const onRE = /^on[^a-z]/;
332const isOn = (key) => onRE.test(key);
333const isModelListener = (key) => key.startsWith('onUpdate:');
334const extend = Object.assign;
335const remove = (arr, el) => {
336 const i = arr.indexOf(el);
337 if (i > -1) {
338 arr.splice(i, 1);
339 }
340};
341const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
342const hasOwn = (val, key) => hasOwnProperty$1.call(val, key);
343const isArray = Array.isArray;
344const isMap = (val) => toTypeString(val) === '[object Map]';
345const isSet = (val) => toTypeString(val) === '[object Set]';
346const isDate = (val) => toTypeString(val) === '[object Date]';
347const isRegExp = (val) => toTypeString(val) === '[object RegExp]';
348const isFunction = (val) => typeof val === 'function';
349const isString = (val) => typeof val === 'string';
350const isSymbol = (val) => typeof val === 'symbol';
351const isObject = (val) => val !== null && typeof val === 'object';
352const isPromise = (val) => {
353 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
354};
355const objectToString = Object.prototype.toString;
356const toTypeString = (value) => objectToString.call(value);
357const toRawType = (value) => {
358 // extract "RawType" from strings like "[object RawType]"
359 return toTypeString(value).slice(8, -1);
360};
361const isPlainObject = (val) => toTypeString(val) === '[object Object]';
362const isIntegerKey = (key) => isString(key) &&
363 key !== 'NaN' &&
364 key[0] !== '-' &&
365 '' + parseInt(key, 10) === key;
366const isReservedProp = /*#__PURE__*/ makeMap(
367// the leading comma is intentional so empty string "" is also included
368',key,ref,ref_for,ref_key,' +
369 'onVnodeBeforeMount,onVnodeMounted,' +
370 'onVnodeBeforeUpdate,onVnodeUpdated,' +
371 'onVnodeBeforeUnmount,onVnodeUnmounted');
372const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
373const cacheStringFunction = (fn) => {
374 const cache = Object.create(null);
375 return ((str) => {
376 const hit = cache[str];
377 return hit || (cache[str] = fn(str));
378 });
379};
380const camelizeRE = /-(\w)/g;
381/**
382 * @private
383 */
384const camelize = cacheStringFunction((str) => {
385 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
386});
387const hyphenateRE = /\B([A-Z])/g;
388/**
389 * @private
390 */
391const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
392/**
393 * @private
394 */
395const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
396/**
397 * @private
398 */
399const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
400// compare whether a value has changed, accounting for NaN.
401const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
402const invokeArrayFns = (fns, arg) => {
403 for (let i = 0; i < fns.length; i++) {
404 fns[i](arg);
405 }
406};
407const def = (obj, key, value) => {
408 Object.defineProperty(obj, key, {
409 configurable: true,
410 enumerable: false,
411 value
412 });
413};
414/**
415 * "123-foo" will be parsed to 123
416 * This is used for the .number modifier in v-model
417 */
418const looseToNumber = (val) => {
419 const n = parseFloat(val);
420 return isNaN(n) ? val : n;
421};
422/**
423 * Only conerces number-like strings
424 * "123-foo" will be returned as-is
425 */
426const toNumber = (val) => {
427 const n = isString(val) ? Number(val) : NaN;
428 return isNaN(n) ? val : n;
429};
430let _globalThis;
431const getGlobalThis = () => {
432 return (_globalThis ||
433 (_globalThis =
434 typeof globalThis !== 'undefined'
435 ? globalThis
436 : typeof self !== 'undefined'
437 ? self
438 : typeof window !== 'undefined'
439 ? window
440 : typeof global !== 'undefined'
441 ? global
442 : {}));
443};
444
445function warn$1(msg, ...args) {
446 console.warn(`[Vue warn] ${msg}`, ...args);
447}
448
449let activeEffectScope;
450class EffectScope {
451 constructor(detached = false) {
452 this.detached = detached;
453 /**
454 * @internal
455 */
456 this._active = true;
457 /**
458 * @internal
459 */
460 this.effects = [];
461 /**
462 * @internal
463 */
464 this.cleanups = [];
465 this.parent = activeEffectScope;
466 if (!detached && activeEffectScope) {
467 this.index =
468 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
469 }
470 }
471 get active() {
472 return this._active;
473 }
474 run(fn) {
475 if (this._active) {
476 const currentEffectScope = activeEffectScope;
477 try {
478 activeEffectScope = this;
479 return fn();
480 }
481 finally {
482 activeEffectScope = currentEffectScope;
483 }
484 }
485 else {
486 warn$1(`cannot run an inactive effect scope.`);
487 }
488 }
489 /**
490 * This should only be called on non-detached scopes
491 * @internal
492 */
493 on() {
494 activeEffectScope = this;
495 }
496 /**
497 * This should only be called on non-detached scopes
498 * @internal
499 */
500 off() {
501 activeEffectScope = this.parent;
502 }
503 stop(fromParent) {
504 if (this._active) {
505 let i, l;
506 for (i = 0, l = this.effects.length; i < l; i++) {
507 this.effects[i].stop();
508 }
509 for (i = 0, l = this.cleanups.length; i < l; i++) {
510 this.cleanups[i]();
511 }
512 if (this.scopes) {
513 for (i = 0, l = this.scopes.length; i < l; i++) {
514 this.scopes[i].stop(true);
515 }
516 }
517 // nested scope, dereference from parent to avoid memory leaks
518 if (!this.detached && this.parent && !fromParent) {
519 // optimized O(1) removal
520 const last = this.parent.scopes.pop();
521 if (last && last !== this) {
522 this.parent.scopes[this.index] = last;
523 last.index = this.index;
524 }
525 }
526 this.parent = undefined;
527 this._active = false;
528 }
529 }
530}
531function effectScope(detached) {
532 return new EffectScope(detached);
533}
534function recordEffectScope(effect, scope = activeEffectScope) {
535 if (scope && scope.active) {
536 scope.effects.push(effect);
537 }
538}
539function getCurrentScope() {
540 return activeEffectScope;
541}
542function onScopeDispose(fn) {
543 if (activeEffectScope) {
544 activeEffectScope.cleanups.push(fn);
545 }
546 else {
547 warn$1(`onScopeDispose() is called when there is no active effect scope` +
548 ` to be associated with.`);
549 }
550}
551
552const createDep = (effects) => {
553 const dep = new Set(effects);
554 dep.w = 0;
555 dep.n = 0;
556 return dep;
557};
558const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
559const newTracked = (dep) => (dep.n & trackOpBit) > 0;
560const initDepMarkers = ({ deps }) => {
561 if (deps.length) {
562 for (let i = 0; i < deps.length; i++) {
563 deps[i].w |= trackOpBit; // set was tracked
564 }
565 }
566};
567const finalizeDepMarkers = (effect) => {
568 const { deps } = effect;
569 if (deps.length) {
570 let ptr = 0;
571 for (let i = 0; i < deps.length; i++) {
572 const dep = deps[i];
573 if (wasTracked(dep) && !newTracked(dep)) {
574 dep.delete(effect);
575 }
576 else {
577 deps[ptr++] = dep;
578 }
579 // clear bits
580 dep.w &= ~trackOpBit;
581 dep.n &= ~trackOpBit;
582 }
583 deps.length = ptr;
584 }
585};
586
587const targetMap = new WeakMap();
588// The number of effects currently being tracked recursively.
589let effectTrackDepth = 0;
590let trackOpBit = 1;
591/**
592 * The bitwise track markers support at most 30 levels of recursion.
593 * This value is chosen to enable modern JS engines to use a SMI on all platforms.
594 * When recursion depth is greater, fall back to using a full cleanup.
595 */
596const maxMarkerBits = 30;
597let activeEffect;
598const ITERATE_KEY = Symbol('iterate' );
599const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
600class ReactiveEffect {
601 constructor(fn, scheduler = null, scope) {
602 this.fn = fn;
603 this.scheduler = scheduler;
604 this.active = true;
605 this.deps = [];
606 this.parent = undefined;
607 recordEffectScope(this, scope);
608 }
609 run() {
610 if (!this.active) {
611 return this.fn();
612 }
613 let parent = activeEffect;
614 let lastShouldTrack = shouldTrack;
615 while (parent) {
616 if (parent === this) {
617 return;
618 }
619 parent = parent.parent;
620 }
621 try {
622 this.parent = activeEffect;
623 activeEffect = this;
624 shouldTrack = true;
625 trackOpBit = 1 << ++effectTrackDepth;
626 if (effectTrackDepth <= maxMarkerBits) {
627 initDepMarkers(this);
628 }
629 else {
630 cleanupEffect(this);
631 }
632 return this.fn();
633 }
634 finally {
635 if (effectTrackDepth <= maxMarkerBits) {
636 finalizeDepMarkers(this);
637 }
638 trackOpBit = 1 << --effectTrackDepth;
639 activeEffect = this.parent;
640 shouldTrack = lastShouldTrack;
641 this.parent = undefined;
642 if (this.deferStop) {
643 this.stop();
644 }
645 }
646 }
647 stop() {
648 // stopped while running itself - defer the cleanup
649 if (activeEffect === this) {
650 this.deferStop = true;
651 }
652 else if (this.active) {
653 cleanupEffect(this);
654 if (this.onStop) {
655 this.onStop();
656 }
657 this.active = false;
658 }
659 }
660}
661function cleanupEffect(effect) {
662 const { deps } = effect;
663 if (deps.length) {
664 for (let i = 0; i < deps.length; i++) {
665 deps[i].delete(effect);
666 }
667 deps.length = 0;
668 }
669}
670function effect(fn, options) {
671 if (fn.effect) {
672 fn = fn.effect.fn;
673 }
674 const _effect = new ReactiveEffect(fn);
675 if (options) {
676 extend(_effect, options);
677 if (options.scope)
678 recordEffectScope(_effect, options.scope);
679 }
680 if (!options || !options.lazy) {
681 _effect.run();
682 }
683 const runner = _effect.run.bind(_effect);
684 runner.effect = _effect;
685 return runner;
686}
687function stop(runner) {
688 runner.effect.stop();
689}
690let shouldTrack = true;
691const trackStack = [];
692function pauseTracking() {
693 trackStack.push(shouldTrack);
694 shouldTrack = false;
695}
696function resetTracking() {
697 const last = trackStack.pop();
698 shouldTrack = last === undefined ? true : last;
699}
700function track(target, type, key) {
701 if (shouldTrack && activeEffect) {
702 let depsMap = targetMap.get(target);
703 if (!depsMap) {
704 targetMap.set(target, (depsMap = new Map()));
705 }
706 let dep = depsMap.get(key);
707 if (!dep) {
708 depsMap.set(key, (dep = createDep()));
709 }
710 const eventInfo = { effect: activeEffect, target, type, key }
711 ;
712 trackEffects(dep, eventInfo);
713 }
714}
715function trackEffects(dep, debuggerEventExtraInfo) {
716 let shouldTrack = false;
717 if (effectTrackDepth <= maxMarkerBits) {
718 if (!newTracked(dep)) {
719 dep.n |= trackOpBit; // set newly tracked
720 shouldTrack = !wasTracked(dep);
721 }
722 }
723 else {
724 // Full cleanup mode.
725 shouldTrack = !dep.has(activeEffect);
726 }
727 if (shouldTrack) {
728 dep.add(activeEffect);
729 activeEffect.deps.push(dep);
730 if (activeEffect.onTrack) {
731 activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo));
732 }
733 }
734}
735function trigger(target, type, key, newValue, oldValue, oldTarget) {
736 const depsMap = targetMap.get(target);
737 if (!depsMap) {
738 // never been tracked
739 return;
740 }
741 let deps = [];
742 if (type === "clear" /* TriggerOpTypes.CLEAR */) {
743 // collection being cleared
744 // trigger all effects for target
745 deps = [...depsMap.values()];
746 }
747 else if (key === 'length' && isArray(target)) {
748 const newLength = Number(newValue);
749 depsMap.forEach((dep, key) => {
750 if (key === 'length' || key >= newLength) {
751 deps.push(dep);
752 }
753 });
754 }
755 else {
756 // schedule runs for SET | ADD | DELETE
757 if (key !== void 0) {
758 deps.push(depsMap.get(key));
759 }
760 // also run for iteration key on ADD | DELETE | Map.SET
761 switch (type) {
762 case "add" /* TriggerOpTypes.ADD */:
763 if (!isArray(target)) {
764 deps.push(depsMap.get(ITERATE_KEY));
765 if (isMap(target)) {
766 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
767 }
768 }
769 else if (isIntegerKey(key)) {
770 // new index added to array -> length changes
771 deps.push(depsMap.get('length'));
772 }
773 break;
774 case "delete" /* TriggerOpTypes.DELETE */:
775 if (!isArray(target)) {
776 deps.push(depsMap.get(ITERATE_KEY));
777 if (isMap(target)) {
778 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
779 }
780 }
781 break;
782 case "set" /* TriggerOpTypes.SET */:
783 if (isMap(target)) {
784 deps.push(depsMap.get(ITERATE_KEY));
785 }
786 break;
787 }
788 }
789 const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
790 ;
791 if (deps.length === 1) {
792 if (deps[0]) {
793 {
794 triggerEffects(deps[0], eventInfo);
795 }
796 }
797 }
798 else {
799 const effects = [];
800 for (const dep of deps) {
801 if (dep) {
802 effects.push(...dep);
803 }
804 }
805 {
806 triggerEffects(createDep(effects), eventInfo);
807 }
808 }
809}
810function triggerEffects(dep, debuggerEventExtraInfo) {
811 // spread into array for stabilization
812 const effects = isArray(dep) ? dep : [...dep];
813 for (const effect of effects) {
814 if (effect.computed) {
815 triggerEffect(effect, debuggerEventExtraInfo);
816 }
817 }
818 for (const effect of effects) {
819 if (!effect.computed) {
820 triggerEffect(effect, debuggerEventExtraInfo);
821 }
822 }
823}
824function triggerEffect(effect, debuggerEventExtraInfo) {
825 if (effect !== activeEffect || effect.allowRecurse) {
826 if (effect.onTrigger) {
827 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
828 }
829 if (effect.scheduler) {
830 effect.scheduler();
831 }
832 else {
833 effect.run();
834 }
835 }
836}
837function getDepFromReactive(object, key) {
838 var _a;
839 return (_a = targetMap.get(object)) === null || _a === void 0 ? void 0 : _a.get(key);
840}
841
842const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
843const builtInSymbols = new Set(
844/*#__PURE__*/
845Object.getOwnPropertyNames(Symbol)
846 // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
847 // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
848 // function
849 .filter(key => key !== 'arguments' && key !== 'caller')
850 .map(key => Symbol[key])
851 .filter(isSymbol));
852const get$1 = /*#__PURE__*/ createGetter();
853const shallowGet = /*#__PURE__*/ createGetter(false, true);
854const readonlyGet = /*#__PURE__*/ createGetter(true);
855const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
856const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
857function createArrayInstrumentations() {
858 const instrumentations = {};
859 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
860 instrumentations[key] = function (...args) {
861 const arr = toRaw(this);
862 for (let i = 0, l = this.length; i < l; i++) {
863 track(arr, "get" /* TrackOpTypes.GET */, i + '');
864 }
865 // we run the method using the original args first (which may be reactive)
866 const res = arr[key](...args);
867 if (res === -1 || res === false) {
868 // if that didn't work, run it again using raw values.
869 return arr[key](...args.map(toRaw));
870 }
871 else {
872 return res;
873 }
874 };
875 });
876 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
877 instrumentations[key] = function (...args) {
878 pauseTracking();
879 const res = toRaw(this)[key].apply(this, args);
880 resetTracking();
881 return res;
882 };
883 });
884 return instrumentations;
885}
886function hasOwnProperty(key) {
887 const obj = toRaw(this);
888 track(obj, "has" /* TrackOpTypes.HAS */, key);
889 return obj.hasOwnProperty(key);
890}
891function createGetter(isReadonly = false, shallow = false) {
892 return function get(target, key, receiver) {
893 if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) {
894 return !isReadonly;
895 }
896 else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) {
897 return isReadonly;
898 }
899 else if (key === "__v_isShallow" /* ReactiveFlags.IS_SHALLOW */) {
900 return shallow;
901 }
902 else if (key === "__v_raw" /* ReactiveFlags.RAW */ &&
903 receiver ===
904 (isReadonly
905 ? shallow
906 ? shallowReadonlyMap
907 : readonlyMap
908 : shallow
909 ? shallowReactiveMap
910 : reactiveMap).get(target)) {
911 return target;
912 }
913 const targetIsArray = isArray(target);
914 if (!isReadonly) {
915 if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
916 return Reflect.get(arrayInstrumentations, key, receiver);
917 }
918 if (key === 'hasOwnProperty') {
919 return hasOwnProperty;
920 }
921 }
922 const res = Reflect.get(target, key, receiver);
923 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
924 return res;
925 }
926 if (!isReadonly) {
927 track(target, "get" /* TrackOpTypes.GET */, key);
928 }
929 if (shallow) {
930 return res;
931 }
932 if (isRef(res)) {
933 // ref unwrapping - skip unwrap for Array + integer key.
934 return targetIsArray && isIntegerKey(key) ? res : res.value;
935 }
936 if (isObject(res)) {
937 // Convert returned value into a proxy as well. we do the isObject check
938 // here to avoid invalid value warning. Also need to lazy access readonly
939 // and reactive here to avoid circular dependency.
940 return isReadonly ? readonly(res) : reactive(res);
941 }
942 return res;
943 };
944}
945const set$1 = /*#__PURE__*/ createSetter();
946const shallowSet = /*#__PURE__*/ createSetter(true);
947function createSetter(shallow = false) {
948 return function set(target, key, value, receiver) {
949 let oldValue = target[key];
950 if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
951 return false;
952 }
953 if (!shallow) {
954 if (!isShallow(value) && !isReadonly(value)) {
955 oldValue = toRaw(oldValue);
956 value = toRaw(value);
957 }
958 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
959 oldValue.value = value;
960 return true;
961 }
962 }
963 const hadKey = isArray(target) && isIntegerKey(key)
964 ? Number(key) < target.length
965 : hasOwn(target, key);
966 const result = Reflect.set(target, key, value, receiver);
967 // don't trigger if target is something up in the prototype chain of original
968 if (target === toRaw(receiver)) {
969 if (!hadKey) {
970 trigger(target, "add" /* TriggerOpTypes.ADD */, key, value);
971 }
972 else if (hasChanged(value, oldValue)) {
973 trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue);
974 }
975 }
976 return result;
977 };
978}
979function deleteProperty(target, key) {
980 const hadKey = hasOwn(target, key);
981 const oldValue = target[key];
982 const result = Reflect.deleteProperty(target, key);
983 if (result && hadKey) {
984 trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue);
985 }
986 return result;
987}
988function has$1(target, key) {
989 const result = Reflect.has(target, key);
990 if (!isSymbol(key) || !builtInSymbols.has(key)) {
991 track(target, "has" /* TrackOpTypes.HAS */, key);
992 }
993 return result;
994}
995function ownKeys(target) {
996 track(target, "iterate" /* TrackOpTypes.ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
997 return Reflect.ownKeys(target);
998}
999const mutableHandlers = {
1000 get: get$1,
1001 set: set$1,
1002 deleteProperty,
1003 has: has$1,
1004 ownKeys
1005};
1006const readonlyHandlers = {
1007 get: readonlyGet,
1008 set(target, key) {
1009 {
1010 warn$1(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
1011 }
1012 return true;
1013 },
1014 deleteProperty(target, key) {
1015 {
1016 warn$1(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
1017 }
1018 return true;
1019 }
1020};
1021const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
1022 get: shallowGet,
1023 set: shallowSet
1024});
1025// Props handlers are special in the sense that it should not unwrap top-level
1026// refs (in order to allow refs to be explicitly passed down), but should
1027// retain the reactivity of the normal readonly object.
1028const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
1029 get: shallowReadonlyGet
1030});
1031
1032const toShallow = (value) => value;
1033const getProto = (v) => Reflect.getPrototypeOf(v);
1034function get(target, key, isReadonly = false, isShallow = false) {
1035 // #1772: readonly(reactive(Map)) should return readonly + reactive version
1036 // of the value
1037 target = target["__v_raw" /* ReactiveFlags.RAW */];
1038 const rawTarget = toRaw(target);
1039 const rawKey = toRaw(key);
1040 if (!isReadonly) {
1041 if (key !== rawKey) {
1042 track(rawTarget, "get" /* TrackOpTypes.GET */, key);
1043 }
1044 track(rawTarget, "get" /* TrackOpTypes.GET */, rawKey);
1045 }
1046 const { has } = getProto(rawTarget);
1047 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1048 if (has.call(rawTarget, key)) {
1049 return wrap(target.get(key));
1050 }
1051 else if (has.call(rawTarget, rawKey)) {
1052 return wrap(target.get(rawKey));
1053 }
1054 else if (target !== rawTarget) {
1055 // #3602 readonly(reactive(Map))
1056 // ensure that the nested reactive `Map` can do tracking for itself
1057 target.get(key);
1058 }
1059}
1060function has(key, isReadonly = false) {
1061 const target = this["__v_raw" /* ReactiveFlags.RAW */];
1062 const rawTarget = toRaw(target);
1063 const rawKey = toRaw(key);
1064 if (!isReadonly) {
1065 if (key !== rawKey) {
1066 track(rawTarget, "has" /* TrackOpTypes.HAS */, key);
1067 }
1068 track(rawTarget, "has" /* TrackOpTypes.HAS */, rawKey);
1069 }
1070 return key === rawKey
1071 ? target.has(key)
1072 : target.has(key) || target.has(rawKey);
1073}
1074function size(target, isReadonly = false) {
1075 target = target["__v_raw" /* ReactiveFlags.RAW */];
1076 !isReadonly && track(toRaw(target), "iterate" /* TrackOpTypes.ITERATE */, ITERATE_KEY);
1077 return Reflect.get(target, 'size', target);
1078}
1079function add(value) {
1080 value = toRaw(value);
1081 const target = toRaw(this);
1082 const proto = getProto(target);
1083 const hadKey = proto.has.call(target, value);
1084 if (!hadKey) {
1085 target.add(value);
1086 trigger(target, "add" /* TriggerOpTypes.ADD */, value, value);
1087 }
1088 return this;
1089}
1090function set(key, value) {
1091 value = toRaw(value);
1092 const target = toRaw(this);
1093 const { has, get } = getProto(target);
1094 let hadKey = has.call(target, key);
1095 if (!hadKey) {
1096 key = toRaw(key);
1097 hadKey = has.call(target, key);
1098 }
1099 else {
1100 checkIdentityKeys(target, has, key);
1101 }
1102 const oldValue = get.call(target, key);
1103 target.set(key, value);
1104 if (!hadKey) {
1105 trigger(target, "add" /* TriggerOpTypes.ADD */, key, value);
1106 }
1107 else if (hasChanged(value, oldValue)) {
1108 trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue);
1109 }
1110 return this;
1111}
1112function deleteEntry(key) {
1113 const target = toRaw(this);
1114 const { has, get } = getProto(target);
1115 let hadKey = has.call(target, key);
1116 if (!hadKey) {
1117 key = toRaw(key);
1118 hadKey = has.call(target, key);
1119 }
1120 else {
1121 checkIdentityKeys(target, has, key);
1122 }
1123 const oldValue = get ? get.call(target, key) : undefined;
1124 // forward the operation before queueing reactions
1125 const result = target.delete(key);
1126 if (hadKey) {
1127 trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue);
1128 }
1129 return result;
1130}
1131function clear() {
1132 const target = toRaw(this);
1133 const hadItems = target.size !== 0;
1134 const oldTarget = isMap(target)
1135 ? new Map(target)
1136 : new Set(target)
1137 ;
1138 // forward the operation before queueing reactions
1139 const result = target.clear();
1140 if (hadItems) {
1141 trigger(target, "clear" /* TriggerOpTypes.CLEAR */, undefined, undefined, oldTarget);
1142 }
1143 return result;
1144}
1145function createForEach(isReadonly, isShallow) {
1146 return function forEach(callback, thisArg) {
1147 const observed = this;
1148 const target = observed["__v_raw" /* ReactiveFlags.RAW */];
1149 const rawTarget = toRaw(target);
1150 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1151 !isReadonly && track(rawTarget, "iterate" /* TrackOpTypes.ITERATE */, ITERATE_KEY);
1152 return target.forEach((value, key) => {
1153 // important: make sure the callback is
1154 // 1. invoked with the reactive map as `this` and 3rd arg
1155 // 2. the value received should be a corresponding reactive/readonly.
1156 return callback.call(thisArg, wrap(value), wrap(key), observed);
1157 });
1158 };
1159}
1160function createIterableMethod(method, isReadonly, isShallow) {
1161 return function (...args) {
1162 const target = this["__v_raw" /* ReactiveFlags.RAW */];
1163 const rawTarget = toRaw(target);
1164 const targetIsMap = isMap(rawTarget);
1165 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
1166 const isKeyOnly = method === 'keys' && targetIsMap;
1167 const innerIterator = target[method](...args);
1168 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1169 !isReadonly &&
1170 track(rawTarget, "iterate" /* TrackOpTypes.ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
1171 // return a wrapped iterator which returns observed versions of the
1172 // values emitted from the real iterator
1173 return {
1174 // iterator protocol
1175 next() {
1176 const { value, done } = innerIterator.next();
1177 return done
1178 ? { value, done }
1179 : {
1180 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1181 done
1182 };
1183 },
1184 // iterable protocol
1185 [Symbol.iterator]() {
1186 return this;
1187 }
1188 };
1189 };
1190}
1191function createReadonlyMethod(type) {
1192 return function (...args) {
1193 {
1194 const key = args[0] ? `on key "${args[0]}" ` : ``;
1195 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
1196 }
1197 return type === "delete" /* TriggerOpTypes.DELETE */ ? false : this;
1198 };
1199}
1200function createInstrumentations() {
1201 const mutableInstrumentations = {
1202 get(key) {
1203 return get(this, key);
1204 },
1205 get size() {
1206 return size(this);
1207 },
1208 has,
1209 add,
1210 set,
1211 delete: deleteEntry,
1212 clear,
1213 forEach: createForEach(false, false)
1214 };
1215 const shallowInstrumentations = {
1216 get(key) {
1217 return get(this, key, false, true);
1218 },
1219 get size() {
1220 return size(this);
1221 },
1222 has,
1223 add,
1224 set,
1225 delete: deleteEntry,
1226 clear,
1227 forEach: createForEach(false, true)
1228 };
1229 const readonlyInstrumentations = {
1230 get(key) {
1231 return get(this, key, true);
1232 },
1233 get size() {
1234 return size(this, true);
1235 },
1236 has(key) {
1237 return has.call(this, key, true);
1238 },
1239 add: createReadonlyMethod("add" /* TriggerOpTypes.ADD */),
1240 set: createReadonlyMethod("set" /* TriggerOpTypes.SET */),
1241 delete: createReadonlyMethod("delete" /* TriggerOpTypes.DELETE */),
1242 clear: createReadonlyMethod("clear" /* TriggerOpTypes.CLEAR */),
1243 forEach: createForEach(true, false)
1244 };
1245 const shallowReadonlyInstrumentations = {
1246 get(key) {
1247 return get(this, key, true, true);
1248 },
1249 get size() {
1250 return size(this, true);
1251 },
1252 has(key) {
1253 return has.call(this, key, true);
1254 },
1255 add: createReadonlyMethod("add" /* TriggerOpTypes.ADD */),
1256 set: createReadonlyMethod("set" /* TriggerOpTypes.SET */),
1257 delete: createReadonlyMethod("delete" /* TriggerOpTypes.DELETE */),
1258 clear: createReadonlyMethod("clear" /* TriggerOpTypes.CLEAR */),
1259 forEach: createForEach(true, true)
1260 };
1261 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
1262 iteratorMethods.forEach(method => {
1263 mutableInstrumentations[method] = createIterableMethod(method, false, false);
1264 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
1265 shallowInstrumentations[method] = createIterableMethod(method, false, true);
1266 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
1267 });
1268 return [
1269 mutableInstrumentations,
1270 readonlyInstrumentations,
1271 shallowInstrumentations,
1272 shallowReadonlyInstrumentations
1273 ];
1274}
1275const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
1276function createInstrumentationGetter(isReadonly, shallow) {
1277 const instrumentations = shallow
1278 ? isReadonly
1279 ? shallowReadonlyInstrumentations
1280 : shallowInstrumentations
1281 : isReadonly
1282 ? readonlyInstrumentations
1283 : mutableInstrumentations;
1284 return (target, key, receiver) => {
1285 if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) {
1286 return !isReadonly;
1287 }
1288 else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) {
1289 return isReadonly;
1290 }
1291 else if (key === "__v_raw" /* ReactiveFlags.RAW */) {
1292 return target;
1293 }
1294 return Reflect.get(hasOwn(instrumentations, key) && key in target
1295 ? instrumentations
1296 : target, key, receiver);
1297 };
1298}
1299const mutableCollectionHandlers = {
1300 get: /*#__PURE__*/ createInstrumentationGetter(false, false)
1301};
1302const shallowCollectionHandlers = {
1303 get: /*#__PURE__*/ createInstrumentationGetter(false, true)
1304};
1305const readonlyCollectionHandlers = {
1306 get: /*#__PURE__*/ createInstrumentationGetter(true, false)
1307};
1308const shallowReadonlyCollectionHandlers = {
1309 get: /*#__PURE__*/ createInstrumentationGetter(true, true)
1310};
1311function checkIdentityKeys(target, has, key) {
1312 const rawKey = toRaw(key);
1313 if (rawKey !== key && has.call(target, rawKey)) {
1314 const type = toRawType(target);
1315 console.warn(`Reactive ${type} contains both the raw and reactive ` +
1316 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
1317 `which can lead to inconsistencies. ` +
1318 `Avoid differentiating between the raw and reactive versions ` +
1319 `of an object and only use the reactive version if possible.`);
1320 }
1321}
1322
1323const reactiveMap = new WeakMap();
1324const shallowReactiveMap = new WeakMap();
1325const readonlyMap = new WeakMap();
1326const shallowReadonlyMap = new WeakMap();
1327function targetTypeMap(rawType) {
1328 switch (rawType) {
1329 case 'Object':
1330 case 'Array':
1331 return 1 /* TargetType.COMMON */;
1332 case 'Map':
1333 case 'Set':
1334 case 'WeakMap':
1335 case 'WeakSet':
1336 return 2 /* TargetType.COLLECTION */;
1337 default:
1338 return 0 /* TargetType.INVALID */;
1339 }
1340}
1341function getTargetType(value) {
1342 return value["__v_skip" /* ReactiveFlags.SKIP */] || !Object.isExtensible(value)
1343 ? 0 /* TargetType.INVALID */
1344 : targetTypeMap(toRawType(value));
1345}
1346function reactive(target) {
1347 // if trying to observe a readonly proxy, return the readonly version.
1348 if (isReadonly(target)) {
1349 return target;
1350 }
1351 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1352}
1353/**
1354 * Return a shallowly-reactive copy of the original object, where only the root
1355 * level properties are reactive. It also does not auto-unwrap refs (even at the
1356 * root level).
1357 */
1358function shallowReactive(target) {
1359 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1360}
1361/**
1362 * Creates a readonly copy of the original object. Note the returned copy is not
1363 * made reactive, but `readonly` can be called on an already reactive object.
1364 */
1365function readonly(target) {
1366 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1367}
1368/**
1369 * Returns a reactive-copy of the original object, where only the root level
1370 * properties are readonly, and does NOT unwrap refs nor recursively convert
1371 * returned properties.
1372 * This is used for creating the props proxy object for stateful components.
1373 */
1374function shallowReadonly(target) {
1375 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1376}
1377function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1378 if (!isObject(target)) {
1379 {
1380 console.warn(`value cannot be made reactive: ${String(target)}`);
1381 }
1382 return target;
1383 }
1384 // target is already a Proxy, return it.
1385 // exception: calling readonly() on a reactive object
1386 if (target["__v_raw" /* ReactiveFlags.RAW */] &&
1387 !(isReadonly && target["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */])) {
1388 return target;
1389 }
1390 // target already has corresponding Proxy
1391 const existingProxy = proxyMap.get(target);
1392 if (existingProxy) {
1393 return existingProxy;
1394 }
1395 // only specific value types can be observed.
1396 const targetType = getTargetType(target);
1397 if (targetType === 0 /* TargetType.INVALID */) {
1398 return target;
1399 }
1400 const proxy = new Proxy(target, targetType === 2 /* TargetType.COLLECTION */ ? collectionHandlers : baseHandlers);
1401 proxyMap.set(target, proxy);
1402 return proxy;
1403}
1404function isReactive(value) {
1405 if (isReadonly(value)) {
1406 return isReactive(value["__v_raw" /* ReactiveFlags.RAW */]);
1407 }
1408 return !!(value && value["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */]);
1409}
1410function isReadonly(value) {
1411 return !!(value && value["__v_isReadonly" /* ReactiveFlags.IS_READONLY */]);
1412}
1413function isShallow(value) {
1414 return !!(value && value["__v_isShallow" /* ReactiveFlags.IS_SHALLOW */]);
1415}
1416function isProxy(value) {
1417 return isReactive(value) || isReadonly(value);
1418}
1419function toRaw(observed) {
1420 const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */];
1421 return raw ? toRaw(raw) : observed;
1422}
1423function markRaw(value) {
1424 def(value, "__v_skip" /* ReactiveFlags.SKIP */, true);
1425 return value;
1426}
1427const toReactive = (value) => isObject(value) ? reactive(value) : value;
1428const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1429
1430function trackRefValue(ref) {
1431 if (shouldTrack && activeEffect) {
1432 ref = toRaw(ref);
1433 {
1434 trackEffects(ref.dep || (ref.dep = createDep()), {
1435 target: ref,
1436 type: "get" /* TrackOpTypes.GET */,
1437 key: 'value'
1438 });
1439 }
1440 }
1441}
1442function triggerRefValue(ref, newVal) {
1443 ref = toRaw(ref);
1444 const dep = ref.dep;
1445 if (dep) {
1446 {
1447 triggerEffects(dep, {
1448 target: ref,
1449 type: "set" /* TriggerOpTypes.SET */,
1450 key: 'value',
1451 newValue: newVal
1452 });
1453 }
1454 }
1455}
1456function isRef(r) {
1457 return !!(r && r.__v_isRef === true);
1458}
1459function ref(value) {
1460 return createRef(value, false);
1461}
1462function shallowRef(value) {
1463 return createRef(value, true);
1464}
1465function createRef(rawValue, shallow) {
1466 if (isRef(rawValue)) {
1467 return rawValue;
1468 }
1469 return new RefImpl(rawValue, shallow);
1470}
1471class RefImpl {
1472 constructor(value, __v_isShallow) {
1473 this.__v_isShallow = __v_isShallow;
1474 this.dep = undefined;
1475 this.__v_isRef = true;
1476 this._rawValue = __v_isShallow ? value : toRaw(value);
1477 this._value = __v_isShallow ? value : toReactive(value);
1478 }
1479 get value() {
1480 trackRefValue(this);
1481 return this._value;
1482 }
1483 set value(newVal) {
1484 const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
1485 newVal = useDirectValue ? newVal : toRaw(newVal);
1486 if (hasChanged(newVal, this._rawValue)) {
1487 this._rawValue = newVal;
1488 this._value = useDirectValue ? newVal : toReactive(newVal);
1489 triggerRefValue(this, newVal);
1490 }
1491 }
1492}
1493function triggerRef(ref) {
1494 triggerRefValue(ref, ref.value );
1495}
1496function unref(ref) {
1497 return isRef(ref) ? ref.value : ref;
1498}
1499const shallowUnwrapHandlers = {
1500 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1501 set: (target, key, value, receiver) => {
1502 const oldValue = target[key];
1503 if (isRef(oldValue) && !isRef(value)) {
1504 oldValue.value = value;
1505 return true;
1506 }
1507 else {
1508 return Reflect.set(target, key, value, receiver);
1509 }
1510 }
1511};
1512function proxyRefs(objectWithRefs) {
1513 return isReactive(objectWithRefs)
1514 ? objectWithRefs
1515 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1516}
1517class CustomRefImpl {
1518 constructor(factory) {
1519 this.dep = undefined;
1520 this.__v_isRef = true;
1521 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
1522 this._get = get;
1523 this._set = set;
1524 }
1525 get value() {
1526 return this._get();
1527 }
1528 set value(newVal) {
1529 this._set(newVal);
1530 }
1531}
1532function customRef(factory) {
1533 return new CustomRefImpl(factory);
1534}
1535function toRefs(object) {
1536 if (!isProxy(object)) {
1537 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1538 }
1539 const ret = isArray(object) ? new Array(object.length) : {};
1540 for (const key in object) {
1541 ret[key] = toRef(object, key);
1542 }
1543 return ret;
1544}
1545class ObjectRefImpl {
1546 constructor(_object, _key, _defaultValue) {
1547 this._object = _object;
1548 this._key = _key;
1549 this._defaultValue = _defaultValue;
1550 this.__v_isRef = true;
1551 }
1552 get value() {
1553 const val = this._object[this._key];
1554 return val === undefined ? this._defaultValue : val;
1555 }
1556 set value(newVal) {
1557 this._object[this._key] = newVal;
1558 }
1559 get dep() {
1560 return getDepFromReactive(toRaw(this._object), this._key);
1561 }
1562}
1563function toRef(object, key, defaultValue) {
1564 const val = object[key];
1565 return isRef(val)
1566 ? val
1567 : new ObjectRefImpl(object, key, defaultValue);
1568}
1569
1570var _a;
1571class ComputedRefImpl {
1572 constructor(getter, _setter, isReadonly, isSSR) {
1573 this._setter = _setter;
1574 this.dep = undefined;
1575 this.__v_isRef = true;
1576 this[_a] = false;
1577 this._dirty = true;
1578 this.effect = new ReactiveEffect(getter, () => {
1579 if (!this._dirty) {
1580 this._dirty = true;
1581 triggerRefValue(this);
1582 }
1583 });
1584 this.effect.computed = this;
1585 this.effect.active = this._cacheable = !isSSR;
1586 this["__v_isReadonly" /* ReactiveFlags.IS_READONLY */] = isReadonly;
1587 }
1588 get value() {
1589 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1590 const self = toRaw(this);
1591 trackRefValue(self);
1592 if (self._dirty || !self._cacheable) {
1593 self._dirty = false;
1594 self._value = self.effect.run();
1595 }
1596 return self._value;
1597 }
1598 set value(newValue) {
1599 this._setter(newValue);
1600 }
1601}
1602_a = "__v_isReadonly" /* ReactiveFlags.IS_READONLY */;
1603function computed$1(getterOrOptions, debugOptions, isSSR = false) {
1604 let getter;
1605 let setter;
1606 const onlyGetter = isFunction(getterOrOptions);
1607 if (onlyGetter) {
1608 getter = getterOrOptions;
1609 setter = () => {
1610 console.warn('Write operation failed: computed value is readonly');
1611 }
1612 ;
1613 }
1614 else {
1615 getter = getterOrOptions.get;
1616 setter = getterOrOptions.set;
1617 }
1618 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1619 if (debugOptions && !isSSR) {
1620 cRef.effect.onTrack = debugOptions.onTrack;
1621 cRef.effect.onTrigger = debugOptions.onTrigger;
1622 }
1623 return cRef;
1624}
1625
1626const stack = [];
1627function pushWarningContext(vnode) {
1628 stack.push(vnode);
1629}
1630function popWarningContext() {
1631 stack.pop();
1632}
1633function warn(msg, ...args) {
1634 // avoid props formatting or warn handler tracking deps that might be mutated
1635 // during patch, leading to infinite recursion.
1636 pauseTracking();
1637 const instance = stack.length ? stack[stack.length - 1].component : null;
1638 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1639 const trace = getComponentTrace();
1640 if (appWarnHandler) {
1641 callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [
1642 msg + args.join(''),
1643 instance && instance.proxy,
1644 trace
1645 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1646 .join('\n'),
1647 trace
1648 ]);
1649 }
1650 else {
1651 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1652 /* istanbul ignore if */
1653 if (trace.length &&
1654 // avoid spamming console during tests
1655 !false) {
1656 warnArgs.push(`\n`, ...formatTrace(trace));
1657 }
1658 console.warn(...warnArgs);
1659 }
1660 resetTracking();
1661}
1662function getComponentTrace() {
1663 let currentVNode = stack[stack.length - 1];
1664 if (!currentVNode) {
1665 return [];
1666 }
1667 // we can't just use the stack because it will be incomplete during updates
1668 // that did not start from the root. Re-construct the parent chain using
1669 // instance parent pointers.
1670 const normalizedStack = [];
1671 while (currentVNode) {
1672 const last = normalizedStack[0];
1673 if (last && last.vnode === currentVNode) {
1674 last.recurseCount++;
1675 }
1676 else {
1677 normalizedStack.push({
1678 vnode: currentVNode,
1679 recurseCount: 0
1680 });
1681 }
1682 const parentInstance = currentVNode.component && currentVNode.component.parent;
1683 currentVNode = parentInstance && parentInstance.vnode;
1684 }
1685 return normalizedStack;
1686}
1687/* istanbul ignore next */
1688function formatTrace(trace) {
1689 const logs = [];
1690 trace.forEach((entry, i) => {
1691 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1692 });
1693 return logs;
1694}
1695function formatTraceEntry({ vnode, recurseCount }) {
1696 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1697 const isRoot = vnode.component ? vnode.component.parent == null : false;
1698 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1699 const close = `>` + postfix;
1700 return vnode.props
1701 ? [open, ...formatProps(vnode.props), close]
1702 : [open + close];
1703}
1704/* istanbul ignore next */
1705function formatProps(props) {
1706 const res = [];
1707 const keys = Object.keys(props);
1708 keys.slice(0, 3).forEach(key => {
1709 res.push(...formatProp(key, props[key]));
1710 });
1711 if (keys.length > 3) {
1712 res.push(` ...`);
1713 }
1714 return res;
1715}
1716/* istanbul ignore next */
1717function formatProp(key, value, raw) {
1718 if (isString(value)) {
1719 value = JSON.stringify(value);
1720 return raw ? value : [`${key}=${value}`];
1721 }
1722 else if (typeof value === 'number' ||
1723 typeof value === 'boolean' ||
1724 value == null) {
1725 return raw ? value : [`${key}=${value}`];
1726 }
1727 else if (isRef(value)) {
1728 value = formatProp(key, toRaw(value.value), true);
1729 return raw ? value : [`${key}=Ref<`, value, `>`];
1730 }
1731 else if (isFunction(value)) {
1732 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1733 }
1734 else {
1735 value = toRaw(value);
1736 return raw ? value : [`${key}=`, value];
1737 }
1738}
1739/**
1740 * @internal
1741 */
1742function assertNumber(val, type) {
1743 if (val === undefined) {
1744 return;
1745 }
1746 else if (typeof val !== 'number') {
1747 warn(`${type} is not a valid number - ` + `got ${JSON.stringify(val)}.`);
1748 }
1749 else if (isNaN(val)) {
1750 warn(`${type} is NaN - ` + 'the duration expression might be incorrect.');
1751 }
1752}
1753
1754const ErrorTypeStrings = {
1755 ["sp" /* LifecycleHooks.SERVER_PREFETCH */]: 'serverPrefetch hook',
1756 ["bc" /* LifecycleHooks.BEFORE_CREATE */]: 'beforeCreate hook',
1757 ["c" /* LifecycleHooks.CREATED */]: 'created hook',
1758 ["bm" /* LifecycleHooks.BEFORE_MOUNT */]: 'beforeMount hook',
1759 ["m" /* LifecycleHooks.MOUNTED */]: 'mounted hook',
1760 ["bu" /* LifecycleHooks.BEFORE_UPDATE */]: 'beforeUpdate hook',
1761 ["u" /* LifecycleHooks.UPDATED */]: 'updated',
1762 ["bum" /* LifecycleHooks.BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1763 ["um" /* LifecycleHooks.UNMOUNTED */]: 'unmounted hook',
1764 ["a" /* LifecycleHooks.ACTIVATED */]: 'activated hook',
1765 ["da" /* LifecycleHooks.DEACTIVATED */]: 'deactivated hook',
1766 ["ec" /* LifecycleHooks.ERROR_CAPTURED */]: 'errorCaptured hook',
1767 ["rtc" /* LifecycleHooks.RENDER_TRACKED */]: 'renderTracked hook',
1768 ["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook',
1769 [0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function',
1770 [1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function',
1771 [2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter',
1772 [3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback',
1773 [4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function',
1774 [5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler',
1775 [6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler',
1776 [7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook',
1777 [8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook',
1778 [9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook',
1779 [10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler',
1780 [11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler',
1781 [12 /* ErrorCodes.FUNCTION_REF */]: 'ref function',
1782 [13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader',
1783 [14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1784 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
1785};
1786function callWithErrorHandling(fn, instance, type, args) {
1787 let res;
1788 try {
1789 res = args ? fn(...args) : fn();
1790 }
1791 catch (err) {
1792 handleError(err, instance, type);
1793 }
1794 return res;
1795}
1796function callWithAsyncErrorHandling(fn, instance, type, args) {
1797 if (isFunction(fn)) {
1798 const res = callWithErrorHandling(fn, instance, type, args);
1799 if (res && isPromise(res)) {
1800 res.catch(err => {
1801 handleError(err, instance, type);
1802 });
1803 }
1804 return res;
1805 }
1806 const values = [];
1807 for (let i = 0; i < fn.length; i++) {
1808 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1809 }
1810 return values;
1811}
1812function handleError(err, instance, type, throwInDev = true) {
1813 const contextVNode = instance ? instance.vnode : null;
1814 if (instance) {
1815 let cur = instance.parent;
1816 // the exposed instance is the render proxy to keep it consistent with 2.x
1817 const exposedInstance = instance.proxy;
1818 // in production the hook receives only the error code
1819 const errorInfo = ErrorTypeStrings[type] ;
1820 while (cur) {
1821 const errorCapturedHooks = cur.ec;
1822 if (errorCapturedHooks) {
1823 for (let i = 0; i < errorCapturedHooks.length; i++) {
1824 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1825 return;
1826 }
1827 }
1828 }
1829 cur = cur.parent;
1830 }
1831 // app-level handling
1832 const appErrorHandler = instance.appContext.config.errorHandler;
1833 if (appErrorHandler) {
1834 callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1835 return;
1836 }
1837 }
1838 logError(err, type, contextVNode, throwInDev);
1839}
1840function logError(err, type, contextVNode, throwInDev = true) {
1841 {
1842 const info = ErrorTypeStrings[type];
1843 if (contextVNode) {
1844 pushWarningContext(contextVNode);
1845 }
1846 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1847 if (contextVNode) {
1848 popWarningContext();
1849 }
1850 // crash in dev by default so it's more noticeable
1851 if (throwInDev) {
1852 throw err;
1853 }
1854 else {
1855 console.error(err);
1856 }
1857 }
1858}
1859
1860let isFlushing = false;
1861let isFlushPending = false;
1862const queue = [];
1863let flushIndex = 0;
1864const pendingPostFlushCbs = [];
1865let activePostFlushCbs = null;
1866let postFlushIndex = 0;
1867const resolvedPromise = /*#__PURE__*/ Promise.resolve();
1868let currentFlushPromise = null;
1869const RECURSION_LIMIT = 100;
1870function nextTick(fn) {
1871 const p = currentFlushPromise || resolvedPromise;
1872 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1873}
1874// #2768
1875// Use binary-search to find a suitable position in the queue,
1876// so that the queue maintains the increasing order of job's id,
1877// which can prevent the job from being skipped and also can avoid repeated patching.
1878function findInsertionIndex(id) {
1879 // the start index should be `flushIndex + 1`
1880 let start = flushIndex + 1;
1881 let end = queue.length;
1882 while (start < end) {
1883 const middle = (start + end) >>> 1;
1884 const middleJobId = getId(queue[middle]);
1885 middleJobId < id ? (start = middle + 1) : (end = middle);
1886 }
1887 return start;
1888}
1889function queueJob(job) {
1890 // the dedupe search uses the startIndex argument of Array.includes()
1891 // by default the search index includes the current job that is being run
1892 // so it cannot recursively trigger itself again.
1893 // if the job is a watch() callback, the search will start with a +1 index to
1894 // allow it recursively trigger itself - it is the user's responsibility to
1895 // ensure it doesn't end up in an infinite loop.
1896 if (!queue.length ||
1897 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) {
1898 if (job.id == null) {
1899 queue.push(job);
1900 }
1901 else {
1902 queue.splice(findInsertionIndex(job.id), 0, job);
1903 }
1904 queueFlush();
1905 }
1906}
1907function queueFlush() {
1908 if (!isFlushing && !isFlushPending) {
1909 isFlushPending = true;
1910 currentFlushPromise = resolvedPromise.then(flushJobs);
1911 }
1912}
1913function invalidateJob(job) {
1914 const i = queue.indexOf(job);
1915 if (i > flushIndex) {
1916 queue.splice(i, 1);
1917 }
1918}
1919function queuePostFlushCb(cb) {
1920 if (!isArray(cb)) {
1921 if (!activePostFlushCbs ||
1922 !activePostFlushCbs.includes(cb, cb.allowRecurse ? postFlushIndex + 1 : postFlushIndex)) {
1923 pendingPostFlushCbs.push(cb);
1924 }
1925 }
1926 else {
1927 // if cb is an array, it is a component lifecycle hook which can only be
1928 // triggered by a job, which is already deduped in the main queue, so
1929 // we can skip duplicate check here to improve perf
1930 pendingPostFlushCbs.push(...cb);
1931 }
1932 queueFlush();
1933}
1934function flushPreFlushCbs(seen,
1935// if currently flushing, skip the current job itself
1936i = isFlushing ? flushIndex + 1 : 0) {
1937 {
1938 seen = seen || new Map();
1939 }
1940 for (; i < queue.length; i++) {
1941 const cb = queue[i];
1942 if (cb && cb.pre) {
1943 if (checkRecursiveUpdates(seen, cb)) {
1944 continue;
1945 }
1946 queue.splice(i, 1);
1947 i--;
1948 cb();
1949 }
1950 }
1951}
1952function flushPostFlushCbs(seen) {
1953 if (pendingPostFlushCbs.length) {
1954 const deduped = [...new Set(pendingPostFlushCbs)];
1955 pendingPostFlushCbs.length = 0;
1956 // #1947 already has active queue, nested flushPostFlushCbs call
1957 if (activePostFlushCbs) {
1958 activePostFlushCbs.push(...deduped);
1959 return;
1960 }
1961 activePostFlushCbs = deduped;
1962 {
1963 seen = seen || new Map();
1964 }
1965 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1966 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1967 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
1968 continue;
1969 }
1970 activePostFlushCbs[postFlushIndex]();
1971 }
1972 activePostFlushCbs = null;
1973 postFlushIndex = 0;
1974 }
1975}
1976const getId = (job) => job.id == null ? Infinity : job.id;
1977const comparator = (a, b) => {
1978 const diff = getId(a) - getId(b);
1979 if (diff === 0) {
1980 if (a.pre && !b.pre)
1981 return -1;
1982 if (b.pre && !a.pre)
1983 return 1;
1984 }
1985 return diff;
1986};
1987function flushJobs(seen) {
1988 isFlushPending = false;
1989 isFlushing = true;
1990 {
1991 seen = seen || new Map();
1992 }
1993 // Sort queue before flush.
1994 // This ensures that:
1995 // 1. Components are updated from parent to child. (because parent is always
1996 // created before the child so its render effect will have smaller
1997 // priority number)
1998 // 2. If a component is unmounted during a parent component's update,
1999 // its update can be skipped.
2000 queue.sort(comparator);
2001 // conditional usage of checkRecursiveUpdate must be determined out of
2002 // try ... catch block since Rollup by default de-optimizes treeshaking
2003 // inside try-catch. This can leave all warning code unshaked. Although
2004 // they would get eventually shaken by a minifier like terser, some minifiers
2005 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610)
2006 const check = (job) => checkRecursiveUpdates(seen, job)
2007 ;
2008 try {
2009 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
2010 const job = queue[flushIndex];
2011 if (job && job.active !== false) {
2012 if (true && check(job)) {
2013 continue;
2014 }
2015 // console.log(`running:`, job.id)
2016 callWithErrorHandling(job, null, 14 /* ErrorCodes.SCHEDULER */);
2017 }
2018 }
2019 }
2020 finally {
2021 flushIndex = 0;
2022 queue.length = 0;
2023 flushPostFlushCbs(seen);
2024 isFlushing = false;
2025 currentFlushPromise = null;
2026 // some postFlushCb queued jobs!
2027 // keep flushing until it drains.
2028 if (queue.length || pendingPostFlushCbs.length) {
2029 flushJobs(seen);
2030 }
2031 }
2032}
2033function checkRecursiveUpdates(seen, fn) {
2034 if (!seen.has(fn)) {
2035 seen.set(fn, 1);
2036 }
2037 else {
2038 const count = seen.get(fn);
2039 if (count > RECURSION_LIMIT) {
2040 const instance = fn.ownerInstance;
2041 const componentName = instance && getComponentName(instance.type);
2042 warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
2043 `This means you have a reactive effect that is mutating its own ` +
2044 `dependencies and thus recursively triggering itself. Possible sources ` +
2045 `include component template, render function, updated hook or ` +
2046 `watcher source function.`);
2047 return true;
2048 }
2049 else {
2050 seen.set(fn, count + 1);
2051 }
2052 }
2053}
2054
2055/* eslint-disable no-restricted-globals */
2056let isHmrUpdating = false;
2057const hmrDirtyComponents = new Set();
2058// Expose the HMR runtime on the global object
2059// This makes it entirely tree-shakable without polluting the exports and makes
2060// it easier to be used in toolings like vue-loader
2061// Note: for a component to be eligible for HMR it also needs the __hmrId option
2062// to be set so that its instances can be registered / removed.
2063{
2064 getGlobalThis().__VUE_HMR_RUNTIME__ = {
2065 createRecord: tryWrap(createRecord),
2066 rerender: tryWrap(rerender),
2067 reload: tryWrap(reload)
2068 };
2069}
2070const map = new Map();
2071function registerHMR(instance) {
2072 const id = instance.type.__hmrId;
2073 let record = map.get(id);
2074 if (!record) {
2075 createRecord(id, instance.type);
2076 record = map.get(id);
2077 }
2078 record.instances.add(instance);
2079}
2080function unregisterHMR(instance) {
2081 map.get(instance.type.__hmrId).instances.delete(instance);
2082}
2083function createRecord(id, initialDef) {
2084 if (map.has(id)) {
2085 return false;
2086 }
2087 map.set(id, {
2088 initialDef: normalizeClassComponent(initialDef),
2089 instances: new Set()
2090 });
2091 return true;
2092}
2093function normalizeClassComponent(component) {
2094 return isClassComponent(component) ? component.__vccOpts : component;
2095}
2096function rerender(id, newRender) {
2097 const record = map.get(id);
2098 if (!record) {
2099 return;
2100 }
2101 // update initial record (for not-yet-rendered component)
2102 record.initialDef.render = newRender;
2103 [...record.instances].forEach(instance => {
2104 if (newRender) {
2105 instance.render = newRender;
2106 normalizeClassComponent(instance.type).render = newRender;
2107 }
2108 instance.renderCache = [];
2109 // this flag forces child components with slot content to update
2110 isHmrUpdating = true;
2111 instance.update();
2112 isHmrUpdating = false;
2113 });
2114}
2115function reload(id, newComp) {
2116 const record = map.get(id);
2117 if (!record)
2118 return;
2119 newComp = normalizeClassComponent(newComp);
2120 // update initial def (for not-yet-rendered components)
2121 updateComponentDef(record.initialDef, newComp);
2122 // create a snapshot which avoids the set being mutated during updates
2123 const instances = [...record.instances];
2124 for (const instance of instances) {
2125 const oldComp = normalizeClassComponent(instance.type);
2126 if (!hmrDirtyComponents.has(oldComp)) {
2127 // 1. Update existing comp definition to match new one
2128 if (oldComp !== record.initialDef) {
2129 updateComponentDef(oldComp, newComp);
2130 }
2131 // 2. mark definition dirty. This forces the renderer to replace the
2132 // component on patch.
2133 hmrDirtyComponents.add(oldComp);
2134 }
2135 // 3. invalidate options resolution cache
2136 instance.appContext.optionsCache.delete(instance.type);
2137 // 4. actually update
2138 if (instance.ceReload) {
2139 // custom element
2140 hmrDirtyComponents.add(oldComp);
2141 instance.ceReload(newComp.styles);
2142 hmrDirtyComponents.delete(oldComp);
2143 }
2144 else if (instance.parent) {
2145 // 4. Force the parent instance to re-render. This will cause all updated
2146 // components to be unmounted and re-mounted. Queue the update so that we
2147 // don't end up forcing the same parent to re-render multiple times.
2148 queueJob(instance.parent.update);
2149 }
2150 else if (instance.appContext.reload) {
2151 // root instance mounted via createApp() has a reload method
2152 instance.appContext.reload();
2153 }
2154 else if (typeof window !== 'undefined') {
2155 // root instance inside tree created via raw render(). Force reload.
2156 window.location.reload();
2157 }
2158 else {
2159 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
2160 }
2161 }
2162 // 5. make sure to cleanup dirty hmr components after update
2163 queuePostFlushCb(() => {
2164 for (const instance of instances) {
2165 hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
2166 }
2167 });
2168}
2169function updateComponentDef(oldComp, newComp) {
2170 extend(oldComp, newComp);
2171 for (const key in oldComp) {
2172 if (key !== '__file' && !(key in newComp)) {
2173 delete oldComp[key];
2174 }
2175 }
2176}
2177function tryWrap(fn) {
2178 return (id, arg) => {
2179 try {
2180 return fn(id, arg);
2181 }
2182 catch (e) {
2183 console.error(e);
2184 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
2185 `Full reload required.`);
2186 }
2187 };
2188}
2189
2190let devtools;
2191let buffer = [];
2192let devtoolsNotInstalled = false;
2193function emit$1(event, ...args) {
2194 if (devtools) {
2195 devtools.emit(event, ...args);
2196 }
2197 else if (!devtoolsNotInstalled) {
2198 buffer.push({ event, args });
2199 }
2200}
2201function setDevtoolsHook(hook, target) {
2202 var _a, _b;
2203 devtools = hook;
2204 if (devtools) {
2205 devtools.enabled = true;
2206 buffer.forEach(({ event, args }) => devtools.emit(event, ...args));
2207 buffer = [];
2208 }
2209 else if (
2210 // handle late devtools injection - only do this if we are in an actual
2211 // browser environment to avoid the timer handle stalling test runner exit
2212 // (#4815)
2213 typeof window !== 'undefined' &&
2214 // some envs mock window but not fully
2215 window.HTMLElement &&
2216 // also exclude jsdom
2217 !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
2218 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
2219 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
2220 replay.push((newHook) => {
2221 setDevtoolsHook(newHook, target);
2222 });
2223 // clear buffer after 3s - the user probably doesn't have devtools installed
2224 // at all, and keeping the buffer will cause memory leaks (#4738)
2225 setTimeout(() => {
2226 if (!devtools) {
2227 target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
2228 devtoolsNotInstalled = true;
2229 buffer = [];
2230 }
2231 }, 3000);
2232 }
2233 else {
2234 // non-browser env, assume not installed
2235 devtoolsNotInstalled = true;
2236 buffer = [];
2237 }
2238}
2239function devtoolsInitApp(app, version) {
2240 emit$1("app:init" /* DevtoolsHooks.APP_INIT */, app, version, {
2241 Fragment,
2242 Text,
2243 Comment,
2244 Static
2245 });
2246}
2247function devtoolsUnmountApp(app) {
2248 emit$1("app:unmount" /* DevtoolsHooks.APP_UNMOUNT */, app);
2249}
2250const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* DevtoolsHooks.COMPONENT_ADDED */);
2251const devtoolsComponentUpdated =
2252/*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* DevtoolsHooks.COMPONENT_UPDATED */);
2253const _devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* DevtoolsHooks.COMPONENT_REMOVED */);
2254const devtoolsComponentRemoved = (component) => {
2255 if (devtools &&
2256 typeof devtools.cleanupBuffer === 'function' &&
2257 // remove the component if it wasn't buffered
2258 !devtools.cleanupBuffer(component)) {
2259 _devtoolsComponentRemoved(component);
2260 }
2261};
2262function createDevtoolsComponentHook(hook) {
2263 return (component) => {
2264 emit$1(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
2265 };
2266}
2267const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* DevtoolsHooks.PERFORMANCE_START */);
2268const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* DevtoolsHooks.PERFORMANCE_END */);
2269function createDevtoolsPerformanceHook(hook) {
2270 return (component, type, time) => {
2271 emit$1(hook, component.appContext.app, component.uid, component, type, time);
2272 };
2273}
2274function devtoolsComponentEmit(component, event, params) {
2275 emit$1("component:emit" /* DevtoolsHooks.COMPONENT_EMIT */, component.appContext.app, component, event, params);
2276}
2277
2278function emit(instance, event, ...rawArgs) {
2279 if (instance.isUnmounted)
2280 return;
2281 const props = instance.vnode.props || EMPTY_OBJ;
2282 {
2283 const { emitsOptions, propsOptions: [propsOptions] } = instance;
2284 if (emitsOptions) {
2285 if (!(event in emitsOptions) &&
2286 !(false )) {
2287 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
2288 warn(`Component emitted event "${event}" but it is neither declared in ` +
2289 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
2290 }
2291 }
2292 else {
2293 const validator = emitsOptions[event];
2294 if (isFunction(validator)) {
2295 const isValid = validator(...rawArgs);
2296 if (!isValid) {
2297 warn(`Invalid event arguments: event validation failed for event "${event}".`);
2298 }
2299 }
2300 }
2301 }
2302 }
2303 let args = rawArgs;
2304 const isModelListener = event.startsWith('update:');
2305 // for v-model update:xxx events, apply modifiers on args
2306 const modelArg = isModelListener && event.slice(7);
2307 if (modelArg && modelArg in props) {
2308 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
2309 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
2310 if (trim) {
2311 args = rawArgs.map(a => (isString(a) ? a.trim() : a));
2312 }
2313 if (number) {
2314 args = rawArgs.map(looseToNumber);
2315 }
2316 }
2317 {
2318 devtoolsComponentEmit(instance, event, args);
2319 }
2320 {
2321 const lowerCaseEvent = event.toLowerCase();
2322 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
2323 warn(`Event "${lowerCaseEvent}" is emitted in component ` +
2324 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
2325 `Note that HTML attributes are case-insensitive and you cannot use ` +
2326 `v-on to listen to camelCase events when using in-DOM templates. ` +
2327 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
2328 }
2329 }
2330 let handlerName;
2331 let handler = props[(handlerName = toHandlerKey(event))] ||
2332 // also try camelCase event handler (#2249)
2333 props[(handlerName = toHandlerKey(camelize(event)))];
2334 // for v-model update:xxx events, also trigger kebab-case equivalent
2335 // for props passed via kebab-case
2336 if (!handler && isModelListener) {
2337 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
2338 }
2339 if (handler) {
2340 callWithAsyncErrorHandling(handler, instance, 6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */, args);
2341 }
2342 const onceHandler = props[handlerName + `Once`];
2343 if (onceHandler) {
2344 if (!instance.emitted) {
2345 instance.emitted = {};
2346 }
2347 else if (instance.emitted[handlerName]) {
2348 return;
2349 }
2350 instance.emitted[handlerName] = true;
2351 callWithAsyncErrorHandling(onceHandler, instance, 6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */, args);
2352 }
2353}
2354function normalizeEmitsOptions(comp, appContext, asMixin = false) {
2355 const cache = appContext.emitsCache;
2356 const cached = cache.get(comp);
2357 if (cached !== undefined) {
2358 return cached;
2359 }
2360 const raw = comp.emits;
2361 let normalized = {};
2362 // apply mixin/extends props
2363 let hasExtends = false;
2364 if (!isFunction(comp)) {
2365 const extendEmits = (raw) => {
2366 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
2367 if (normalizedFromExtend) {
2368 hasExtends = true;
2369 extend(normalized, normalizedFromExtend);
2370 }
2371 };
2372 if (!asMixin && appContext.mixins.length) {
2373 appContext.mixins.forEach(extendEmits);
2374 }
2375 if (comp.extends) {
2376 extendEmits(comp.extends);
2377 }
2378 if (comp.mixins) {
2379 comp.mixins.forEach(extendEmits);
2380 }
2381 }
2382 if (!raw && !hasExtends) {
2383 if (isObject(comp)) {
2384 cache.set(comp, null);
2385 }
2386 return null;
2387 }
2388 if (isArray(raw)) {
2389 raw.forEach(key => (normalized[key] = null));
2390 }
2391 else {
2392 extend(normalized, raw);
2393 }
2394 if (isObject(comp)) {
2395 cache.set(comp, normalized);
2396 }
2397 return normalized;
2398}
2399// Check if an incoming prop key is a declared emit event listener.
2400// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
2401// both considered matched listeners.
2402function isEmitListener(options, key) {
2403 if (!options || !isOn(key)) {
2404 return false;
2405 }
2406 key = key.slice(2).replace(/Once$/, '');
2407 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
2408 hasOwn(options, hyphenate(key)) ||
2409 hasOwn(options, key));
2410}
2411
2412/**
2413 * mark the current rendering instance for asset resolution (e.g.
2414 * resolveComponent, resolveDirective) during render
2415 */
2416let currentRenderingInstance = null;
2417let currentScopeId = null;
2418/**
2419 * Note: rendering calls maybe nested. The function returns the parent rendering
2420 * instance if present, which should be restored after the render is done:
2421 *
2422 * ```js
2423 * const prev = setCurrentRenderingInstance(i)
2424 * // ...render
2425 * setCurrentRenderingInstance(prev)
2426 * ```
2427 */
2428function setCurrentRenderingInstance(instance) {
2429 const prev = currentRenderingInstance;
2430 currentRenderingInstance = instance;
2431 currentScopeId = (instance && instance.type.__scopeId) || null;
2432 return prev;
2433}
2434/**
2435 * Set scope id when creating hoisted vnodes.
2436 * @private compiler helper
2437 */
2438function pushScopeId(id) {
2439 currentScopeId = id;
2440}
2441/**
2442 * Technically we no longer need this after 3.0.8 but we need to keep the same
2443 * API for backwards compat w/ code generated by compilers.
2444 * @private
2445 */
2446function popScopeId() {
2447 currentScopeId = null;
2448}
2449/**
2450 * Only for backwards compat
2451 * @private
2452 */
2453const withScopeId = (_id) => withCtx;
2454/**
2455 * Wrap a slot function to memoize current rendering instance
2456 * @private compiler helper
2457 */
2458function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
2459) {
2460 if (!ctx)
2461 return fn;
2462 // already normalized
2463 if (fn._n) {
2464 return fn;
2465 }
2466 const renderFnWithContext = (...args) => {
2467 // If a user calls a compiled slot inside a template expression (#1745), it
2468 // can mess up block tracking, so by default we disable block tracking and
2469 // force bail out when invoking a compiled slot (indicated by the ._d flag).
2470 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
2471 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
2472 if (renderFnWithContext._d) {
2473 setBlockTracking(-1);
2474 }
2475 const prevInstance = setCurrentRenderingInstance(ctx);
2476 let res;
2477 try {
2478 res = fn(...args);
2479 }
2480 finally {
2481 setCurrentRenderingInstance(prevInstance);
2482 if (renderFnWithContext._d) {
2483 setBlockTracking(1);
2484 }
2485 }
2486 {
2487 devtoolsComponentUpdated(ctx);
2488 }
2489 return res;
2490 };
2491 // mark normalized to avoid duplicated wrapping
2492 renderFnWithContext._n = true;
2493 // mark this as compiled by default
2494 // this is used in vnode.ts -> normalizeChildren() to set the slot
2495 // rendering flag.
2496 renderFnWithContext._c = true;
2497 // disable block tracking by default
2498 renderFnWithContext._d = true;
2499 return renderFnWithContext;
2500}
2501
2502/**
2503 * dev only flag to track whether $attrs was used during render.
2504 * If $attrs was used during render then the warning for failed attrs
2505 * fallthrough can be suppressed.
2506 */
2507let accessedAttrs = false;
2508function markAttrsAccessed() {
2509 accessedAttrs = true;
2510}
2511function renderComponentRoot(instance) {
2512 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
2513 let result;
2514 let fallthroughAttrs;
2515 const prev = setCurrentRenderingInstance(instance);
2516 {
2517 accessedAttrs = false;
2518 }
2519 try {
2520 if (vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */) {
2521 // withProxy is a proxy with a different `has` trap only for
2522 // runtime-compiled render functions using `with` block.
2523 const proxyToUse = withProxy || proxy;
2524 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2525 fallthroughAttrs = attrs;
2526 }
2527 else {
2528 // functional
2529 const render = Component;
2530 // in dev, mark attrs accessed if optional props (attrs === props)
2531 if (true && attrs === props) {
2532 markAttrsAccessed();
2533 }
2534 result = normalizeVNode(render.length > 1
2535 ? render(props, true
2536 ? {
2537 get attrs() {
2538 markAttrsAccessed();
2539 return attrs;
2540 },
2541 slots,
2542 emit
2543 }
2544 : { attrs, slots, emit })
2545 : render(props, null /* we know it doesn't need it */));
2546 fallthroughAttrs = Component.props
2547 ? attrs
2548 : getFunctionalFallthrough(attrs);
2549 }
2550 }
2551 catch (err) {
2552 blockStack.length = 0;
2553 handleError(err, instance, 1 /* ErrorCodes.RENDER_FUNCTION */);
2554 result = createVNode(Comment);
2555 }
2556 // attr merging
2557 // in dev mode, comments are preserved, and it's possible for a template
2558 // to have comments along side the root element which makes it a fragment
2559 let root = result;
2560 let setRoot = undefined;
2561 if (result.patchFlag > 0 &&
2562 result.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */) {
2563 [root, setRoot] = getChildRoot(result);
2564 }
2565 if (fallthroughAttrs && inheritAttrs !== false) {
2566 const keys = Object.keys(fallthroughAttrs);
2567 const { shapeFlag } = root;
2568 if (keys.length) {
2569 if (shapeFlag & (1 /* ShapeFlags.ELEMENT */ | 6 /* ShapeFlags.COMPONENT */)) {
2570 if (propsOptions && keys.some(isModelListener)) {
2571 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2572 // prop, it indicates this component expects to handle v-model and
2573 // it should not fallthrough.
2574 // related: #1543, #1643, #1989
2575 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2576 }
2577 root = cloneVNode(root, fallthroughAttrs);
2578 }
2579 else if (!accessedAttrs && root.type !== Comment) {
2580 const allAttrs = Object.keys(attrs);
2581 const eventAttrs = [];
2582 const extraAttrs = [];
2583 for (let i = 0, l = allAttrs.length; i < l; i++) {
2584 const key = allAttrs[i];
2585 if (isOn(key)) {
2586 // ignore v-model handlers when they fail to fallthrough
2587 if (!isModelListener(key)) {
2588 // remove `on`, lowercase first letter to reflect event casing
2589 // accurately
2590 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2591 }
2592 }
2593 else {
2594 extraAttrs.push(key);
2595 }
2596 }
2597 if (extraAttrs.length) {
2598 warn(`Extraneous non-props attributes (` +
2599 `${extraAttrs.join(', ')}) ` +
2600 `were passed to component but could not be automatically inherited ` +
2601 `because component renders fragment or text root nodes.`);
2602 }
2603 if (eventAttrs.length) {
2604 warn(`Extraneous non-emits event listeners (` +
2605 `${eventAttrs.join(', ')}) ` +
2606 `were passed to component but could not be automatically inherited ` +
2607 `because component renders fragment or text root nodes. ` +
2608 `If the listener is intended to be a component custom event listener only, ` +
2609 `declare it using the "emits" option.`);
2610 }
2611 }
2612 }
2613 }
2614 // inherit directives
2615 if (vnode.dirs) {
2616 if (!isElementRoot(root)) {
2617 warn(`Runtime directive used on component with non-element root node. ` +
2618 `The directives will not function as intended.`);
2619 }
2620 // clone before mutating since the root may be a hoisted vnode
2621 root = cloneVNode(root);
2622 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2623 }
2624 // inherit transition data
2625 if (vnode.transition) {
2626 if (!isElementRoot(root)) {
2627 warn(`Component inside <Transition> renders non-element root node ` +
2628 `that cannot be animated.`);
2629 }
2630 root.transition = vnode.transition;
2631 }
2632 if (setRoot) {
2633 setRoot(root);
2634 }
2635 else {
2636 result = root;
2637 }
2638 setCurrentRenderingInstance(prev);
2639 return result;
2640}
2641/**
2642 * dev only
2643 * In dev mode, template root level comments are rendered, which turns the
2644 * template into a fragment root, but we need to locate the single element
2645 * root for attrs and scope id processing.
2646 */
2647const getChildRoot = (vnode) => {
2648 const rawChildren = vnode.children;
2649 const dynamicChildren = vnode.dynamicChildren;
2650 const childRoot = filterSingleRoot(rawChildren);
2651 if (!childRoot) {
2652 return [vnode, undefined];
2653 }
2654 const index = rawChildren.indexOf(childRoot);
2655 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2656 const setRoot = (updatedRoot) => {
2657 rawChildren[index] = updatedRoot;
2658 if (dynamicChildren) {
2659 if (dynamicIndex > -1) {
2660 dynamicChildren[dynamicIndex] = updatedRoot;
2661 }
2662 else if (updatedRoot.patchFlag > 0) {
2663 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2664 }
2665 }
2666 };
2667 return [normalizeVNode(childRoot), setRoot];
2668};
2669function filterSingleRoot(children) {
2670 let singleRoot;
2671 for (let i = 0; i < children.length; i++) {
2672 const child = children[i];
2673 if (isVNode(child)) {
2674 // ignore user comment
2675 if (child.type !== Comment || child.children === 'v-if') {
2676 if (singleRoot) {
2677 // has more than 1 non-comment child, return now
2678 return;
2679 }
2680 else {
2681 singleRoot = child;
2682 }
2683 }
2684 }
2685 else {
2686 return;
2687 }
2688 }
2689 return singleRoot;
2690}
2691const getFunctionalFallthrough = (attrs) => {
2692 let res;
2693 for (const key in attrs) {
2694 if (key === 'class' || key === 'style' || isOn(key)) {
2695 (res || (res = {}))[key] = attrs[key];
2696 }
2697 }
2698 return res;
2699};
2700const filterModelListeners = (attrs, props) => {
2701 const res = {};
2702 for (const key in attrs) {
2703 if (!isModelListener(key) || !(key.slice(9) in props)) {
2704 res[key] = attrs[key];
2705 }
2706 }
2707 return res;
2708};
2709const isElementRoot = (vnode) => {
2710 return (vnode.shapeFlag & (6 /* ShapeFlags.COMPONENT */ | 1 /* ShapeFlags.ELEMENT */) ||
2711 vnode.type === Comment // potential v-if branch switch
2712 );
2713};
2714function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2715 const { props: prevProps, children: prevChildren, component } = prevVNode;
2716 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2717 const emits = component.emitsOptions;
2718 // Parent component's render function was hot-updated. Since this may have
2719 // caused the child component's slots content to have changed, we need to
2720 // force the child to update as well.
2721 if ((prevChildren || nextChildren) && isHmrUpdating) {
2722 return true;
2723 }
2724 // force child update for runtime directive or transition on component vnode.
2725 if (nextVNode.dirs || nextVNode.transition) {
2726 return true;
2727 }
2728 if (optimized && patchFlag >= 0) {
2729 if (patchFlag & 1024 /* PatchFlags.DYNAMIC_SLOTS */) {
2730 // slot content that references values that might have changed,
2731 // e.g. in a v-for
2732 return true;
2733 }
2734 if (patchFlag & 16 /* PatchFlags.FULL_PROPS */) {
2735 if (!prevProps) {
2736 return !!nextProps;
2737 }
2738 // presence of this flag indicates props are always non-null
2739 return hasPropsChanged(prevProps, nextProps, emits);
2740 }
2741 else if (patchFlag & 8 /* PatchFlags.PROPS */) {
2742 const dynamicProps = nextVNode.dynamicProps;
2743 for (let i = 0; i < dynamicProps.length; i++) {
2744 const key = dynamicProps[i];
2745 if (nextProps[key] !== prevProps[key] &&
2746 !isEmitListener(emits, key)) {
2747 return true;
2748 }
2749 }
2750 }
2751 }
2752 else {
2753 // this path is only taken by manually written render functions
2754 // so presence of any children leads to a forced update
2755 if (prevChildren || nextChildren) {
2756 if (!nextChildren || !nextChildren.$stable) {
2757 return true;
2758 }
2759 }
2760 if (prevProps === nextProps) {
2761 return false;
2762 }
2763 if (!prevProps) {
2764 return !!nextProps;
2765 }
2766 if (!nextProps) {
2767 return true;
2768 }
2769 return hasPropsChanged(prevProps, nextProps, emits);
2770 }
2771 return false;
2772}
2773function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2774 const nextKeys = Object.keys(nextProps);
2775 if (nextKeys.length !== Object.keys(prevProps).length) {
2776 return true;
2777 }
2778 for (let i = 0; i < nextKeys.length; i++) {
2779 const key = nextKeys[i];
2780 if (nextProps[key] !== prevProps[key] &&
2781 !isEmitListener(emitsOptions, key)) {
2782 return true;
2783 }
2784 }
2785 return false;
2786}
2787function updateHOCHostEl({ vnode, parent }, el // HostNode
2788) {
2789 while (parent && parent.subTree === vnode) {
2790 (vnode = parent.vnode).el = el;
2791 parent = parent.parent;
2792 }
2793}
2794
2795const isSuspense = (type) => type.__isSuspense;
2796// Suspense exposes a component-like API, and is treated like a component
2797// in the compiler, but internally it's a special built-in type that hooks
2798// directly into the renderer.
2799const SuspenseImpl = {
2800 name: 'Suspense',
2801 // In order to make Suspense tree-shakable, we need to avoid importing it
2802 // directly in the renderer. The renderer checks for the __isSuspense flag
2803 // on a vnode's type and calls the `process` method, passing in renderer
2804 // internals.
2805 __isSuspense: true,
2806 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2807 // platform-specific impl passed from renderer
2808 rendererInternals) {
2809 if (n1 == null) {
2810 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2811 }
2812 else {
2813 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2814 }
2815 },
2816 hydrate: hydrateSuspense,
2817 create: createSuspenseBoundary,
2818 normalize: normalizeSuspenseChildren
2819};
2820// Force-casted public typing for h and TSX props inference
2821const Suspense = (SuspenseImpl
2822 );
2823function triggerEvent(vnode, name) {
2824 const eventListener = vnode.props && vnode.props[name];
2825 if (isFunction(eventListener)) {
2826 eventListener();
2827 }
2828}
2829function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2830 const { p: patch, o: { createElement } } = rendererInternals;
2831 const hiddenContainer = createElement('div');
2832 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2833 // start mounting the content subtree in an off-dom container
2834 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2835 // now check if we have encountered any async deps
2836 if (suspense.deps > 0) {
2837 // has async
2838 // invoke @fallback event
2839 triggerEvent(vnode, 'onPending');
2840 triggerEvent(vnode, 'onFallback');
2841 // mount the fallback tree
2842 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2843 isSVG, slotScopeIds);
2844 setActiveBranch(suspense, vnode.ssFallback);
2845 }
2846 else {
2847 // Suspense has no async deps. Just resolve.
2848 suspense.resolve();
2849 }
2850}
2851function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2852 const suspense = (n2.suspense = n1.suspense);
2853 suspense.vnode = n2;
2854 n2.el = n1.el;
2855 const newBranch = n2.ssContent;
2856 const newFallback = n2.ssFallback;
2857 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2858 if (pendingBranch) {
2859 suspense.pendingBranch = newBranch;
2860 if (isSameVNodeType(newBranch, pendingBranch)) {
2861 // same root type but content may have changed.
2862 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2863 if (suspense.deps <= 0) {
2864 suspense.resolve();
2865 }
2866 else if (isInFallback) {
2867 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2868 isSVG, slotScopeIds, optimized);
2869 setActiveBranch(suspense, newFallback);
2870 }
2871 }
2872 else {
2873 // toggled before pending tree is resolved
2874 suspense.pendingId++;
2875 if (isHydrating) {
2876 // if toggled before hydration is finished, the current DOM tree is
2877 // no longer valid. set it as the active branch so it will be unmounted
2878 // when resolved
2879 suspense.isHydrating = false;
2880 suspense.activeBranch = pendingBranch;
2881 }
2882 else {
2883 unmount(pendingBranch, parentComponent, suspense);
2884 }
2885 // increment pending ID. this is used to invalidate async callbacks
2886 // reset suspense state
2887 suspense.deps = 0;
2888 // discard effects from pending branch
2889 suspense.effects.length = 0;
2890 // discard previous container
2891 suspense.hiddenContainer = createElement('div');
2892 if (isInFallback) {
2893 // already in fallback state
2894 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2895 if (suspense.deps <= 0) {
2896 suspense.resolve();
2897 }
2898 else {
2899 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2900 isSVG, slotScopeIds, optimized);
2901 setActiveBranch(suspense, newFallback);
2902 }
2903 }
2904 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2905 // toggled "back" to current active branch
2906 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2907 // force resolve
2908 suspense.resolve(true);
2909 }
2910 else {
2911 // switched to a 3rd branch
2912 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2913 if (suspense.deps <= 0) {
2914 suspense.resolve();
2915 }
2916 }
2917 }
2918 }
2919 else {
2920 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2921 // root did not change, just normal patch
2922 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2923 setActiveBranch(suspense, newBranch);
2924 }
2925 else {
2926 // root node toggled
2927 // invoke @pending event
2928 triggerEvent(n2, 'onPending');
2929 // mount pending branch in off-dom container
2930 suspense.pendingBranch = newBranch;
2931 suspense.pendingId++;
2932 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2933 if (suspense.deps <= 0) {
2934 // incoming branch has no async deps, resolve now.
2935 suspense.resolve();
2936 }
2937 else {
2938 const { timeout, pendingId } = suspense;
2939 if (timeout > 0) {
2940 setTimeout(() => {
2941 if (suspense.pendingId === pendingId) {
2942 suspense.fallback(newFallback);
2943 }
2944 }, timeout);
2945 }
2946 else if (timeout === 0) {
2947 suspense.fallback(newFallback);
2948 }
2949 }
2950 }
2951 }
2952}
2953let hasWarned = false;
2954function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2955 /* istanbul ignore if */
2956 if (!hasWarned) {
2957 hasWarned = true;
2958 // @ts-ignore `console.info` cannot be null error
2959 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2960 }
2961 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2962 const timeout = vnode.props ? toNumber(vnode.props.timeout) : undefined;
2963 {
2964 assertNumber(timeout, `Suspense timeout`);
2965 }
2966 const suspense = {
2967 vnode,
2968 parent,
2969 parentComponent,
2970 isSVG,
2971 container,
2972 hiddenContainer,
2973 anchor,
2974 deps: 0,
2975 pendingId: 0,
2976 timeout: typeof timeout === 'number' ? timeout : -1,
2977 activeBranch: null,
2978 pendingBranch: null,
2979 isInFallback: true,
2980 isHydrating,
2981 isUnmounted: false,
2982 effects: [],
2983 resolve(resume = false) {
2984 {
2985 if (!resume && !suspense.pendingBranch) {
2986 throw new Error(`suspense.resolve() is called without a pending branch.`);
2987 }
2988 if (suspense.isUnmounted) {
2989 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2990 }
2991 }
2992 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2993 if (suspense.isHydrating) {
2994 suspense.isHydrating = false;
2995 }
2996 else if (!resume) {
2997 const delayEnter = activeBranch &&
2998 pendingBranch.transition &&
2999 pendingBranch.transition.mode === 'out-in';
3000 if (delayEnter) {
3001 activeBranch.transition.afterLeave = () => {
3002 if (pendingId === suspense.pendingId) {
3003 move(pendingBranch, container, anchor, 0 /* MoveType.ENTER */);
3004 }
3005 };
3006 }
3007 // this is initial anchor on mount
3008 let { anchor } = suspense;
3009 // unmount current active tree
3010 if (activeBranch) {
3011 // if the fallback tree was mounted, it may have been moved
3012 // as part of a parent suspense. get the latest anchor for insertion
3013 anchor = next(activeBranch);
3014 unmount(activeBranch, parentComponent, suspense, true);
3015 }
3016 if (!delayEnter) {
3017 // move content from off-dom container to actual container
3018 move(pendingBranch, container, anchor, 0 /* MoveType.ENTER */);
3019 }
3020 }
3021 setActiveBranch(suspense, pendingBranch);
3022 suspense.pendingBranch = null;
3023 suspense.isInFallback = false;
3024 // flush buffered effects
3025 // check if there is a pending parent suspense
3026 let parent = suspense.parent;
3027 let hasUnresolvedAncestor = false;
3028 while (parent) {
3029 if (parent.pendingBranch) {
3030 // found a pending parent suspense, merge buffered post jobs
3031 // into that parent
3032 parent.effects.push(...effects);
3033 hasUnresolvedAncestor = true;
3034 break;
3035 }
3036 parent = parent.parent;
3037 }
3038 // no pending parent suspense, flush all jobs
3039 if (!hasUnresolvedAncestor) {
3040 queuePostFlushCb(effects);
3041 }
3042 suspense.effects = [];
3043 // invoke @resolve event
3044 triggerEvent(vnode, 'onResolve');
3045 },
3046 fallback(fallbackVNode) {
3047 if (!suspense.pendingBranch) {
3048 return;
3049 }
3050 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
3051 // invoke @fallback event
3052 triggerEvent(vnode, 'onFallback');
3053 const anchor = next(activeBranch);
3054 const mountFallback = () => {
3055 if (!suspense.isInFallback) {
3056 return;
3057 }
3058 // mount the fallback tree
3059 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
3060 isSVG, slotScopeIds, optimized);
3061 setActiveBranch(suspense, fallbackVNode);
3062 };
3063 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
3064 if (delayEnter) {
3065 activeBranch.transition.afterLeave = mountFallback;
3066 }
3067 suspense.isInFallback = true;
3068 // unmount current active branch
3069 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
3070 true // shouldRemove
3071 );
3072 if (!delayEnter) {
3073 mountFallback();
3074 }
3075 },
3076 move(container, anchor, type) {
3077 suspense.activeBranch &&
3078 move(suspense.activeBranch, container, anchor, type);
3079 suspense.container = container;
3080 },
3081 next() {
3082 return suspense.activeBranch && next(suspense.activeBranch);
3083 },
3084 registerDep(instance, setupRenderEffect) {
3085 const isInPendingSuspense = !!suspense.pendingBranch;
3086 if (isInPendingSuspense) {
3087 suspense.deps++;
3088 }
3089 const hydratedEl = instance.vnode.el;
3090 instance
3091 .asyncDep.catch(err => {
3092 handleError(err, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
3093 })
3094 .then(asyncSetupResult => {
3095 // retry when the setup() promise resolves.
3096 // component may have been unmounted before resolve.
3097 if (instance.isUnmounted ||
3098 suspense.isUnmounted ||
3099 suspense.pendingId !== instance.suspenseId) {
3100 return;
3101 }
3102 // retry from this component
3103 instance.asyncResolved = true;
3104 const { vnode } = instance;
3105 {
3106 pushWarningContext(vnode);
3107 }
3108 handleSetupResult(instance, asyncSetupResult, false);
3109 if (hydratedEl) {
3110 // vnode may have been replaced if an update happened before the
3111 // async dep is resolved.
3112 vnode.el = hydratedEl;
3113 }
3114 const placeholder = !hydratedEl && instance.subTree.el;
3115 setupRenderEffect(instance, vnode,
3116 // component may have been moved before resolve.
3117 // if this is not a hydration, instance.subTree will be the comment
3118 // placeholder.
3119 parentNode(hydratedEl || instance.subTree.el),
3120 // anchor will not be used if this is hydration, so only need to
3121 // consider the comment placeholder case.
3122 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
3123 if (placeholder) {
3124 remove(placeholder);
3125 }
3126 updateHOCHostEl(instance, vnode.el);
3127 {
3128 popWarningContext();
3129 }
3130 // only decrease deps count if suspense is not already resolved
3131 if (isInPendingSuspense && --suspense.deps === 0) {
3132 suspense.resolve();
3133 }
3134 });
3135 },
3136 unmount(parentSuspense, doRemove) {
3137 suspense.isUnmounted = true;
3138 if (suspense.activeBranch) {
3139 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
3140 }
3141 if (suspense.pendingBranch) {
3142 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
3143 }
3144 }
3145 };
3146 return suspense;
3147}
3148function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
3149 /* eslint-disable no-restricted-globals */
3150 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
3151 // there are two possible scenarios for server-rendered suspense:
3152 // - success: ssr content should be fully resolved
3153 // - failure: ssr content should be the fallback branch.
3154 // however, on the client we don't really know if it has failed or not
3155 // attempt to hydrate the DOM assuming it has succeeded, but we still
3156 // need to construct a suspense boundary first
3157 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
3158 if (suspense.deps === 0) {
3159 suspense.resolve();
3160 }
3161 return result;
3162 /* eslint-enable no-restricted-globals */
3163}
3164function normalizeSuspenseChildren(vnode) {
3165 const { shapeFlag, children } = vnode;
3166 const isSlotChildren = shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */;
3167 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
3168 vnode.ssFallback = isSlotChildren
3169 ? normalizeSuspenseSlot(children.fallback)
3170 : createVNode(Comment);
3171}
3172function normalizeSuspenseSlot(s) {
3173 let block;
3174 if (isFunction(s)) {
3175 const trackBlock = isBlockTreeEnabled && s._c;
3176 if (trackBlock) {
3177 // disableTracking: false
3178 // allow block tracking for compiled slots
3179 // (see ./componentRenderContext.ts)
3180 s._d = false;
3181 openBlock();
3182 }
3183 s = s();
3184 if (trackBlock) {
3185 s._d = true;
3186 block = currentBlock;
3187 closeBlock();
3188 }
3189 }
3190 if (isArray(s)) {
3191 const singleChild = filterSingleRoot(s);
3192 if (!singleChild) {
3193 warn(`<Suspense> slots expect a single root node.`);
3194 }
3195 s = singleChild;
3196 }
3197 s = normalizeVNode(s);
3198 if (block && !s.dynamicChildren) {
3199 s.dynamicChildren = block.filter(c => c !== s);
3200 }
3201 return s;
3202}
3203function queueEffectWithSuspense(fn, suspense) {
3204 if (suspense && suspense.pendingBranch) {
3205 if (isArray(fn)) {
3206 suspense.effects.push(...fn);
3207 }
3208 else {
3209 suspense.effects.push(fn);
3210 }
3211 }
3212 else {
3213 queuePostFlushCb(fn);
3214 }
3215}
3216function setActiveBranch(suspense, branch) {
3217 suspense.activeBranch = branch;
3218 const { vnode, parentComponent } = suspense;
3219 const el = (vnode.el = branch.el);
3220 // in case suspense is the root node of a component,
3221 // recursively update the HOC el
3222 if (parentComponent && parentComponent.subTree === vnode) {
3223 parentComponent.vnode.el = el;
3224 updateHOCHostEl(parentComponent, el);
3225 }
3226}
3227
3228function provide(key, value) {
3229 if (!currentInstance) {
3230 {
3231 warn(`provide() can only be used inside setup().`);
3232 }
3233 }
3234 else {
3235 let provides = currentInstance.provides;
3236 // by default an instance inherits its parent's provides object
3237 // but when it needs to provide values of its own, it creates its
3238 // own provides object using parent provides object as prototype.
3239 // this way in `inject` we can simply look up injections from direct
3240 // parent and let the prototype chain do the work.
3241 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
3242 if (parentProvides === provides) {
3243 provides = currentInstance.provides = Object.create(parentProvides);
3244 }
3245 // TS doesn't allow symbol as index type
3246 provides[key] = value;
3247 }
3248}
3249function inject(key, defaultValue, treatDefaultAsFactory = false) {
3250 // fallback to `currentRenderingInstance` so that this can be called in
3251 // a functional component
3252 const instance = currentInstance || currentRenderingInstance;
3253 if (instance) {
3254 // #2400
3255 // to support `app.use` plugins,
3256 // fallback to appContext's `provides` if the instance is at root
3257 const provides = instance.parent == null
3258 ? instance.vnode.appContext && instance.vnode.appContext.provides
3259 : instance.parent.provides;
3260 if (provides && key in provides) {
3261 // TS doesn't allow symbol as index type
3262 return provides[key];
3263 }
3264 else if (arguments.length > 1) {
3265 return treatDefaultAsFactory && isFunction(defaultValue)
3266 ? defaultValue.call(instance.proxy)
3267 : defaultValue;
3268 }
3269 else {
3270 warn(`injection "${String(key)}" not found.`);
3271 }
3272 }
3273 else {
3274 warn(`inject() can only be used inside setup() or functional components.`);
3275 }
3276}
3277
3278// Simple effect.
3279function watchEffect(effect, options) {
3280 return doWatch(effect, null, options);
3281}
3282function watchPostEffect(effect, options) {
3283 return doWatch(effect, null, Object.assign(Object.assign({}, options), { flush: 'post' }) );
3284}
3285function watchSyncEffect(effect, options) {
3286 return doWatch(effect, null, Object.assign(Object.assign({}, options), { flush: 'sync' }) );
3287}
3288// initial value for watchers to trigger on undefined initial values
3289const INITIAL_WATCHER_VALUE = {};
3290// implementation
3291function watch(source, cb, options) {
3292 if (!isFunction(cb)) {
3293 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3294 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3295 `supports \`watch(source, cb, options?) signature.`);
3296 }
3297 return doWatch(source, cb, options);
3298}
3299function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
3300 if (!cb) {
3301 if (immediate !== undefined) {
3302 warn(`watch() "immediate" option is only respected when using the ` +
3303 `watch(source, callback, options?) signature.`);
3304 }
3305 if (deep !== undefined) {
3306 warn(`watch() "deep" option is only respected when using the ` +
3307 `watch(source, callback, options?) signature.`);
3308 }
3309 }
3310 const warnInvalidSource = (s) => {
3311 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3312 `a reactive object, or an array of these types.`);
3313 };
3314 const instance = getCurrentScope() === (currentInstance === null || currentInstance === void 0 ? void 0 : currentInstance.scope) ? currentInstance : null;
3315 // const instance = currentInstance
3316 let getter;
3317 let forceTrigger = false;
3318 let isMultiSource = false;
3319 if (isRef(source)) {
3320 getter = () => source.value;
3321 forceTrigger = isShallow(source);
3322 }
3323 else if (isReactive(source)) {
3324 getter = () => source;
3325 deep = true;
3326 }
3327 else if (isArray(source)) {
3328 isMultiSource = true;
3329 forceTrigger = source.some(s => isReactive(s) || isShallow(s));
3330 getter = () => source.map(s => {
3331 if (isRef(s)) {
3332 return s.value;
3333 }
3334 else if (isReactive(s)) {
3335 return traverse(s);
3336 }
3337 else if (isFunction(s)) {
3338 return callWithErrorHandling(s, instance, 2 /* ErrorCodes.WATCH_GETTER */);
3339 }
3340 else {
3341 warnInvalidSource(s);
3342 }
3343 });
3344 }
3345 else if (isFunction(source)) {
3346 if (cb) {
3347 // getter with cb
3348 getter = () => callWithErrorHandling(source, instance, 2 /* ErrorCodes.WATCH_GETTER */);
3349 }
3350 else {
3351 // no cb -> simple effect
3352 getter = () => {
3353 if (instance && instance.isUnmounted) {
3354 return;
3355 }
3356 if (cleanup) {
3357 cleanup();
3358 }
3359 return callWithAsyncErrorHandling(source, instance, 3 /* ErrorCodes.WATCH_CALLBACK */, [onCleanup]);
3360 };
3361 }
3362 }
3363 else {
3364 getter = NOOP;
3365 warnInvalidSource(source);
3366 }
3367 if (cb && deep) {
3368 const baseGetter = getter;
3369 getter = () => traverse(baseGetter());
3370 }
3371 let cleanup;
3372 let onCleanup = (fn) => {
3373 cleanup = effect.onStop = () => {
3374 callWithErrorHandling(fn, instance, 4 /* ErrorCodes.WATCH_CLEANUP */);
3375 };
3376 };
3377 let oldValue = isMultiSource
3378 ? new Array(source.length).fill(INITIAL_WATCHER_VALUE)
3379 : INITIAL_WATCHER_VALUE;
3380 const job = () => {
3381 if (!effect.active) {
3382 return;
3383 }
3384 if (cb) {
3385 // watch(source, cb)
3386 const newValue = effect.run();
3387 if (deep ||
3388 forceTrigger ||
3389 (isMultiSource
3390 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
3391 : hasChanged(newValue, oldValue)) ||
3392 (false )) {
3393 // cleanup before running cb again
3394 if (cleanup) {
3395 cleanup();
3396 }
3397 callWithAsyncErrorHandling(cb, instance, 3 /* ErrorCodes.WATCH_CALLBACK */, [
3398 newValue,
3399 // pass undefined as the old value when it's changed for the first time
3400 oldValue === INITIAL_WATCHER_VALUE
3401 ? undefined
3402 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE
3403 ? []
3404 : oldValue,
3405 onCleanup
3406 ]);
3407 oldValue = newValue;
3408 }
3409 }
3410 else {
3411 // watchEffect
3412 effect.run();
3413 }
3414 };
3415 // important: mark the job as a watcher callback so that scheduler knows
3416 // it is allowed to self-trigger (#1727)
3417 job.allowRecurse = !!cb;
3418 let scheduler;
3419 if (flush === 'sync') {
3420 scheduler = job; // the scheduler function gets called directly
3421 }
3422 else if (flush === 'post') {
3423 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3424 }
3425 else {
3426 // default: 'pre'
3427 job.pre = true;
3428 if (instance)
3429 job.id = instance.uid;
3430 scheduler = () => queueJob(job);
3431 }
3432 const effect = new ReactiveEffect(getter, scheduler);
3433 {
3434 effect.onTrack = onTrack;
3435 effect.onTrigger = onTrigger;
3436 }
3437 // initial run
3438 if (cb) {
3439 if (immediate) {
3440 job();
3441 }
3442 else {
3443 oldValue = effect.run();
3444 }
3445 }
3446 else if (flush === 'post') {
3447 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
3448 }
3449 else {
3450 effect.run();
3451 }
3452 const unwatch = () => {
3453 effect.stop();
3454 if (instance && instance.scope) {
3455 remove(instance.scope.effects, effect);
3456 }
3457 };
3458 return unwatch;
3459}
3460// this.$watch
3461function instanceWatch(source, value, options) {
3462 const publicThis = this.proxy;
3463 const getter = isString(source)
3464 ? source.includes('.')
3465 ? createPathGetter(publicThis, source)
3466 : () => publicThis[source]
3467 : source.bind(publicThis, publicThis);
3468 let cb;
3469 if (isFunction(value)) {
3470 cb = value;
3471 }
3472 else {
3473 cb = value.handler;
3474 options = value;
3475 }
3476 const cur = currentInstance;
3477 setCurrentInstance(this);
3478 const res = doWatch(getter, cb.bind(publicThis), options);
3479 if (cur) {
3480 setCurrentInstance(cur);
3481 }
3482 else {
3483 unsetCurrentInstance();
3484 }
3485 return res;
3486}
3487function createPathGetter(ctx, path) {
3488 const segments = path.split('.');
3489 return () => {
3490 let cur = ctx;
3491 for (let i = 0; i < segments.length && cur; i++) {
3492 cur = cur[segments[i]];
3493 }
3494 return cur;
3495 };
3496}
3497function traverse(value, seen) {
3498 if (!isObject(value) || value["__v_skip" /* ReactiveFlags.SKIP */]) {
3499 return value;
3500 }
3501 seen = seen || new Set();
3502 if (seen.has(value)) {
3503 return value;
3504 }
3505 seen.add(value);
3506 if (isRef(value)) {
3507 traverse(value.value, seen);
3508 }
3509 else if (isArray(value)) {
3510 for (let i = 0; i < value.length; i++) {
3511 traverse(value[i], seen);
3512 }
3513 }
3514 else if (isSet(value) || isMap(value)) {
3515 value.forEach((v) => {
3516 traverse(v, seen);
3517 });
3518 }
3519 else if (isPlainObject(value)) {
3520 for (const key in value) {
3521 traverse(value[key], seen);
3522 }
3523 }
3524 return value;
3525}
3526
3527function useTransitionState() {
3528 const state = {
3529 isMounted: false,
3530 isLeaving: false,
3531 isUnmounting: false,
3532 leavingVNodes: new Map()
3533 };
3534 onMounted(() => {
3535 state.isMounted = true;
3536 });
3537 onBeforeUnmount(() => {
3538 state.isUnmounting = true;
3539 });
3540 return state;
3541}
3542const TransitionHookValidator = [Function, Array];
3543const BaseTransitionImpl = {
3544 name: `BaseTransition`,
3545 props: {
3546 mode: String,
3547 appear: Boolean,
3548 persisted: Boolean,
3549 // enter
3550 onBeforeEnter: TransitionHookValidator,
3551 onEnter: TransitionHookValidator,
3552 onAfterEnter: TransitionHookValidator,
3553 onEnterCancelled: TransitionHookValidator,
3554 // leave
3555 onBeforeLeave: TransitionHookValidator,
3556 onLeave: TransitionHookValidator,
3557 onAfterLeave: TransitionHookValidator,
3558 onLeaveCancelled: TransitionHookValidator,
3559 // appear
3560 onBeforeAppear: TransitionHookValidator,
3561 onAppear: TransitionHookValidator,
3562 onAfterAppear: TransitionHookValidator,
3563 onAppearCancelled: TransitionHookValidator
3564 },
3565 setup(props, { slots }) {
3566 const instance = getCurrentInstance();
3567 const state = useTransitionState();
3568 let prevTransitionKey;
3569 return () => {
3570 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3571 if (!children || !children.length) {
3572 return;
3573 }
3574 let child = children[0];
3575 if (children.length > 1) {
3576 let hasFound = false;
3577 // locate first non-comment child
3578 for (const c of children) {
3579 if (c.type !== Comment) {
3580 if (hasFound) {
3581 // warn more than one non-comment child
3582 warn('<transition> can only be used on a single element or component. ' +
3583 'Use <transition-group> for lists.');
3584 break;
3585 }
3586 child = c;
3587 hasFound = true;
3588 }
3589 }
3590 }
3591 // there's no need to track reactivity for these props so use the raw
3592 // props for a bit better perf
3593 const rawProps = toRaw(props);
3594 const { mode } = rawProps;
3595 // check mode
3596 if (mode &&
3597 mode !== 'in-out' &&
3598 mode !== 'out-in' &&
3599 mode !== 'default') {
3600 warn(`invalid <transition> mode: ${mode}`);
3601 }
3602 if (state.isLeaving) {
3603 return emptyPlaceholder(child);
3604 }
3605 // in the case of <transition><keep-alive/></transition>, we need to
3606 // compare the type of the kept-alive children.
3607 const innerChild = getKeepAliveChild(child);
3608 if (!innerChild) {
3609 return emptyPlaceholder(child);
3610 }
3611 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3612 setTransitionHooks(innerChild, enterHooks);
3613 const oldChild = instance.subTree;
3614 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3615 let transitionKeyChanged = false;
3616 const { getTransitionKey } = innerChild.type;
3617 if (getTransitionKey) {
3618 const key = getTransitionKey();
3619 if (prevTransitionKey === undefined) {
3620 prevTransitionKey = key;
3621 }
3622 else if (key !== prevTransitionKey) {
3623 prevTransitionKey = key;
3624 transitionKeyChanged = true;
3625 }
3626 }
3627 // handle mode
3628 if (oldInnerChild &&
3629 oldInnerChild.type !== Comment &&
3630 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3631 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3632 // update old tree's hooks in case of dynamic transition
3633 setTransitionHooks(oldInnerChild, leavingHooks);
3634 // switching between different views
3635 if (mode === 'out-in') {
3636 state.isLeaving = true;
3637 // return placeholder node and queue update when leave finishes
3638 leavingHooks.afterLeave = () => {
3639 state.isLeaving = false;
3640 // #6835
3641 // it also needs to be updated when active is undefined
3642 if (instance.update.active !== false) {
3643 instance.update();
3644 }
3645 };
3646 return emptyPlaceholder(child);
3647 }
3648 else if (mode === 'in-out' && innerChild.type !== Comment) {
3649 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3650 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3651 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3652 // early removal callback
3653 el._leaveCb = () => {
3654 earlyRemove();
3655 el._leaveCb = undefined;
3656 delete enterHooks.delayedLeave;
3657 };
3658 enterHooks.delayedLeave = delayedLeave;
3659 };
3660 }
3661 }
3662 return child;
3663 };
3664 }
3665};
3666// export the public type for h/tsx inference
3667// also to avoid inline import() in generated d.ts files
3668const BaseTransition = BaseTransitionImpl;
3669function getLeavingNodesForType(state, vnode) {
3670 const { leavingVNodes } = state;
3671 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3672 if (!leavingVNodesCache) {
3673 leavingVNodesCache = Object.create(null);
3674 leavingVNodes.set(vnode.type, leavingVNodesCache);
3675 }
3676 return leavingVNodesCache;
3677}
3678// The transition hooks are attached to the vnode as vnode.transition
3679// and will be called at appropriate timing in the renderer.
3680function resolveTransitionHooks(vnode, props, state, instance) {
3681 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3682 const key = String(vnode.key);
3683 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3684 const callHook = (hook, args) => {
3685 hook &&
3686 callWithAsyncErrorHandling(hook, instance, 9 /* ErrorCodes.TRANSITION_HOOK */, args);
3687 };
3688 const callAsyncHook = (hook, args) => {
3689 const done = args[1];
3690 callHook(hook, args);
3691 if (isArray(hook)) {
3692 if (hook.every(hook => hook.length <= 1))
3693 done();
3694 }
3695 else if (hook.length <= 1) {
3696 done();
3697 }
3698 };
3699 const hooks = {
3700 mode,
3701 persisted,
3702 beforeEnter(el) {
3703 let hook = onBeforeEnter;
3704 if (!state.isMounted) {
3705 if (appear) {
3706 hook = onBeforeAppear || onBeforeEnter;
3707 }
3708 else {
3709 return;
3710 }
3711 }
3712 // for same element (v-show)
3713 if (el._leaveCb) {
3714 el._leaveCb(true /* cancelled */);
3715 }
3716 // for toggled element with same key (v-if)
3717 const leavingVNode = leavingVNodesCache[key];
3718 if (leavingVNode &&
3719 isSameVNodeType(vnode, leavingVNode) &&
3720 leavingVNode.el._leaveCb) {
3721 // force early removal (not cancelled)
3722 leavingVNode.el._leaveCb();
3723 }
3724 callHook(hook, [el]);
3725 },
3726 enter(el) {
3727 let hook = onEnter;
3728 let afterHook = onAfterEnter;
3729 let cancelHook = onEnterCancelled;
3730 if (!state.isMounted) {
3731 if (appear) {
3732 hook = onAppear || onEnter;
3733 afterHook = onAfterAppear || onAfterEnter;
3734 cancelHook = onAppearCancelled || onEnterCancelled;
3735 }
3736 else {
3737 return;
3738 }
3739 }
3740 let called = false;
3741 const done = (el._enterCb = (cancelled) => {
3742 if (called)
3743 return;
3744 called = true;
3745 if (cancelled) {
3746 callHook(cancelHook, [el]);
3747 }
3748 else {
3749 callHook(afterHook, [el]);
3750 }
3751 if (hooks.delayedLeave) {
3752 hooks.delayedLeave();
3753 }
3754 el._enterCb = undefined;
3755 });
3756 if (hook) {
3757 callAsyncHook(hook, [el, done]);
3758 }
3759 else {
3760 done();
3761 }
3762 },
3763 leave(el, remove) {
3764 const key = String(vnode.key);
3765 if (el._enterCb) {
3766 el._enterCb(true /* cancelled */);
3767 }
3768 if (state.isUnmounting) {
3769 return remove();
3770 }
3771 callHook(onBeforeLeave, [el]);
3772 let called = false;
3773 const done = (el._leaveCb = (cancelled) => {
3774 if (called)
3775 return;
3776 called = true;
3777 remove();
3778 if (cancelled) {
3779 callHook(onLeaveCancelled, [el]);
3780 }
3781 else {
3782 callHook(onAfterLeave, [el]);
3783 }
3784 el._leaveCb = undefined;
3785 if (leavingVNodesCache[key] === vnode) {
3786 delete leavingVNodesCache[key];
3787 }
3788 });
3789 leavingVNodesCache[key] = vnode;
3790 if (onLeave) {
3791 callAsyncHook(onLeave, [el, done]);
3792 }
3793 else {
3794 done();
3795 }
3796 },
3797 clone(vnode) {
3798 return resolveTransitionHooks(vnode, props, state, instance);
3799 }
3800 };
3801 return hooks;
3802}
3803// the placeholder really only handles one special case: KeepAlive
3804// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3805// placeholder with empty content to avoid the KeepAlive instance from being
3806// unmounted.
3807function emptyPlaceholder(vnode) {
3808 if (isKeepAlive(vnode)) {
3809 vnode = cloneVNode(vnode);
3810 vnode.children = null;
3811 return vnode;
3812 }
3813}
3814function getKeepAliveChild(vnode) {
3815 return isKeepAlive(vnode)
3816 ? vnode.children
3817 ? vnode.children[0]
3818 : undefined
3819 : vnode;
3820}
3821function setTransitionHooks(vnode, hooks) {
3822 if (vnode.shapeFlag & 6 /* ShapeFlags.COMPONENT */ && vnode.component) {
3823 setTransitionHooks(vnode.component.subTree, hooks);
3824 }
3825 else if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
3826 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3827 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3828 }
3829 else {
3830 vnode.transition = hooks;
3831 }
3832}
3833function getTransitionRawChildren(children, keepComment = false, parentKey) {
3834 let ret = [];
3835 let keyedFragmentCount = 0;
3836 for (let i = 0; i < children.length; i++) {
3837 let child = children[i];
3838 // #5360 inherit parent key in case of <template v-for>
3839 const key = parentKey == null
3840 ? child.key
3841 : String(parentKey) + String(child.key != null ? child.key : i);
3842 // handle fragment children case, e.g. v-for
3843 if (child.type === Fragment) {
3844 if (child.patchFlag & 128 /* PatchFlags.KEYED_FRAGMENT */)
3845 keyedFragmentCount++;
3846 ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key));
3847 }
3848 // comment placeholders should be skipped, e.g. v-if
3849 else if (keepComment || child.type !== Comment) {
3850 ret.push(key != null ? cloneVNode(child, { key }) : child);
3851 }
3852 }
3853 // #1126 if a transition children list contains multiple sub fragments, these
3854 // fragments will be merged into a flat children array. Since each v-for
3855 // fragment may contain different static bindings inside, we need to de-op
3856 // these children to force full diffs to ensure correct behavior.
3857 if (keyedFragmentCount > 1) {
3858 for (let i = 0; i < ret.length; i++) {
3859 ret[i].patchFlag = -2 /* PatchFlags.BAIL */;
3860 }
3861 }
3862 return ret;
3863}
3864
3865// implementation, close to no-op
3866function defineComponent(options) {
3867 return isFunction(options) ? { setup: options, name: options.name } : options;
3868}
3869
3870const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
3871function defineAsyncComponent(source) {
3872 if (isFunction(source)) {
3873 source = { loader: source };
3874 }
3875 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
3876 suspensible = true, onError: userOnError } = source;
3877 let pendingRequest = null;
3878 let resolvedComp;
3879 let retries = 0;
3880 const retry = () => {
3881 retries++;
3882 pendingRequest = null;
3883 return load();
3884 };
3885 const load = () => {
3886 let thisRequest;
3887 return (pendingRequest ||
3888 (thisRequest = pendingRequest =
3889 loader()
3890 .catch(err => {
3891 err = err instanceof Error ? err : new Error(String(err));
3892 if (userOnError) {
3893 return new Promise((resolve, reject) => {
3894 const userRetry = () => resolve(retry());
3895 const userFail = () => reject(err);
3896 userOnError(err, userRetry, userFail, retries + 1);
3897 });
3898 }
3899 else {
3900 throw err;
3901 }
3902 })
3903 .then((comp) => {
3904 if (thisRequest !== pendingRequest && pendingRequest) {
3905 return pendingRequest;
3906 }
3907 if (!comp) {
3908 warn(`Async component loader resolved to undefined. ` +
3909 `If you are using retry(), make sure to return its return value.`);
3910 }
3911 // interop module default
3912 if (comp &&
3913 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3914 comp = comp.default;
3915 }
3916 if (comp && !isObject(comp) && !isFunction(comp)) {
3917 throw new Error(`Invalid async component load result: ${comp}`);
3918 }
3919 resolvedComp = comp;
3920 return comp;
3921 })));
3922 };
3923 return defineComponent({
3924 name: 'AsyncComponentWrapper',
3925 __asyncLoader: load,
3926 get __asyncResolved() {
3927 return resolvedComp;
3928 },
3929 setup() {
3930 const instance = currentInstance;
3931 // already resolved
3932 if (resolvedComp) {
3933 return () => createInnerComp(resolvedComp, instance);
3934 }
3935 const onError = (err) => {
3936 pendingRequest = null;
3937 handleError(err, instance, 13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3938 };
3939 // suspense-controlled or SSR.
3940 if ((suspensible && instance.suspense) ||
3941 (false )) {
3942 return load()
3943 .then(comp => {
3944 return () => createInnerComp(comp, instance);
3945 })
3946 .catch(err => {
3947 onError(err);
3948 return () => errorComponent
3949 ? createVNode(errorComponent, {
3950 error: err
3951 })
3952 : null;
3953 });
3954 }
3955 const loaded = ref(false);
3956 const error = ref();
3957 const delayed = ref(!!delay);
3958 if (delay) {
3959 setTimeout(() => {
3960 delayed.value = false;
3961 }, delay);
3962 }
3963 if (timeout != null) {
3964 setTimeout(() => {
3965 if (!loaded.value && !error.value) {
3966 const err = new Error(`Async component timed out after ${timeout}ms.`);
3967 onError(err);
3968 error.value = err;
3969 }
3970 }, timeout);
3971 }
3972 load()
3973 .then(() => {
3974 loaded.value = true;
3975 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3976 // parent is keep-alive, force update so the loaded component's
3977 // name is taken into account
3978 queueJob(instance.parent.update);
3979 }
3980 })
3981 .catch(err => {
3982 onError(err);
3983 error.value = err;
3984 });
3985 return () => {
3986 if (loaded.value && resolvedComp) {
3987 return createInnerComp(resolvedComp, instance);
3988 }
3989 else if (error.value && errorComponent) {
3990 return createVNode(errorComponent, {
3991 error: error.value
3992 });
3993 }
3994 else if (loadingComponent && !delayed.value) {
3995 return createVNode(loadingComponent);
3996 }
3997 };
3998 }
3999 });
4000}
4001function createInnerComp(comp, parent) {
4002 const { ref, props, children, ce } = parent.vnode;
4003 const vnode = createVNode(comp, props, children);
4004 // ensure inner component inherits the async wrapper's ref owner
4005 vnode.ref = ref;
4006 // pass the custom element callback on to the inner comp
4007 // and remove it from the async wrapper
4008 vnode.ce = ce;
4009 delete parent.vnode.ce;
4010 return vnode;
4011}
4012
4013const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
4014const KeepAliveImpl = {
4015 name: `KeepAlive`,
4016 // Marker for special handling inside the renderer. We are not using a ===
4017 // check directly on KeepAlive in the renderer, because importing it directly
4018 // would prevent it from being tree-shaken.
4019 __isKeepAlive: true,
4020 props: {
4021 include: [String, RegExp, Array],
4022 exclude: [String, RegExp, Array],
4023 max: [String, Number]
4024 },
4025 setup(props, { slots }) {
4026 const instance = getCurrentInstance();
4027 // KeepAlive communicates with the instantiated renderer via the
4028 // ctx where the renderer passes in its internals,
4029 // and the KeepAlive instance exposes activate/deactivate implementations.
4030 // The whole point of this is to avoid importing KeepAlive directly in the
4031 // renderer to facilitate tree-shaking.
4032 const sharedContext = instance.ctx;
4033 const cache = new Map();
4034 const keys = new Set();
4035 let current = null;
4036 {
4037 instance.__v_cache = cache;
4038 }
4039 const parentSuspense = instance.suspense;
4040 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
4041 const storageContainer = createElement('div');
4042 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
4043 const instance = vnode.component;
4044 move(vnode, container, anchor, 0 /* MoveType.ENTER */, parentSuspense);
4045 // in case props have changed
4046 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
4047 queuePostRenderEffect(() => {
4048 instance.isDeactivated = false;
4049 if (instance.a) {
4050 invokeArrayFns(instance.a);
4051 }
4052 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
4053 if (vnodeHook) {
4054 invokeVNodeHook(vnodeHook, instance.parent, vnode);
4055 }
4056 }, parentSuspense);
4057 {
4058 // Update components tree
4059 devtoolsComponentAdded(instance);
4060 }
4061 };
4062 sharedContext.deactivate = (vnode) => {
4063 const instance = vnode.component;
4064 move(vnode, storageContainer, null, 1 /* MoveType.LEAVE */, parentSuspense);
4065 queuePostRenderEffect(() => {
4066 if (instance.da) {
4067 invokeArrayFns(instance.da);
4068 }
4069 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
4070 if (vnodeHook) {
4071 invokeVNodeHook(vnodeHook, instance.parent, vnode);
4072 }
4073 instance.isDeactivated = true;
4074 }, parentSuspense);
4075 {
4076 // Update components tree
4077 devtoolsComponentAdded(instance);
4078 }
4079 };
4080 function unmount(vnode) {
4081 // reset the shapeFlag so it can be properly unmounted
4082 resetShapeFlag(vnode);
4083 _unmount(vnode, instance, parentSuspense, true);
4084 }
4085 function pruneCache(filter) {
4086 cache.forEach((vnode, key) => {
4087 const name = getComponentName(vnode.type);
4088 if (name && (!filter || !filter(name))) {
4089 pruneCacheEntry(key);
4090 }
4091 });
4092 }
4093 function pruneCacheEntry(key) {
4094 const cached = cache.get(key);
4095 if (!current || !isSameVNodeType(cached, current)) {
4096 unmount(cached);
4097 }
4098 else if (current) {
4099 // current active instance should no longer be kept-alive.
4100 // we can't unmount it now but it might be later, so reset its flag now.
4101 resetShapeFlag(current);
4102 }
4103 cache.delete(key);
4104 keys.delete(key);
4105 }
4106 // prune cache on include/exclude prop change
4107 watch(() => [props.include, props.exclude], ([include, exclude]) => {
4108 include && pruneCache(name => matches(include, name));
4109 exclude && pruneCache(name => !matches(exclude, name));
4110 },
4111 // prune post-render after `current` has been updated
4112 { flush: 'post', deep: true });
4113 // cache sub tree after render
4114 let pendingCacheKey = null;
4115 const cacheSubtree = () => {
4116 // fix #1621, the pendingCacheKey could be 0
4117 if (pendingCacheKey != null) {
4118 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
4119 }
4120 };
4121 onMounted(cacheSubtree);
4122 onUpdated(cacheSubtree);
4123 onBeforeUnmount(() => {
4124 cache.forEach(cached => {
4125 const { subTree, suspense } = instance;
4126 const vnode = getInnerChild(subTree);
4127 if (cached.type === vnode.type && cached.key === vnode.key) {
4128 // current instance will be unmounted as part of keep-alive's unmount
4129 resetShapeFlag(vnode);
4130 // but invoke its deactivated hook here
4131 const da = vnode.component.da;
4132 da && queuePostRenderEffect(da, suspense);
4133 return;
4134 }
4135 unmount(cached);
4136 });
4137 });
4138 return () => {
4139 pendingCacheKey = null;
4140 if (!slots.default) {
4141 return null;
4142 }
4143 const children = slots.default();
4144 const rawVNode = children[0];
4145 if (children.length > 1) {
4146 {
4147 warn(`KeepAlive should contain exactly one component child.`);
4148 }
4149 current = null;
4150 return children;
4151 }
4152 else if (!isVNode(rawVNode) ||
4153 (!(rawVNode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */) &&
4154 !(rawVNode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */))) {
4155 current = null;
4156 return rawVNode;
4157 }
4158 let vnode = getInnerChild(rawVNode);
4159 const comp = vnode.type;
4160 // for async components, name check should be based in its loaded
4161 // inner component if available
4162 const name = getComponentName(isAsyncWrapper(vnode)
4163 ? vnode.type.__asyncResolved || {}
4164 : comp);
4165 const { include, exclude, max } = props;
4166 if ((include && (!name || !matches(include, name))) ||
4167 (exclude && name && matches(exclude, name))) {
4168 current = vnode;
4169 return rawVNode;
4170 }
4171 const key = vnode.key == null ? comp : vnode.key;
4172 const cachedVNode = cache.get(key);
4173 // clone vnode if it's reused because we are going to mutate it
4174 if (vnode.el) {
4175 vnode = cloneVNode(vnode);
4176 if (rawVNode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
4177 rawVNode.ssContent = vnode;
4178 }
4179 }
4180 // #1513 it's possible for the returned vnode to be cloned due to attr
4181 // fallthrough or scopeId, so the vnode here may not be the final vnode
4182 // that is mounted. Instead of caching it directly, we store the pending
4183 // key and cache `instance.subTree` (the normalized vnode) in
4184 // beforeMount/beforeUpdate hooks.
4185 pendingCacheKey = key;
4186 if (cachedVNode) {
4187 // copy over mounted state
4188 vnode.el = cachedVNode.el;
4189 vnode.component = cachedVNode.component;
4190 if (vnode.transition) {
4191 // recursively update transition hooks on subTree
4192 setTransitionHooks(vnode, vnode.transition);
4193 }
4194 // avoid vnode being mounted as fresh
4195 vnode.shapeFlag |= 512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */;
4196 // make this key the freshest
4197 keys.delete(key);
4198 keys.add(key);
4199 }
4200 else {
4201 keys.add(key);
4202 // prune oldest entry
4203 if (max && keys.size > parseInt(max, 10)) {
4204 pruneCacheEntry(keys.values().next().value);
4205 }
4206 }
4207 // avoid vnode being unmounted
4208 vnode.shapeFlag |= 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */;
4209 current = vnode;
4210 return isSuspense(rawVNode.type) ? rawVNode : vnode;
4211 };
4212 }
4213};
4214// export the public type for h/tsx inference
4215// also to avoid inline import() in generated d.ts files
4216const KeepAlive = KeepAliveImpl;
4217function matches(pattern, name) {
4218 if (isArray(pattern)) {
4219 return pattern.some((p) => matches(p, name));
4220 }
4221 else if (isString(pattern)) {
4222 return pattern.split(',').includes(name);
4223 }
4224 else if (isRegExp(pattern)) {
4225 return pattern.test(name);
4226 }
4227 /* istanbul ignore next */
4228 return false;
4229}
4230function onActivated(hook, target) {
4231 registerKeepAliveHook(hook, "a" /* LifecycleHooks.ACTIVATED */, target);
4232}
4233function onDeactivated(hook, target) {
4234 registerKeepAliveHook(hook, "da" /* LifecycleHooks.DEACTIVATED */, target);
4235}
4236function registerKeepAliveHook(hook, type, target = currentInstance) {
4237 // cache the deactivate branch check wrapper for injected hooks so the same
4238 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
4239 // deactivation check".
4240 const wrappedHook = hook.__wdc ||
4241 (hook.__wdc = () => {
4242 // only fire the hook if the target instance is NOT in a deactivated branch.
4243 let current = target;
4244 while (current) {
4245 if (current.isDeactivated) {
4246 return;
4247 }
4248 current = current.parent;
4249 }
4250 return hook();
4251 });
4252 injectHook(type, wrappedHook, target);
4253 // In addition to registering it on the target instance, we walk up the parent
4254 // chain and register it on all ancestor instances that are keep-alive roots.
4255 // This avoids the need to walk the entire component tree when invoking these
4256 // hooks, and more importantly, avoids the need to track child components in
4257 // arrays.
4258 if (target) {
4259 let current = target.parent;
4260 while (current && current.parent) {
4261 if (isKeepAlive(current.parent.vnode)) {
4262 injectToKeepAliveRoot(wrappedHook, type, target, current);
4263 }
4264 current = current.parent;
4265 }
4266 }
4267}
4268function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
4269 // injectHook wraps the original for error handling, so make sure to remove
4270 // the wrapped version.
4271 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4272 onUnmounted(() => {
4273 remove(keepAliveRoot[type], injected);
4274 }, target);
4275}
4276function resetShapeFlag(vnode) {
4277 // bitwise operations to remove keep alive flags
4278 vnode.shapeFlag &= ~256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */;
4279 vnode.shapeFlag &= ~512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */;
4280}
4281function getInnerChild(vnode) {
4282 return vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */ ? vnode.ssContent : vnode;
4283}
4284
4285function injectHook(type, hook, target = currentInstance, prepend = false) {
4286 if (target) {
4287 const hooks = target[type] || (target[type] = []);
4288 // cache the error handling wrapper for injected hooks so the same hook
4289 // can be properly deduped by the scheduler. "__weh" stands for "with error
4290 // handling".
4291 const wrappedHook = hook.__weh ||
4292 (hook.__weh = (...args) => {
4293 if (target.isUnmounted) {
4294 return;
4295 }
4296 // disable tracking inside all lifecycle hooks
4297 // since they can potentially be called inside effects.
4298 pauseTracking();
4299 // Set currentInstance during hook invocation.
4300 // This assumes the hook does not synchronously trigger other hooks, which
4301 // can only be false when the user does something really funky.
4302 setCurrentInstance(target);
4303 const res = callWithAsyncErrorHandling(hook, target, type, args);
4304 unsetCurrentInstance();
4305 resetTracking();
4306 return res;
4307 });
4308 if (prepend) {
4309 hooks.unshift(wrappedHook);
4310 }
4311 else {
4312 hooks.push(wrappedHook);
4313 }
4314 return wrappedHook;
4315 }
4316 else {
4317 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
4318 warn(`${apiName} is called when there is no active component instance to be ` +
4319 `associated with. ` +
4320 `Lifecycle injection APIs can only be used during execution of setup().` +
4321 (` If you are using async setup(), make sure to register lifecycle ` +
4322 `hooks before the first await statement.`
4323 ));
4324 }
4325}
4326const createHook = (lifecycle) => (hook, target = currentInstance) =>
4327// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
4328(!isInSSRComponentSetup || lifecycle === "sp" /* LifecycleHooks.SERVER_PREFETCH */) &&
4329 injectHook(lifecycle, (...args) => hook(...args), target);
4330const onBeforeMount = createHook("bm" /* LifecycleHooks.BEFORE_MOUNT */);
4331const onMounted = createHook("m" /* LifecycleHooks.MOUNTED */);
4332const onBeforeUpdate = createHook("bu" /* LifecycleHooks.BEFORE_UPDATE */);
4333const onUpdated = createHook("u" /* LifecycleHooks.UPDATED */);
4334const onBeforeUnmount = createHook("bum" /* LifecycleHooks.BEFORE_UNMOUNT */);
4335const onUnmounted = createHook("um" /* LifecycleHooks.UNMOUNTED */);
4336const onServerPrefetch = createHook("sp" /* LifecycleHooks.SERVER_PREFETCH */);
4337const onRenderTriggered = createHook("rtg" /* LifecycleHooks.RENDER_TRIGGERED */);
4338const onRenderTracked = createHook("rtc" /* LifecycleHooks.RENDER_TRACKED */);
4339function onErrorCaptured(hook, target = currentInstance) {
4340 injectHook("ec" /* LifecycleHooks.ERROR_CAPTURED */, hook, target);
4341}
4342
4343/**
4344Runtime helper for applying directives to a vnode. Example usage:
4345
4346const comp = resolveComponent('comp')
4347const foo = resolveDirective('foo')
4348const bar = resolveDirective('bar')
4349
4350return withDirectives(h(comp), [
4351 [foo, this.x],
4352 [bar, this.y]
4353])
4354*/
4355function validateDirectiveName(name) {
4356 if (isBuiltInDirective(name)) {
4357 warn('Do not use built-in directive ids as custom directive id: ' + name);
4358 }
4359}
4360/**
4361 * Adds directives to a VNode.
4362 */
4363function withDirectives(vnode, directives) {
4364 const internalInstance = currentRenderingInstance;
4365 if (internalInstance === null) {
4366 warn(`withDirectives can only be used inside render functions.`);
4367 return vnode;
4368 }
4369 const instance = getExposeProxy(internalInstance) ||
4370 internalInstance.proxy;
4371 const bindings = vnode.dirs || (vnode.dirs = []);
4372 for (let i = 0; i < directives.length; i++) {
4373 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4374 if (dir) {
4375 if (isFunction(dir)) {
4376 dir = {
4377 mounted: dir,
4378 updated: dir
4379 };
4380 }
4381 if (dir.deep) {
4382 traverse(value);
4383 }
4384 bindings.push({
4385 dir,
4386 instance,
4387 value,
4388 oldValue: void 0,
4389 arg,
4390 modifiers
4391 });
4392 }
4393 }
4394 return vnode;
4395}
4396function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4397 const bindings = vnode.dirs;
4398 const oldBindings = prevVNode && prevVNode.dirs;
4399 for (let i = 0; i < bindings.length; i++) {
4400 const binding = bindings[i];
4401 if (oldBindings) {
4402 binding.oldValue = oldBindings[i].value;
4403 }
4404 let hook = binding.dir[name];
4405 if (hook) {
4406 // disable tracking inside all lifecycle hooks
4407 // since they can potentially be called inside effects.
4408 pauseTracking();
4409 callWithAsyncErrorHandling(hook, instance, 8 /* ErrorCodes.DIRECTIVE_HOOK */, [
4410 vnode.el,
4411 binding,
4412 vnode,
4413 prevVNode
4414 ]);
4415 resetTracking();
4416 }
4417 }
4418}
4419
4420const COMPONENTS = 'components';
4421const DIRECTIVES = 'directives';
4422/**
4423 * @private
4424 */
4425function resolveComponent(name, maybeSelfReference) {
4426 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
4427}
4428const NULL_DYNAMIC_COMPONENT = Symbol();
4429/**
4430 * @private
4431 */
4432function resolveDynamicComponent(component) {
4433 if (isString(component)) {
4434 return resolveAsset(COMPONENTS, component, false) || component;
4435 }
4436 else {
4437 // invalid types will fallthrough to createVNode and raise warning
4438 return (component || NULL_DYNAMIC_COMPONENT);
4439 }
4440}
4441/**
4442 * @private
4443 */
4444function resolveDirective(name) {
4445 return resolveAsset(DIRECTIVES, name);
4446}
4447// implementation
4448function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
4449 const instance = currentRenderingInstance || currentInstance;
4450 if (instance) {
4451 const Component = instance.type;
4452 // explicit self name has highest priority
4453 if (type === COMPONENTS) {
4454 const selfName = getComponentName(Component, false /* do not include inferred name to avoid breaking existing code */);
4455 if (selfName &&
4456 (selfName === name ||
4457 selfName === camelize(name) ||
4458 selfName === capitalize(camelize(name)))) {
4459 return Component;
4460 }
4461 }
4462 const res =
4463 // local registration
4464 // check instance[type] first which is resolved for options API
4465 resolve(instance[type] || Component[type], name) ||
4466 // global registration
4467 resolve(instance.appContext[type], name);
4468 if (!res && maybeSelfReference) {
4469 // fallback to implicit self-reference
4470 return Component;
4471 }
4472 if (warnMissing && !res) {
4473 const extra = type === COMPONENTS
4474 ? `\nIf this is a native custom element, make sure to exclude it from ` +
4475 `component resolution via compilerOptions.isCustomElement.`
4476 : ``;
4477 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
4478 }
4479 return res;
4480 }
4481 else {
4482 warn(`resolve${capitalize(type.slice(0, -1))} ` +
4483 `can only be used in render() or setup().`);
4484 }
4485}
4486function resolve(registry, name) {
4487 return (registry &&
4488 (registry[name] ||
4489 registry[camelize(name)] ||
4490 registry[capitalize(camelize(name))]));
4491}
4492
4493/**
4494 * Actual implementation
4495 */
4496function renderList(source, renderItem, cache, index) {
4497 let ret;
4498 const cached = (cache && cache[index]);
4499 if (isArray(source) || isString(source)) {
4500 ret = new Array(source.length);
4501 for (let i = 0, l = source.length; i < l; i++) {
4502 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
4503 }
4504 }
4505 else if (typeof source === 'number') {
4506 if (!Number.isInteger(source)) {
4507 warn(`The v-for range expect an integer value but got ${source}.`);
4508 }
4509 ret = new Array(source);
4510 for (let i = 0; i < source; i++) {
4511 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
4512 }
4513 }
4514 else if (isObject(source)) {
4515 if (source[Symbol.iterator]) {
4516 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
4517 }
4518 else {
4519 const keys = Object.keys(source);
4520 ret = new Array(keys.length);
4521 for (let i = 0, l = keys.length; i < l; i++) {
4522 const key = keys[i];
4523 ret[i] = renderItem(source[key], key, i, cached && cached[i]);
4524 }
4525 }
4526 }
4527 else {
4528 ret = [];
4529 }
4530 if (cache) {
4531 cache[index] = ret;
4532 }
4533 return ret;
4534}
4535
4536/**
4537 * Compiler runtime helper for creating dynamic slots object
4538 * @private
4539 */
4540function createSlots(slots, dynamicSlots) {
4541 for (let i = 0; i < dynamicSlots.length; i++) {
4542 const slot = dynamicSlots[i];
4543 // array of dynamic slot generated by <template v-for="..." #[...]>
4544 if (isArray(slot)) {
4545 for (let j = 0; j < slot.length; j++) {
4546 slots[slot[j].name] = slot[j].fn;
4547 }
4548 }
4549 else if (slot) {
4550 // conditional single slot generated by <template v-if="..." #foo>
4551 slots[slot.name] = slot.key
4552 ? (...args) => {
4553 const res = slot.fn(...args);
4554 // attach branch key so each conditional branch is considered a
4555 // different fragment
4556 if (res)
4557 res.key = slot.key;
4558 return res;
4559 }
4560 : slot.fn;
4561 }
4562 }
4563 return slots;
4564}
4565
4566/**
4567 * Compiler runtime helper for rendering `<slot/>`
4568 * @private
4569 */
4570function renderSlot(slots, name, props = {},
4571// this is not a user-facing function, so the fallback is always generated by
4572// the compiler and guaranteed to be a function returning an array
4573fallback, noSlotted) {
4574 if (currentRenderingInstance.isCE ||
4575 (currentRenderingInstance.parent &&
4576 isAsyncWrapper(currentRenderingInstance.parent) &&
4577 currentRenderingInstance.parent.isCE)) {
4578 if (name !== 'default')
4579 props.name = name;
4580 return createVNode('slot', props, fallback && fallback());
4581 }
4582 let slot = slots[name];
4583 if (slot && slot.length > 1) {
4584 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
4585 `function. You need to mark this component with $dynamic-slots in the ` +
4586 `parent template.`);
4587 slot = () => [];
4588 }
4589 // a compiled slot disables block tracking by default to avoid manual
4590 // invocation interfering with template-based block tracking, but in
4591 // `renderSlot` we can be sure that it's template-based so we can force
4592 // enable it.
4593 if (slot && slot._c) {
4594 slot._d = false;
4595 }
4596 openBlock();
4597 const validSlotContent = slot && ensureValidVNode(slot(props));
4598 const rendered = createBlock(Fragment, {
4599 key: props.key ||
4600 // slot content array of a dynamic conditional slot may have a branch
4601 // key attached in the `createSlots` helper, respect that
4602 (validSlotContent && validSlotContent.key) ||
4603 `_${name}`
4604 }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* SlotFlags.STABLE */
4605 ? 64 /* PatchFlags.STABLE_FRAGMENT */
4606 : -2 /* PatchFlags.BAIL */);
4607 if (!noSlotted && rendered.scopeId) {
4608 rendered.slotScopeIds = [rendered.scopeId + '-s'];
4609 }
4610 if (slot && slot._c) {
4611 slot._d = true;
4612 }
4613 return rendered;
4614}
4615function ensureValidVNode(vnodes) {
4616 return vnodes.some(child => {
4617 if (!isVNode(child))
4618 return true;
4619 if (child.type === Comment)
4620 return false;
4621 if (child.type === Fragment &&
4622 !ensureValidVNode(child.children))
4623 return false;
4624 return true;
4625 })
4626 ? vnodes
4627 : null;
4628}
4629
4630/**
4631 * For prefixing keys in v-on="obj" with "on"
4632 * @private
4633 */
4634function toHandlers(obj, preserveCaseIfNecessary) {
4635 const ret = {};
4636 if (!isObject(obj)) {
4637 warn(`v-on with no argument expects an object value.`);
4638 return ret;
4639 }
4640 for (const key in obj) {
4641 ret[preserveCaseIfNecessary && /[A-Z]/.test(key)
4642 ? `on:${key}`
4643 : toHandlerKey(key)] = obj[key];
4644 }
4645 return ret;
4646}
4647
4648/**
4649 * #2437 In Vue 3, functional components do not have a public instance proxy but
4650 * they exist in the internal parent chain. For code that relies on traversing
4651 * public $parent chains, skip functional ones and go to the parent instead.
4652 */
4653const getPublicInstance = (i) => {
4654 if (!i)
4655 return null;
4656 if (isStatefulComponent(i))
4657 return getExposeProxy(i) || i.proxy;
4658 return getPublicInstance(i.parent);
4659};
4660const publicPropertiesMap =
4661// Move PURE marker to new line to workaround compiler discarding it
4662// due to type annotation
4663/*#__PURE__*/ extend(Object.create(null), {
4664 $: i => i,
4665 $el: i => i.vnode.el,
4666 $data: i => i.data,
4667 $props: i => (shallowReadonly(i.props) ),
4668 $attrs: i => (shallowReadonly(i.attrs) ),
4669 $slots: i => (shallowReadonly(i.slots) ),
4670 $refs: i => (shallowReadonly(i.refs) ),
4671 $parent: i => getPublicInstance(i.parent),
4672 $root: i => getPublicInstance(i.root),
4673 $emit: i => i.emit,
4674 $options: i => (resolveMergedOptions(i) ),
4675 $forceUpdate: i => i.f || (i.f = () => queueJob(i.update)),
4676 $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)),
4677 $watch: i => (instanceWatch.bind(i) )
4678});
4679const isReservedPrefix = (key) => key === '_' || key === '$';
4680const hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key);
4681const PublicInstanceProxyHandlers = {
4682 get({ _: instance }, key) {
4683 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
4684 // for internal formatters to know that this is a Vue instance
4685 if (key === '__isVue') {
4686 return true;
4687 }
4688 // data / props / ctx
4689 // This getter gets called for every property access on the render context
4690 // during render and is a major hotspot. The most expensive part of this
4691 // is the multiple hasOwn() calls. It's much faster to do a simple property
4692 // access on a plain object, so we use an accessCache object (with null
4693 // prototype) to memoize what access type a key corresponds to.
4694 let normalizedProps;
4695 if (key[0] !== '$') {
4696 const n = accessCache[key];
4697 if (n !== undefined) {
4698 switch (n) {
4699 case 1 /* AccessTypes.SETUP */:
4700 return setupState[key];
4701 case 2 /* AccessTypes.DATA */:
4702 return data[key];
4703 case 4 /* AccessTypes.CONTEXT */:
4704 return ctx[key];
4705 case 3 /* AccessTypes.PROPS */:
4706 return props[key];
4707 // default: just fallthrough
4708 }
4709 }
4710 else if (hasSetupBinding(setupState, key)) {
4711 accessCache[key] = 1 /* AccessTypes.SETUP */;
4712 return setupState[key];
4713 }
4714 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4715 accessCache[key] = 2 /* AccessTypes.DATA */;
4716 return data[key];
4717 }
4718 else if (
4719 // only cache other properties when instance has declared (thus stable)
4720 // props
4721 (normalizedProps = instance.propsOptions[0]) &&
4722 hasOwn(normalizedProps, key)) {
4723 accessCache[key] = 3 /* AccessTypes.PROPS */;
4724 return props[key];
4725 }
4726 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4727 accessCache[key] = 4 /* AccessTypes.CONTEXT */;
4728 return ctx[key];
4729 }
4730 else if (shouldCacheAccess) {
4731 accessCache[key] = 0 /* AccessTypes.OTHER */;
4732 }
4733 }
4734 const publicGetter = publicPropertiesMap[key];
4735 let cssModule, globalProperties;
4736 // public $xxx properties
4737 if (publicGetter) {
4738 if (key === '$attrs') {
4739 track(instance, "get" /* TrackOpTypes.GET */, key);
4740 markAttrsAccessed();
4741 }
4742 return publicGetter(instance);
4743 }
4744 else if (
4745 // css module (injected by vue-loader)
4746 (cssModule = type.__cssModules) &&
4747 (cssModule = cssModule[key])) {
4748 return cssModule;
4749 }
4750 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4751 // user may set custom properties to `this` that start with `$`
4752 accessCache[key] = 4 /* AccessTypes.CONTEXT */;
4753 return ctx[key];
4754 }
4755 else if (
4756 // global properties
4757 ((globalProperties = appContext.config.globalProperties),
4758 hasOwn(globalProperties, key))) {
4759 {
4760 return globalProperties[key];
4761 }
4762 }
4763 else if (currentRenderingInstance &&
4764 (!isString(key) ||
4765 // #1091 avoid internal isRef/isVNode checks on component instance leading
4766 // to infinite warning loop
4767 key.indexOf('__v') !== 0)) {
4768 if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {
4769 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
4770 `character ("$" or "_") and is not proxied on the render context.`);
4771 }
4772 else if (instance === currentRenderingInstance) {
4773 warn(`Property ${JSON.stringify(key)} was accessed during render ` +
4774 `but is not defined on instance.`);
4775 }
4776 }
4777 },
4778 set({ _: instance }, key, value) {
4779 const { data, setupState, ctx } = instance;
4780 if (hasSetupBinding(setupState, key)) {
4781 setupState[key] = value;
4782 return true;
4783 }
4784 else if (setupState.__isScriptSetup &&
4785 hasOwn(setupState, key)) {
4786 warn(`Cannot mutate <script setup> binding "${key}" from Options API.`);
4787 return false;
4788 }
4789 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4790 data[key] = value;
4791 return true;
4792 }
4793 else if (hasOwn(instance.props, key)) {
4794 warn(`Attempting to mutate prop "${key}". Props are readonly.`);
4795 return false;
4796 }
4797 if (key[0] === '$' && key.slice(1) in instance) {
4798 warn(`Attempting to mutate public property "${key}". ` +
4799 `Properties starting with $ are reserved and readonly.`);
4800 return false;
4801 }
4802 else {
4803 if (key in instance.appContext.config.globalProperties) {
4804 Object.defineProperty(ctx, key, {
4805 enumerable: true,
4806 configurable: true,
4807 value
4808 });
4809 }
4810 else {
4811 ctx[key] = value;
4812 }
4813 }
4814 return true;
4815 },
4816 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
4817 let normalizedProps;
4818 return (!!accessCache[key] ||
4819 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
4820 hasSetupBinding(setupState, key) ||
4821 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
4822 hasOwn(ctx, key) ||
4823 hasOwn(publicPropertiesMap, key) ||
4824 hasOwn(appContext.config.globalProperties, key));
4825 },
4826 defineProperty(target, key, descriptor) {
4827 if (descriptor.get != null) {
4828 // invalidate key cache of a getter based property #5417
4829 target._.accessCache[key] = 0;
4830 }
4831 else if (hasOwn(descriptor, 'value')) {
4832 this.set(target, key, descriptor.value, null);
4833 }
4834 return Reflect.defineProperty(target, key, descriptor);
4835 }
4836};
4837{
4838 PublicInstanceProxyHandlers.ownKeys = (target) => {
4839 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
4840 `The keys will be empty in production mode to avoid performance overhead.`);
4841 return Reflect.ownKeys(target);
4842 };
4843}
4844const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, {
4845 get(target, key) {
4846 // fast path for unscopables when using `with` block
4847 if (key === Symbol.unscopables) {
4848 return;
4849 }
4850 return PublicInstanceProxyHandlers.get(target, key, target);
4851 },
4852 has(_, key) {
4853 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
4854 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
4855 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
4856 }
4857 return has;
4858 }
4859});
4860// dev only
4861// In dev mode, the proxy target exposes the same properties as seen on `this`
4862// for easier console inspection. In prod mode it will be an empty object so
4863// these properties definitions can be skipped.
4864function createDevRenderContext(instance) {
4865 const target = {};
4866 // expose internal instance for proxy handlers
4867 Object.defineProperty(target, `_`, {
4868 configurable: true,
4869 enumerable: false,
4870 get: () => instance
4871 });
4872 // expose public properties
4873 Object.keys(publicPropertiesMap).forEach(key => {
4874 Object.defineProperty(target, key, {
4875 configurable: true,
4876 enumerable: false,
4877 get: () => publicPropertiesMap[key](instance),
4878 // intercepted by the proxy so no need for implementation,
4879 // but needed to prevent set errors
4880 set: NOOP
4881 });
4882 });
4883 return target;
4884}
4885// dev only
4886function exposePropsOnRenderContext(instance) {
4887 const { ctx, propsOptions: [propsOptions] } = instance;
4888 if (propsOptions) {
4889 Object.keys(propsOptions).forEach(key => {
4890 Object.defineProperty(ctx, key, {
4891 enumerable: true,
4892 configurable: true,
4893 get: () => instance.props[key],
4894 set: NOOP
4895 });
4896 });
4897 }
4898}
4899// dev only
4900function exposeSetupStateOnRenderContext(instance) {
4901 const { ctx, setupState } = instance;
4902 Object.keys(toRaw(setupState)).forEach(key => {
4903 if (!setupState.__isScriptSetup) {
4904 if (isReservedPrefix(key[0])) {
4905 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
4906 `which are reserved prefixes for Vue internals.`);
4907 return;
4908 }
4909 Object.defineProperty(ctx, key, {
4910 enumerable: true,
4911 configurable: true,
4912 get: () => setupState[key],
4913 set: NOOP
4914 });
4915 }
4916 });
4917}
4918
4919function createDuplicateChecker() {
4920 const cache = Object.create(null);
4921 return (type, key) => {
4922 if (cache[key]) {
4923 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
4924 }
4925 else {
4926 cache[key] = type;
4927 }
4928 };
4929}
4930let shouldCacheAccess = true;
4931function applyOptions(instance) {
4932 const options = resolveMergedOptions(instance);
4933 const publicThis = instance.proxy;
4934 const ctx = instance.ctx;
4935 // do not cache property access on public proxy during state initialization
4936 shouldCacheAccess = false;
4937 // call beforeCreate first before accessing other options since
4938 // the hook may mutate resolved options (#2791)
4939 if (options.beforeCreate) {
4940 callHook$1(options.beforeCreate, instance, "bc" /* LifecycleHooks.BEFORE_CREATE */);
4941 }
4942 const {
4943 // state
4944 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
4945 // lifecycle
4946 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
4947 // public API
4948 expose, inheritAttrs,
4949 // assets
4950 components, directives, filters } = options;
4951 const checkDuplicateProperties = createDuplicateChecker() ;
4952 {
4953 const [propsOptions] = instance.propsOptions;
4954 if (propsOptions) {
4955 for (const key in propsOptions) {
4956 checkDuplicateProperties("Props" /* OptionTypes.PROPS */, key);
4957 }
4958 }
4959 }
4960 // options initialization order (to be consistent with Vue 2):
4961 // - props (already done outside of this function)
4962 // - inject
4963 // - methods
4964 // - data (deferred since it relies on `this` access)
4965 // - computed
4966 // - watch (deferred since it relies on `this` access)
4967 if (injectOptions) {
4968 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
4969 }
4970 if (methods) {
4971 for (const key in methods) {
4972 const methodHandler = methods[key];
4973 if (isFunction(methodHandler)) {
4974 // In dev mode, we use the `createRenderContext` function to define
4975 // methods to the proxy target, and those are read-only but
4976 // reconfigurable, so it needs to be redefined here
4977 {
4978 Object.defineProperty(ctx, key, {
4979 value: methodHandler.bind(publicThis),
4980 configurable: true,
4981 enumerable: true,
4982 writable: true
4983 });
4984 }
4985 {
4986 checkDuplicateProperties("Methods" /* OptionTypes.METHODS */, key);
4987 }
4988 }
4989 else {
4990 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
4991 `Did you reference the function correctly?`);
4992 }
4993 }
4994 }
4995 if (dataOptions) {
4996 if (!isFunction(dataOptions)) {
4997 warn(`The data option must be a function. ` +
4998 `Plain object usage is no longer supported.`);
4999 }
5000 const data = dataOptions.call(publicThis, publicThis);
5001 if (isPromise(data)) {
5002 warn(`data() returned a Promise - note data() cannot be async; If you ` +
5003 `intend to perform data fetching before component renders, use ` +
5004 `async setup() + <Suspense>.`);
5005 }
5006 if (!isObject(data)) {
5007 warn(`data() should return an object.`);
5008 }
5009 else {
5010 instance.data = reactive(data);
5011 {
5012 for (const key in data) {
5013 checkDuplicateProperties("Data" /* OptionTypes.DATA */, key);
5014 // expose data on ctx during dev
5015 if (!isReservedPrefix(key[0])) {
5016 Object.defineProperty(ctx, key, {
5017 configurable: true,
5018 enumerable: true,
5019 get: () => data[key],
5020 set: NOOP
5021 });
5022 }
5023 }
5024 }
5025 }
5026 }
5027 // state initialization complete at this point - start caching access
5028 shouldCacheAccess = true;
5029 if (computedOptions) {
5030 for (const key in computedOptions) {
5031 const opt = computedOptions[key];
5032 const get = isFunction(opt)
5033 ? opt.bind(publicThis, publicThis)
5034 : isFunction(opt.get)
5035 ? opt.get.bind(publicThis, publicThis)
5036 : NOOP;
5037 if (get === NOOP) {
5038 warn(`Computed property "${key}" has no getter.`);
5039 }
5040 const set = !isFunction(opt) && isFunction(opt.set)
5041 ? opt.set.bind(publicThis)
5042 : () => {
5043 warn(`Write operation failed: computed property "${key}" is readonly.`);
5044 }
5045 ;
5046 const c = computed({
5047 get,
5048 set
5049 });
5050 Object.defineProperty(ctx, key, {
5051 enumerable: true,
5052 configurable: true,
5053 get: () => c.value,
5054 set: v => (c.value = v)
5055 });
5056 {
5057 checkDuplicateProperties("Computed" /* OptionTypes.COMPUTED */, key);
5058 }
5059 }
5060 }
5061 if (watchOptions) {
5062 for (const key in watchOptions) {
5063 createWatcher(watchOptions[key], ctx, publicThis, key);
5064 }
5065 }
5066 if (provideOptions) {
5067 const provides = isFunction(provideOptions)
5068 ? provideOptions.call(publicThis)
5069 : provideOptions;
5070 Reflect.ownKeys(provides).forEach(key => {
5071 provide(key, provides[key]);
5072 });
5073 }
5074 if (created) {
5075 callHook$1(created, instance, "c" /* LifecycleHooks.CREATED */);
5076 }
5077 function registerLifecycleHook(register, hook) {
5078 if (isArray(hook)) {
5079 hook.forEach(_hook => register(_hook.bind(publicThis)));
5080 }
5081 else if (hook) {
5082 register(hook.bind(publicThis));
5083 }
5084 }
5085 registerLifecycleHook(onBeforeMount, beforeMount);
5086 registerLifecycleHook(onMounted, mounted);
5087 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
5088 registerLifecycleHook(onUpdated, updated);
5089 registerLifecycleHook(onActivated, activated);
5090 registerLifecycleHook(onDeactivated, deactivated);
5091 registerLifecycleHook(onErrorCaptured, errorCaptured);
5092 registerLifecycleHook(onRenderTracked, renderTracked);
5093 registerLifecycleHook(onRenderTriggered, renderTriggered);
5094 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
5095 registerLifecycleHook(onUnmounted, unmounted);
5096 registerLifecycleHook(onServerPrefetch, serverPrefetch);
5097 if (isArray(expose)) {
5098 if (expose.length) {
5099 const exposed = instance.exposed || (instance.exposed = {});
5100 expose.forEach(key => {
5101 Object.defineProperty(exposed, key, {
5102 get: () => publicThis[key],
5103 set: val => (publicThis[key] = val)
5104 });
5105 });
5106 }
5107 else if (!instance.exposed) {
5108 instance.exposed = {};
5109 }
5110 }
5111 // options that are handled when creating the instance but also need to be
5112 // applied from mixins
5113 if (render && instance.render === NOOP) {
5114 instance.render = render;
5115 }
5116 if (inheritAttrs != null) {
5117 instance.inheritAttrs = inheritAttrs;
5118 }
5119 // asset options.
5120 if (components)
5121 instance.components = components;
5122 if (directives)
5123 instance.directives = directives;
5124}
5125function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
5126 if (isArray(injectOptions)) {
5127 injectOptions = normalizeInject(injectOptions);
5128 }
5129 for (const key in injectOptions) {
5130 const opt = injectOptions[key];
5131 let injected;
5132 if (isObject(opt)) {
5133 if ('default' in opt) {
5134 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
5135 }
5136 else {
5137 injected = inject(opt.from || key);
5138 }
5139 }
5140 else {
5141 injected = inject(opt);
5142 }
5143 if (isRef(injected)) {
5144 // TODO remove the check in 3.3
5145 if (unwrapRef) {
5146 Object.defineProperty(ctx, key, {
5147 enumerable: true,
5148 configurable: true,
5149 get: () => injected.value,
5150 set: v => (injected.value = v)
5151 });
5152 }
5153 else {
5154 {
5155 warn(`injected property "${key}" is a ref and will be auto-unwrapped ` +
5156 `and no longer needs \`.value\` in the next minor release. ` +
5157 `To opt-in to the new behavior now, ` +
5158 `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
5159 `temporary and will not be needed in the future.)`);
5160 }
5161 ctx[key] = injected;
5162 }
5163 }
5164 else {
5165 ctx[key] = injected;
5166 }
5167 {
5168 checkDuplicateProperties("Inject" /* OptionTypes.INJECT */, key);
5169 }
5170 }
5171}
5172function callHook$1(hook, instance, type) {
5173 callWithAsyncErrorHandling(isArray(hook)
5174 ? hook.map(h => h.bind(instance.proxy))
5175 : hook.bind(instance.proxy), instance, type);
5176}
5177function createWatcher(raw, ctx, publicThis, key) {
5178 const getter = key.includes('.')
5179 ? createPathGetter(publicThis, key)
5180 : () => publicThis[key];
5181 if (isString(raw)) {
5182 const handler = ctx[raw];
5183 if (isFunction(handler)) {
5184 watch(getter, handler);
5185 }
5186 else {
5187 warn(`Invalid watch handler specified by key "${raw}"`, handler);
5188 }
5189 }
5190 else if (isFunction(raw)) {
5191 watch(getter, raw.bind(publicThis));
5192 }
5193 else if (isObject(raw)) {
5194 if (isArray(raw)) {
5195 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
5196 }
5197 else {
5198 const handler = isFunction(raw.handler)
5199 ? raw.handler.bind(publicThis)
5200 : ctx[raw.handler];
5201 if (isFunction(handler)) {
5202 watch(getter, handler, raw);
5203 }
5204 else {
5205 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
5206 }
5207 }
5208 }
5209 else {
5210 warn(`Invalid watch option: "${key}"`, raw);
5211 }
5212}
5213/**
5214 * Resolve merged options and cache it on the component.
5215 * This is done only once per-component since the merging does not involve
5216 * instances.
5217 */
5218function resolveMergedOptions(instance) {
5219 const base = instance.type;
5220 const { mixins, extends: extendsOptions } = base;
5221 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
5222 const cached = cache.get(base);
5223 let resolved;
5224 if (cached) {
5225 resolved = cached;
5226 }
5227 else if (!globalMixins.length && !mixins && !extendsOptions) {
5228 {
5229 resolved = base;
5230 }
5231 }
5232 else {
5233 resolved = {};
5234 if (globalMixins.length) {
5235 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
5236 }
5237 mergeOptions(resolved, base, optionMergeStrategies);
5238 }
5239 if (isObject(base)) {
5240 cache.set(base, resolved);
5241 }
5242 return resolved;
5243}
5244function mergeOptions(to, from, strats, asMixin = false) {
5245 const { mixins, extends: extendsOptions } = from;
5246 if (extendsOptions) {
5247 mergeOptions(to, extendsOptions, strats, true);
5248 }
5249 if (mixins) {
5250 mixins.forEach((m) => mergeOptions(to, m, strats, true));
5251 }
5252 for (const key in from) {
5253 if (asMixin && key === 'expose') {
5254 warn(`"expose" option is ignored when declared in mixins or extends. ` +
5255 `It should only be declared in the base component itself.`);
5256 }
5257 else {
5258 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
5259 to[key] = strat ? strat(to[key], from[key]) : from[key];
5260 }
5261 }
5262 return to;
5263}
5264const internalOptionMergeStrats = {
5265 data: mergeDataFn,
5266 props: mergeObjectOptions,
5267 emits: mergeObjectOptions,
5268 // objects
5269 methods: mergeObjectOptions,
5270 computed: mergeObjectOptions,
5271 // lifecycle
5272 beforeCreate: mergeAsArray$1,
5273 created: mergeAsArray$1,
5274 beforeMount: mergeAsArray$1,
5275 mounted: mergeAsArray$1,
5276 beforeUpdate: mergeAsArray$1,
5277 updated: mergeAsArray$1,
5278 beforeDestroy: mergeAsArray$1,
5279 beforeUnmount: mergeAsArray$1,
5280 destroyed: mergeAsArray$1,
5281 unmounted: mergeAsArray$1,
5282 activated: mergeAsArray$1,
5283 deactivated: mergeAsArray$1,
5284 errorCaptured: mergeAsArray$1,
5285 serverPrefetch: mergeAsArray$1,
5286 // assets
5287 components: mergeObjectOptions,
5288 directives: mergeObjectOptions,
5289 // watch
5290 watch: mergeWatchOptions,
5291 // provide / inject
5292 provide: mergeDataFn,
5293 inject: mergeInject
5294};
5295function mergeDataFn(to, from) {
5296 if (!from) {
5297 return to;
5298 }
5299 if (!to) {
5300 return from;
5301 }
5302 return function mergedDataFn() {
5303 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
5304 };
5305}
5306function mergeInject(to, from) {
5307 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
5308}
5309function normalizeInject(raw) {
5310 if (isArray(raw)) {
5311 const res = {};
5312 for (let i = 0; i < raw.length; i++) {
5313 res[raw[i]] = raw[i];
5314 }
5315 return res;
5316 }
5317 return raw;
5318}
5319function mergeAsArray$1(to, from) {
5320 return to ? [...new Set([].concat(to, from))] : from;
5321}
5322function mergeObjectOptions(to, from) {
5323 return to ? extend(extend(Object.create(null), to), from) : from;
5324}
5325function mergeWatchOptions(to, from) {
5326 if (!to)
5327 return from;
5328 if (!from)
5329 return to;
5330 const merged = extend(Object.create(null), to);
5331 for (const key in from) {
5332 merged[key] = mergeAsArray$1(to[key], from[key]);
5333 }
5334 return merged;
5335}
5336
5337function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
5338isSSR = false) {
5339 const props = {};
5340 const attrs = {};
5341 def(attrs, InternalObjectKey, 1);
5342 instance.propsDefaults = Object.create(null);
5343 setFullProps(instance, rawProps, props, attrs);
5344 // ensure all declared prop keys are present
5345 for (const key in instance.propsOptions[0]) {
5346 if (!(key in props)) {
5347 props[key] = undefined;
5348 }
5349 }
5350 // validation
5351 {
5352 validateProps(rawProps || {}, props, instance);
5353 }
5354 if (isStateful) {
5355 // stateful
5356 instance.props = isSSR ? props : shallowReactive(props);
5357 }
5358 else {
5359 if (!instance.type.props) {
5360 // functional w/ optional props, props === attrs
5361 instance.props = attrs;
5362 }
5363 else {
5364 // functional w/ declared props
5365 instance.props = props;
5366 }
5367 }
5368 instance.attrs = attrs;
5369}
5370function isInHmrContext(instance) {
5371 while (instance) {
5372 if (instance.type.__hmrId)
5373 return true;
5374 instance = instance.parent;
5375 }
5376}
5377function updateProps(instance, rawProps, rawPrevProps, optimized) {
5378 const { props, attrs, vnode: { patchFlag } } = instance;
5379 const rawCurrentProps = toRaw(props);
5380 const [options] = instance.propsOptions;
5381 let hasAttrsChanged = false;
5382 if (
5383 // always force full diff in dev
5384 // - #1942 if hmr is enabled with sfc component
5385 // - vite#872 non-sfc component used by sfc component
5386 !(isInHmrContext(instance)) &&
5387 (optimized || patchFlag > 0) &&
5388 !(patchFlag & 16 /* PatchFlags.FULL_PROPS */)) {
5389 if (patchFlag & 8 /* PatchFlags.PROPS */) {
5390 // Compiler-generated props & no keys change, just set the updated
5391 // the props.
5392 const propsToUpdate = instance.vnode.dynamicProps;
5393 for (let i = 0; i < propsToUpdate.length; i++) {
5394 let key = propsToUpdate[i];
5395 // skip if the prop key is a declared emit event listener
5396 if (isEmitListener(instance.emitsOptions, key)) {
5397 continue;
5398 }
5399 // PROPS flag guarantees rawProps to be non-null
5400 const value = rawProps[key];
5401 if (options) {
5402 // attr / props separation was done on init and will be consistent
5403 // in this code path, so just check if attrs have it.
5404 if (hasOwn(attrs, key)) {
5405 if (value !== attrs[key]) {
5406 attrs[key] = value;
5407 hasAttrsChanged = true;
5408 }
5409 }
5410 else {
5411 const camelizedKey = camelize(key);
5412 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
5413 }
5414 }
5415 else {
5416 if (value !== attrs[key]) {
5417 attrs[key] = value;
5418 hasAttrsChanged = true;
5419 }
5420 }
5421 }
5422 }
5423 }
5424 else {
5425 // full props update.
5426 if (setFullProps(instance, rawProps, props, attrs)) {
5427 hasAttrsChanged = true;
5428 }
5429 // in case of dynamic props, check if we need to delete keys from
5430 // the props object
5431 let kebabKey;
5432 for (const key in rawCurrentProps) {
5433 if (!rawProps ||
5434 // for camelCase
5435 (!hasOwn(rawProps, key) &&
5436 // it's possible the original props was passed in as kebab-case
5437 // and converted to camelCase (#955)
5438 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
5439 if (options) {
5440 if (rawPrevProps &&
5441 // for camelCase
5442 (rawPrevProps[key] !== undefined ||
5443 // for kebab-case
5444 rawPrevProps[kebabKey] !== undefined)) {
5445 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
5446 }
5447 }
5448 else {
5449 delete props[key];
5450 }
5451 }
5452 }
5453 // in the case of functional component w/o props declaration, props and
5454 // attrs point to the same object so it should already have been updated.
5455 if (attrs !== rawCurrentProps) {
5456 for (const key in attrs) {
5457 if (!rawProps ||
5458 (!hasOwn(rawProps, key) &&
5459 (!false ))) {
5460 delete attrs[key];
5461 hasAttrsChanged = true;
5462 }
5463 }
5464 }
5465 }
5466 // trigger updates for $attrs in case it's used in component slots
5467 if (hasAttrsChanged) {
5468 trigger(instance, "set" /* TriggerOpTypes.SET */, '$attrs');
5469 }
5470 {
5471 validateProps(rawProps || {}, props, instance);
5472 }
5473}
5474function setFullProps(instance, rawProps, props, attrs) {
5475 const [options, needCastKeys] = instance.propsOptions;
5476 let hasAttrsChanged = false;
5477 let rawCastValues;
5478 if (rawProps) {
5479 for (let key in rawProps) {
5480 // key, ref are reserved and never passed down
5481 if (isReservedProp(key)) {
5482 continue;
5483 }
5484 const value = rawProps[key];
5485 // prop option names are camelized during normalization, so to support
5486 // kebab -> camel conversion here we need to camelize the key.
5487 let camelKey;
5488 if (options && hasOwn(options, (camelKey = camelize(key)))) {
5489 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
5490 props[camelKey] = value;
5491 }
5492 else {
5493 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
5494 }
5495 }
5496 else if (!isEmitListener(instance.emitsOptions, key)) {
5497 if (!(key in attrs) || value !== attrs[key]) {
5498 attrs[key] = value;
5499 hasAttrsChanged = true;
5500 }
5501 }
5502 }
5503 }
5504 if (needCastKeys) {
5505 const rawCurrentProps = toRaw(props);
5506 const castValues = rawCastValues || EMPTY_OBJ;
5507 for (let i = 0; i < needCastKeys.length; i++) {
5508 const key = needCastKeys[i];
5509 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
5510 }
5511 }
5512 return hasAttrsChanged;
5513}
5514function resolvePropValue(options, props, key, value, instance, isAbsent) {
5515 const opt = options[key];
5516 if (opt != null) {
5517 const hasDefault = hasOwn(opt, 'default');
5518 // default values
5519 if (hasDefault && value === undefined) {
5520 const defaultValue = opt.default;
5521 if (opt.type !== Function && isFunction(defaultValue)) {
5522 const { propsDefaults } = instance;
5523 if (key in propsDefaults) {
5524 value = propsDefaults[key];
5525 }
5526 else {
5527 setCurrentInstance(instance);
5528 value = propsDefaults[key] = defaultValue.call(null, props);
5529 unsetCurrentInstance();
5530 }
5531 }
5532 else {
5533 value = defaultValue;
5534 }
5535 }
5536 // boolean casting
5537 if (opt[0 /* BooleanFlags.shouldCast */]) {
5538 if (isAbsent && !hasDefault) {
5539 value = false;
5540 }
5541 else if (opt[1 /* BooleanFlags.shouldCastTrue */] &&
5542 (value === '' || value === hyphenate(key))) {
5543 value = true;
5544 }
5545 }
5546 }
5547 return value;
5548}
5549function normalizePropsOptions(comp, appContext, asMixin = false) {
5550 const cache = appContext.propsCache;
5551 const cached = cache.get(comp);
5552 if (cached) {
5553 return cached;
5554 }
5555 const raw = comp.props;
5556 const normalized = {};
5557 const needCastKeys = [];
5558 // apply mixin/extends props
5559 let hasExtends = false;
5560 if (!isFunction(comp)) {
5561 const extendProps = (raw) => {
5562 hasExtends = true;
5563 const [props, keys] = normalizePropsOptions(raw, appContext, true);
5564 extend(normalized, props);
5565 if (keys)
5566 needCastKeys.push(...keys);
5567 };
5568 if (!asMixin && appContext.mixins.length) {
5569 appContext.mixins.forEach(extendProps);
5570 }
5571 if (comp.extends) {
5572 extendProps(comp.extends);
5573 }
5574 if (comp.mixins) {
5575 comp.mixins.forEach(extendProps);
5576 }
5577 }
5578 if (!raw && !hasExtends) {
5579 if (isObject(comp)) {
5580 cache.set(comp, EMPTY_ARR);
5581 }
5582 return EMPTY_ARR;
5583 }
5584 if (isArray(raw)) {
5585 for (let i = 0; i < raw.length; i++) {
5586 if (!isString(raw[i])) {
5587 warn(`props must be strings when using array syntax.`, raw[i]);
5588 }
5589 const normalizedKey = camelize(raw[i]);
5590 if (validatePropName(normalizedKey)) {
5591 normalized[normalizedKey] = EMPTY_OBJ;
5592 }
5593 }
5594 }
5595 else if (raw) {
5596 if (!isObject(raw)) {
5597 warn(`invalid props options`, raw);
5598 }
5599 for (const key in raw) {
5600 const normalizedKey = camelize(key);
5601 if (validatePropName(normalizedKey)) {
5602 const opt = raw[key];
5603 const prop = (normalized[normalizedKey] =
5604 isArray(opt) || isFunction(opt) ? { type: opt } : Object.assign({}, opt));
5605 if (prop) {
5606 const booleanIndex = getTypeIndex(Boolean, prop.type);
5607 const stringIndex = getTypeIndex(String, prop.type);
5608 prop[0 /* BooleanFlags.shouldCast */] = booleanIndex > -1;
5609 prop[1 /* BooleanFlags.shouldCastTrue */] =
5610 stringIndex < 0 || booleanIndex < stringIndex;
5611 // if the prop needs boolean casting or default value
5612 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
5613 needCastKeys.push(normalizedKey);
5614 }
5615 }
5616 }
5617 }
5618 }
5619 const res = [normalized, needCastKeys];
5620 if (isObject(comp)) {
5621 cache.set(comp, res);
5622 }
5623 return res;
5624}
5625function validatePropName(key) {
5626 if (key[0] !== '$') {
5627 return true;
5628 }
5629 else {
5630 warn(`Invalid prop name: "${key}" is a reserved property.`);
5631 }
5632 return false;
5633}
5634// use function string name to check type constructors
5635// so that it works across vms / iframes.
5636function getType(ctor) {
5637 const match = ctor && ctor.toString().match(/^\s*(function|class) (\w+)/);
5638 return match ? match[2] : ctor === null ? 'null' : '';
5639}
5640function isSameType(a, b) {
5641 return getType(a) === getType(b);
5642}
5643function getTypeIndex(type, expectedTypes) {
5644 if (isArray(expectedTypes)) {
5645 return expectedTypes.findIndex(t => isSameType(t, type));
5646 }
5647 else if (isFunction(expectedTypes)) {
5648 return isSameType(expectedTypes, type) ? 0 : -1;
5649 }
5650 return -1;
5651}
5652/**
5653 * dev only
5654 */
5655function validateProps(rawProps, props, instance) {
5656 const resolvedValues = toRaw(props);
5657 const options = instance.propsOptions[0];
5658 for (const key in options) {
5659 let opt = options[key];
5660 if (opt == null)
5661 continue;
5662 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
5663 }
5664}
5665/**
5666 * dev only
5667 */
5668function validateProp(name, value, prop, isAbsent) {
5669 const { type, required, validator } = prop;
5670 // required!
5671 if (required && isAbsent) {
5672 warn('Missing required prop: "' + name + '"');
5673 return;
5674 }
5675 // missing but optional
5676 if (value == null && !prop.required) {
5677 return;
5678 }
5679 // type check
5680 if (type != null && type !== true) {
5681 let isValid = false;
5682 const types = isArray(type) ? type : [type];
5683 const expectedTypes = [];
5684 // value is valid as long as one of the specified types match
5685 for (let i = 0; i < types.length && !isValid; i++) {
5686 const { valid, expectedType } = assertType(value, types[i]);
5687 expectedTypes.push(expectedType || '');
5688 isValid = valid;
5689 }
5690 if (!isValid) {
5691 warn(getInvalidTypeMessage(name, value, expectedTypes));
5692 return;
5693 }
5694 }
5695 // custom validator
5696 if (validator && !validator(value)) {
5697 warn('Invalid prop: custom validator check failed for prop "' + name + '".');
5698 }
5699}
5700const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
5701/**
5702 * dev only
5703 */
5704function assertType(value, type) {
5705 let valid;
5706 const expectedType = getType(type);
5707 if (isSimpleType(expectedType)) {
5708 const t = typeof value;
5709 valid = t === expectedType.toLowerCase();
5710 // for primitive wrapper objects
5711 if (!valid && t === 'object') {
5712 valid = value instanceof type;
5713 }
5714 }
5715 else if (expectedType === 'Object') {
5716 valid = isObject(value);
5717 }
5718 else if (expectedType === 'Array') {
5719 valid = isArray(value);
5720 }
5721 else if (expectedType === 'null') {
5722 valid = value === null;
5723 }
5724 else {
5725 valid = value instanceof type;
5726 }
5727 return {
5728 valid,
5729 expectedType
5730 };
5731}
5732/**
5733 * dev only
5734 */
5735function getInvalidTypeMessage(name, value, expectedTypes) {
5736 let message = `Invalid prop: type check failed for prop "${name}".` +
5737 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
5738 const expectedType = expectedTypes[0];
5739 const receivedType = toRawType(value);
5740 const expectedValue = styleValue(value, expectedType);
5741 const receivedValue = styleValue(value, receivedType);
5742 // check if we need to specify expected value
5743 if (expectedTypes.length === 1 &&
5744 isExplicable(expectedType) &&
5745 !isBoolean(expectedType, receivedType)) {
5746 message += ` with value ${expectedValue}`;
5747 }
5748 message += `, got ${receivedType} `;
5749 // check if we need to specify received value
5750 if (isExplicable(receivedType)) {
5751 message += `with value ${receivedValue}.`;
5752 }
5753 return message;
5754}
5755/**
5756 * dev only
5757 */
5758function styleValue(value, type) {
5759 if (type === 'String') {
5760 return `"${value}"`;
5761 }
5762 else if (type === 'Number') {
5763 return `${Number(value)}`;
5764 }
5765 else {
5766 return `${value}`;
5767 }
5768}
5769/**
5770 * dev only
5771 */
5772function isExplicable(type) {
5773 const explicitTypes = ['string', 'number', 'boolean'];
5774 return explicitTypes.some(elem => type.toLowerCase() === elem);
5775}
5776/**
5777 * dev only
5778 */
5779function isBoolean(...args) {
5780 return args.some(elem => elem.toLowerCase() === 'boolean');
5781}
5782
5783const isInternalKey = (key) => key[0] === '_' || key === '$stable';
5784const normalizeSlotValue = (value) => isArray(value)
5785 ? value.map(normalizeVNode)
5786 : [normalizeVNode(value)];
5787const normalizeSlot = (key, rawSlot, ctx) => {
5788 if (rawSlot._n) {
5789 // already normalized - #5353
5790 return rawSlot;
5791 }
5792 const normalized = withCtx((...args) => {
5793 if (true && currentInstance) {
5794 warn(`Slot "${key}" invoked outside of the render function: ` +
5795 `this will not track dependencies used in the slot. ` +
5796 `Invoke the slot function inside the render function instead.`);
5797 }
5798 return normalizeSlotValue(rawSlot(...args));
5799 }, ctx);
5800 normalized._c = false;
5801 return normalized;
5802};
5803const normalizeObjectSlots = (rawSlots, slots, instance) => {
5804 const ctx = rawSlots._ctx;
5805 for (const key in rawSlots) {
5806 if (isInternalKey(key))
5807 continue;
5808 const value = rawSlots[key];
5809 if (isFunction(value)) {
5810 slots[key] = normalizeSlot(key, value, ctx);
5811 }
5812 else if (value != null) {
5813 {
5814 warn(`Non-function value encountered for slot "${key}". ` +
5815 `Prefer function slots for better performance.`);
5816 }
5817 const normalized = normalizeSlotValue(value);
5818 slots[key] = () => normalized;
5819 }
5820 }
5821};
5822const normalizeVNodeSlots = (instance, children) => {
5823 if (!isKeepAlive(instance.vnode) &&
5824 !(false )) {
5825 warn(`Non-function value encountered for default slot. ` +
5826 `Prefer function slots for better performance.`);
5827 }
5828 const normalized = normalizeSlotValue(children);
5829 instance.slots.default = () => normalized;
5830};
5831const initSlots = (instance, children) => {
5832 if (instance.vnode.shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */) {
5833 const type = children._;
5834 if (type) {
5835 // users can get the shallow readonly version of the slots object through `this.$slots`,
5836 // we should avoid the proxy object polluting the slots of the internal instance
5837 instance.slots = toRaw(children);
5838 // make compiler marker non-enumerable
5839 def(children, '_', type);
5840 }
5841 else {
5842 normalizeObjectSlots(children, (instance.slots = {}));
5843 }
5844 }
5845 else {
5846 instance.slots = {};
5847 if (children) {
5848 normalizeVNodeSlots(instance, children);
5849 }
5850 }
5851 def(instance.slots, InternalObjectKey, 1);
5852};
5853const updateSlots = (instance, children, optimized) => {
5854 const { vnode, slots } = instance;
5855 let needDeletionCheck = true;
5856 let deletionComparisonTarget = EMPTY_OBJ;
5857 if (vnode.shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */) {
5858 const type = children._;
5859 if (type) {
5860 // compiled slots.
5861 if (isHmrUpdating) {
5862 // Parent was HMR updated so slot content may have changed.
5863 // force update slots and mark instance for hmr as well
5864 extend(slots, children);
5865 }
5866 else if (optimized && type === 1 /* SlotFlags.STABLE */) {
5867 // compiled AND stable.
5868 // no need to update, and skip stale slots removal.
5869 needDeletionCheck = false;
5870 }
5871 else {
5872 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
5873 // normalization.
5874 extend(slots, children);
5875 // #2893
5876 // when rendering the optimized slots by manually written render function,
5877 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
5878 // i.e. let the `renderSlot` create the bailed Fragment
5879 if (!optimized && type === 1 /* SlotFlags.STABLE */) {
5880 delete slots._;
5881 }
5882 }
5883 }
5884 else {
5885 needDeletionCheck = !children.$stable;
5886 normalizeObjectSlots(children, slots);
5887 }
5888 deletionComparisonTarget = children;
5889 }
5890 else if (children) {
5891 // non slot object children (direct value) passed to a component
5892 normalizeVNodeSlots(instance, children);
5893 deletionComparisonTarget = { default: 1 };
5894 }
5895 // delete stale slots
5896 if (needDeletionCheck) {
5897 for (const key in slots) {
5898 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
5899 delete slots[key];
5900 }
5901 }
5902 }
5903};
5904
5905function createAppContext() {
5906 return {
5907 app: null,
5908 config: {
5909 isNativeTag: NO,
5910 performance: false,
5911 globalProperties: {},
5912 optionMergeStrategies: {},
5913 errorHandler: undefined,
5914 warnHandler: undefined,
5915 compilerOptions: {}
5916 },
5917 mixins: [],
5918 components: {},
5919 directives: {},
5920 provides: Object.create(null),
5921 optionsCache: new WeakMap(),
5922 propsCache: new WeakMap(),
5923 emitsCache: new WeakMap()
5924 };
5925}
5926let uid$1 = 0;
5927function createAppAPI(render, hydrate) {
5928 return function createApp(rootComponent, rootProps = null) {
5929 if (!isFunction(rootComponent)) {
5930 rootComponent = Object.assign({}, rootComponent);
5931 }
5932 if (rootProps != null && !isObject(rootProps)) {
5933 warn(`root props passed to app.mount() must be an object.`);
5934 rootProps = null;
5935 }
5936 const context = createAppContext();
5937 const installedPlugins = new Set();
5938 let isMounted = false;
5939 const app = (context.app = {
5940 _uid: uid$1++,
5941 _component: rootComponent,
5942 _props: rootProps,
5943 _container: null,
5944 _context: context,
5945 _instance: null,
5946 version,
5947 get config() {
5948 return context.config;
5949 },
5950 set config(v) {
5951 {
5952 warn(`app.config cannot be replaced. Modify individual options instead.`);
5953 }
5954 },
5955 use(plugin, ...options) {
5956 if (installedPlugins.has(plugin)) {
5957 warn(`Plugin has already been applied to target app.`);
5958 }
5959 else if (plugin && isFunction(plugin.install)) {
5960 installedPlugins.add(plugin);
5961 plugin.install(app, ...options);
5962 }
5963 else if (isFunction(plugin)) {
5964 installedPlugins.add(plugin);
5965 plugin(app, ...options);
5966 }
5967 else {
5968 warn(`A plugin must either be a function or an object with an "install" ` +
5969 `function.`);
5970 }
5971 return app;
5972 },
5973 mixin(mixin) {
5974 {
5975 if (!context.mixins.includes(mixin)) {
5976 context.mixins.push(mixin);
5977 }
5978 else {
5979 warn('Mixin has already been applied to target app' +
5980 (mixin.name ? `: ${mixin.name}` : ''));
5981 }
5982 }
5983 return app;
5984 },
5985 component(name, component) {
5986 {
5987 validateComponentName(name, context.config);
5988 }
5989 if (!component) {
5990 return context.components[name];
5991 }
5992 if (context.components[name]) {
5993 warn(`Component "${name}" has already been registered in target app.`);
5994 }
5995 context.components[name] = component;
5996 return app;
5997 },
5998 directive(name, directive) {
5999 {
6000 validateDirectiveName(name);
6001 }
6002 if (!directive) {
6003 return context.directives[name];
6004 }
6005 if (context.directives[name]) {
6006 warn(`Directive "${name}" has already been registered in target app.`);
6007 }
6008 context.directives[name] = directive;
6009 return app;
6010 },
6011 mount(rootContainer, isHydrate, isSVG) {
6012 if (!isMounted) {
6013 // #5571
6014 if (rootContainer.__vue_app__) {
6015 warn(`There is already an app instance mounted on the host container.\n` +
6016 ` If you want to mount another app on the same host container,` +
6017 ` you need to unmount the previous app by calling \`app.unmount()\` first.`);
6018 }
6019 const vnode = createVNode(rootComponent, rootProps);
6020 // store app context on the root VNode.
6021 // this will be set on the root instance on initial mount.
6022 vnode.appContext = context;
6023 // HMR root reload
6024 {
6025 context.reload = () => {
6026 render(cloneVNode(vnode), rootContainer, isSVG);
6027 };
6028 }
6029 if (isHydrate && hydrate) {
6030 hydrate(vnode, rootContainer);
6031 }
6032 else {
6033 render(vnode, rootContainer, isSVG);
6034 }
6035 isMounted = true;
6036 app._container = rootContainer;
6037 rootContainer.__vue_app__ = app;
6038 {
6039 app._instance = vnode.component;
6040 devtoolsInitApp(app, version);
6041 }
6042 return getExposeProxy(vnode.component) || vnode.component.proxy;
6043 }
6044 else {
6045 warn(`App has already been mounted.\n` +
6046 `If you want to remount the same app, move your app creation logic ` +
6047 `into a factory function and create fresh app instances for each ` +
6048 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
6049 }
6050 },
6051 unmount() {
6052 if (isMounted) {
6053 render(null, app._container);
6054 {
6055 app._instance = null;
6056 devtoolsUnmountApp(app);
6057 }
6058 delete app._container.__vue_app__;
6059 }
6060 else {
6061 warn(`Cannot unmount an app that is not mounted.`);
6062 }
6063 },
6064 provide(key, value) {
6065 if (key in context.provides) {
6066 warn(`App already provides property with key "${String(key)}". ` +
6067 `It will be overwritten with the new value.`);
6068 }
6069 context.provides[key] = value;
6070 return app;
6071 }
6072 });
6073 return app;
6074 };
6075}
6076
6077/**
6078 * Function for handling a template ref
6079 */
6080function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6081 if (isArray(rawRef)) {
6082 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6083 return;
6084 }
6085 if (isAsyncWrapper(vnode) && !isUnmount) {
6086 // when mounting async components, nothing needs to be done,
6087 // because the template ref is forwarded to inner component
6088 return;
6089 }
6090 const refValue = vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */
6091 ? getExposeProxy(vnode.component) || vnode.component.proxy
6092 : vnode.el;
6093 const value = isUnmount ? null : refValue;
6094 const { i: owner, r: ref } = rawRef;
6095 if (!owner) {
6096 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
6097 `A vnode with ref must be created inside the render function.`);
6098 return;
6099 }
6100 const oldRef = oldRawRef && oldRawRef.r;
6101 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6102 const setupState = owner.setupState;
6103 // dynamic ref changed. unset old ref
6104 if (oldRef != null && oldRef !== ref) {
6105 if (isString(oldRef)) {
6106 refs[oldRef] = null;
6107 if (hasOwn(setupState, oldRef)) {
6108 setupState[oldRef] = null;
6109 }
6110 }
6111 else if (isRef(oldRef)) {
6112 oldRef.value = null;
6113 }
6114 }
6115 if (isFunction(ref)) {
6116 callWithErrorHandling(ref, owner, 12 /* ErrorCodes.FUNCTION_REF */, [value, refs]);
6117 }
6118 else {
6119 const _isString = isString(ref);
6120 const _isRef = isRef(ref);
6121 if (_isString || _isRef) {
6122 const doSet = () => {
6123 if (rawRef.f) {
6124 const existing = _isString
6125 ? hasOwn(setupState, ref)
6126 ? setupState[ref]
6127 : refs[ref]
6128 : ref.value;
6129 if (isUnmount) {
6130 isArray(existing) && remove(existing, refValue);
6131 }
6132 else {
6133 if (!isArray(existing)) {
6134 if (_isString) {
6135 refs[ref] = [refValue];
6136 if (hasOwn(setupState, ref)) {
6137 setupState[ref] = refs[ref];
6138 }
6139 }
6140 else {
6141 ref.value = [refValue];
6142 if (rawRef.k)
6143 refs[rawRef.k] = ref.value;
6144 }
6145 }
6146 else if (!existing.includes(refValue)) {
6147 existing.push(refValue);
6148 }
6149 }
6150 }
6151 else if (_isString) {
6152 refs[ref] = value;
6153 if (hasOwn(setupState, ref)) {
6154 setupState[ref] = value;
6155 }
6156 }
6157 else if (_isRef) {
6158 ref.value = value;
6159 if (rawRef.k)
6160 refs[rawRef.k] = value;
6161 }
6162 else {
6163 warn('Invalid template ref type:', ref, `(${typeof ref})`);
6164 }
6165 };
6166 if (value) {
6167 doSet.id = -1;
6168 queuePostRenderEffect(doSet, parentSuspense);
6169 }
6170 else {
6171 doSet();
6172 }
6173 }
6174 else {
6175 warn('Invalid template ref type:', ref, `(${typeof ref})`);
6176 }
6177 }
6178}
6179
6180let hasMismatch = false;
6181const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
6182const isComment = (node) => node.nodeType === 8 /* DOMNodeTypes.COMMENT */;
6183// Note: hydration is DOM-specific
6184// But we have to place it in core due to tight coupling with core - splitting
6185// it out creates a ton of unnecessary complexity.
6186// Hydration also depends on some renderer internal logic which needs to be
6187// passed in via arguments.
6188function createHydrationFunctions(rendererInternals) {
6189 const { mt: mountComponent, p: patch, o: { patchProp, createText, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
6190 const hydrate = (vnode, container) => {
6191 if (!container.hasChildNodes()) {
6192 warn(`Attempting to hydrate existing markup but container is empty. ` +
6193 `Performing full mount instead.`);
6194 patch(null, vnode, container);
6195 flushPostFlushCbs();
6196 container._vnode = vnode;
6197 return;
6198 }
6199 hasMismatch = false;
6200 hydrateNode(container.firstChild, vnode, null, null, null);
6201 flushPostFlushCbs();
6202 container._vnode = vnode;
6203 if (hasMismatch && !false) {
6204 // this error should show up in production
6205 console.error(`Hydration completed but contains mismatches.`);
6206 }
6207 };
6208 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
6209 const isFragmentStart = isComment(node) && node.data === '[';
6210 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
6211 const { type, ref, shapeFlag, patchFlag } = vnode;
6212 let domType = node.nodeType;
6213 vnode.el = node;
6214 if (patchFlag === -2 /* PatchFlags.BAIL */) {
6215 optimized = false;
6216 vnode.dynamicChildren = null;
6217 }
6218 let nextNode = null;
6219 switch (type) {
6220 case Text:
6221 if (domType !== 3 /* DOMNodeTypes.TEXT */) {
6222 // #5728 empty text node inside a slot can cause hydration failure
6223 // because the server rendered HTML won't contain a text node
6224 if (vnode.children === '') {
6225 insert((vnode.el = createText('')), parentNode(node), node);
6226 nextNode = node;
6227 }
6228 else {
6229 nextNode = onMismatch();
6230 }
6231 }
6232 else {
6233 if (node.data !== vnode.children) {
6234 hasMismatch = true;
6235 warn(`Hydration text mismatch:` +
6236 `\n- Client: ${JSON.stringify(node.data)}` +
6237 `\n- Server: ${JSON.stringify(vnode.children)}`);
6238 node.data = vnode.children;
6239 }
6240 nextNode = nextSibling(node);
6241 }
6242 break;
6243 case Comment:
6244 if (domType !== 8 /* DOMNodeTypes.COMMENT */ || isFragmentStart) {
6245 nextNode = onMismatch();
6246 }
6247 else {
6248 nextNode = nextSibling(node);
6249 }
6250 break;
6251 case Static:
6252 if (isFragmentStart) {
6253 // entire template is static but SSRed as a fragment
6254 node = nextSibling(node);
6255 domType = node.nodeType;
6256 }
6257 if (domType === 1 /* DOMNodeTypes.ELEMENT */ || domType === 3 /* DOMNodeTypes.TEXT */) {
6258 // determine anchor, adopt content
6259 nextNode = node;
6260 // if the static vnode has its content stripped during build,
6261 // adopt it from the server-rendered HTML.
6262 const needToAdoptContent = !vnode.children.length;
6263 for (let i = 0; i < vnode.staticCount; i++) {
6264 if (needToAdoptContent)
6265 vnode.children +=
6266 nextNode.nodeType === 1 /* DOMNodeTypes.ELEMENT */
6267 ? nextNode.outerHTML
6268 : nextNode.data;
6269 if (i === vnode.staticCount - 1) {
6270 vnode.anchor = nextNode;
6271 }
6272 nextNode = nextSibling(nextNode);
6273 }
6274 return isFragmentStart ? nextSibling(nextNode) : nextNode;
6275 }
6276 else {
6277 onMismatch();
6278 }
6279 break;
6280 case Fragment:
6281 if (!isFragmentStart) {
6282 nextNode = onMismatch();
6283 }
6284 else {
6285 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6286 }
6287 break;
6288 default:
6289 if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
6290 if (domType !== 1 /* DOMNodeTypes.ELEMENT */ ||
6291 vnode.type.toLowerCase() !==
6292 node.tagName.toLowerCase()) {
6293 nextNode = onMismatch();
6294 }
6295 else {
6296 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6297 }
6298 }
6299 else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
6300 // when setting up the render effect, if the initial vnode already
6301 // has .el set, the component will perform hydration instead of mount
6302 // on its sub-tree.
6303 vnode.slotScopeIds = slotScopeIds;
6304 const container = parentNode(node);
6305 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
6306 // component may be async, so in the case of fragments we cannot rely
6307 // on component's rendered output to determine the end of the fragment
6308 // instead, we do a lookahead to find the end anchor node.
6309 nextNode = isFragmentStart
6310 ? locateClosingAsyncAnchor(node)
6311 : nextSibling(node);
6312 // #4293 teleport as component root
6313 if (nextNode &&
6314 isComment(nextNode) &&
6315 nextNode.data === 'teleport end') {
6316 nextNode = nextSibling(nextNode);
6317 }
6318 // #3787
6319 // if component is async, it may get moved / unmounted before its
6320 // inner component is loaded, so we need to give it a placeholder
6321 // vnode that matches its adopted DOM.
6322 if (isAsyncWrapper(vnode)) {
6323 let subTree;
6324 if (isFragmentStart) {
6325 subTree = createVNode(Fragment);
6326 subTree.anchor = nextNode
6327 ? nextNode.previousSibling
6328 : container.lastChild;
6329 }
6330 else {
6331 subTree =
6332 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
6333 }
6334 subTree.el = node;
6335 vnode.component.subTree = subTree;
6336 }
6337 }
6338 else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
6339 if (domType !== 8 /* DOMNodeTypes.COMMENT */) {
6340 nextNode = onMismatch();
6341 }
6342 else {
6343 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
6344 }
6345 }
6346 else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
6347 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
6348 }
6349 else {
6350 warn('Invalid HostVNode type:', type, `(${typeof type})`);
6351 }
6352 }
6353 if (ref != null) {
6354 setRef(ref, null, parentSuspense, vnode);
6355 }
6356 return nextNode;
6357 };
6358 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6359 optimized = optimized || !!vnode.dynamicChildren;
6360 const { type, props, patchFlag, shapeFlag, dirs } = vnode;
6361 // #4006 for form elements with non-string v-model value bindings
6362 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
6363 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
6364 // skip props & children if this is hoisted static nodes
6365 // #5405 in dev, always hydrate children for HMR
6366 {
6367 if (dirs) {
6368 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6369 }
6370 // props
6371 if (props) {
6372 if (forcePatchValue ||
6373 !optimized ||
6374 patchFlag & (16 /* PatchFlags.FULL_PROPS */ | 32 /* PatchFlags.HYDRATE_EVENTS */)) {
6375 for (const key in props) {
6376 if ((forcePatchValue && key.endsWith('value')) ||
6377 (isOn(key) && !isReservedProp(key))) {
6378 patchProp(el, key, null, props[key], false, undefined, parentComponent);
6379 }
6380 }
6381 }
6382 else if (props.onClick) {
6383 // Fast path for click listeners (which is most often) to avoid
6384 // iterating through props.
6385 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent);
6386 }
6387 }
6388 // vnode / directive hooks
6389 let vnodeHooks;
6390 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
6391 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6392 }
6393 if (dirs) {
6394 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6395 }
6396 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
6397 queueEffectWithSuspense(() => {
6398 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6399 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6400 }, parentSuspense);
6401 }
6402 // children
6403 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */ &&
6404 // skip if element has innerHTML / textContent
6405 !(props && (props.innerHTML || props.textContent))) {
6406 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
6407 let hasWarned = false;
6408 while (next) {
6409 hasMismatch = true;
6410 if (!hasWarned) {
6411 warn(`Hydration children mismatch in <${vnode.type}>: ` +
6412 `server rendered element contains more child nodes than client vdom.`);
6413 hasWarned = true;
6414 }
6415 // The SSRed DOM contains more nodes than it should. Remove them.
6416 const cur = next;
6417 next = next.nextSibling;
6418 remove(cur);
6419 }
6420 }
6421 else if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
6422 if (el.textContent !== vnode.children) {
6423 hasMismatch = true;
6424 warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
6425 `- Client: ${el.textContent}\n` +
6426 `- Server: ${vnode.children}`);
6427 el.textContent = vnode.children;
6428 }
6429 }
6430 }
6431 return el.nextSibling;
6432 };
6433 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6434 optimized = optimized || !!parentVNode.dynamicChildren;
6435 const children = parentVNode.children;
6436 const l = children.length;
6437 let hasWarned = false;
6438 for (let i = 0; i < l; i++) {
6439 const vnode = optimized
6440 ? children[i]
6441 : (children[i] = normalizeVNode(children[i]));
6442 if (node) {
6443 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6444 }
6445 else if (vnode.type === Text && !vnode.children) {
6446 continue;
6447 }
6448 else {
6449 hasMismatch = true;
6450 if (!hasWarned) {
6451 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
6452 `server rendered element contains fewer child nodes than client vdom.`);
6453 hasWarned = true;
6454 }
6455 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
6456 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6457 }
6458 }
6459 return node;
6460 };
6461 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6462 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
6463 if (fragmentSlotScopeIds) {
6464 slotScopeIds = slotScopeIds
6465 ? slotScopeIds.concat(fragmentSlotScopeIds)
6466 : fragmentSlotScopeIds;
6467 }
6468 const container = parentNode(node);
6469 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
6470 if (next && isComment(next) && next.data === ']') {
6471 return nextSibling((vnode.anchor = next));
6472 }
6473 else {
6474 // fragment didn't hydrate successfully, since we didn't get a end anchor
6475 // back. This should have led to node/children mismatch warnings.
6476 hasMismatch = true;
6477 // since the anchor is missing, we need to create one and insert it
6478 insert((vnode.anchor = createComment(`]`)), container, next);
6479 return next;
6480 }
6481 };
6482 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
6483 hasMismatch = true;
6484 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* DOMNodeTypes.TEXT */
6485 ? `(text)`
6486 : isComment(node) && node.data === '['
6487 ? `(start of fragment)`
6488 : ``);
6489 vnode.el = null;
6490 if (isFragment) {
6491 // remove excessive fragment nodes
6492 const end = locateClosingAsyncAnchor(node);
6493 while (true) {
6494 const next = nextSibling(node);
6495 if (next && next !== end) {
6496 remove(next);
6497 }
6498 else {
6499 break;
6500 }
6501 }
6502 }
6503 const next = nextSibling(node);
6504 const container = parentNode(node);
6505 remove(node);
6506 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6507 return next;
6508 };
6509 const locateClosingAsyncAnchor = (node) => {
6510 let match = 0;
6511 while (node) {
6512 node = nextSibling(node);
6513 if (node && isComment(node)) {
6514 if (node.data === '[')
6515 match++;
6516 if (node.data === ']') {
6517 if (match === 0) {
6518 return nextSibling(node);
6519 }
6520 else {
6521 match--;
6522 }
6523 }
6524 }
6525 }
6526 return node;
6527 };
6528 return [hydrate, hydrateNode];
6529}
6530
6531/* eslint-disable no-restricted-globals */
6532let supported;
6533let perf;
6534function startMeasure(instance, type) {
6535 if (instance.appContext.config.performance && isSupported()) {
6536 perf.mark(`vue-${type}-${instance.uid}`);
6537 }
6538 {
6539 devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now());
6540 }
6541}
6542function endMeasure(instance, type) {
6543 if (instance.appContext.config.performance && isSupported()) {
6544 const startTag = `vue-${type}-${instance.uid}`;
6545 const endTag = startTag + `:end`;
6546 perf.mark(endTag);
6547 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
6548 perf.clearMarks(startTag);
6549 perf.clearMarks(endTag);
6550 }
6551 {
6552 devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now());
6553 }
6554}
6555function isSupported() {
6556 if (supported !== undefined) {
6557 return supported;
6558 }
6559 if (typeof window !== 'undefined' && window.performance) {
6560 supported = true;
6561 perf = window.performance;
6562 }
6563 else {
6564 supported = false;
6565 }
6566 return supported;
6567}
6568
6569const queuePostRenderEffect = queueEffectWithSuspense
6570 ;
6571/**
6572 * The createRenderer function accepts two generic arguments:
6573 * HostNode and HostElement, corresponding to Node and Element types in the
6574 * host environment. For example, for runtime-dom, HostNode would be the DOM
6575 * `Node` interface and HostElement would be the DOM `Element` interface.
6576 *
6577 * Custom renderers can pass in the platform specific types like this:
6578 *
6579 * ``` js
6580 * const { render, createApp } = createRenderer<Node, Element>({
6581 * patchProp,
6582 * ...nodeOps
6583 * })
6584 * ```
6585 */
6586function createRenderer(options) {
6587 return baseCreateRenderer(options);
6588}
6589// Separate API for creating hydration-enabled renderer.
6590// Hydration logic is only used when calling this function, making it
6591// tree-shakable.
6592function createHydrationRenderer(options) {
6593 return baseCreateRenderer(options, createHydrationFunctions);
6594}
6595// implementation
6596function baseCreateRenderer(options, createHydrationFns) {
6597 const target = getGlobalThis();
6598 target.__VUE__ = true;
6599 {
6600 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
6601 }
6602 const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, insertStaticContent: hostInsertStaticContent } = options;
6603 // Note: functions inside this closure should use `const xxx = () => {}`
6604 // style in order to prevent being inlined by minifiers.
6605 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
6606 if (n1 === n2) {
6607 return;
6608 }
6609 // patching & not same type, unmount old tree
6610 if (n1 && !isSameVNodeType(n1, n2)) {
6611 anchor = getNextHostNode(n1);
6612 unmount(n1, parentComponent, parentSuspense, true);
6613 n1 = null;
6614 }
6615 if (n2.patchFlag === -2 /* PatchFlags.BAIL */) {
6616 optimized = false;
6617 n2.dynamicChildren = null;
6618 }
6619 const { type, ref, shapeFlag } = n2;
6620 switch (type) {
6621 case Text:
6622 processText(n1, n2, container, anchor);
6623 break;
6624 case Comment:
6625 processCommentNode(n1, n2, container, anchor);
6626 break;
6627 case Static:
6628 if (n1 == null) {
6629 mountStaticNode(n2, container, anchor, isSVG);
6630 }
6631 else {
6632 patchStaticNode(n1, n2, container, isSVG);
6633 }
6634 break;
6635 case Fragment:
6636 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6637 break;
6638 default:
6639 if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
6640 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6641 }
6642 else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
6643 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6644 }
6645 else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
6646 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6647 }
6648 else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
6649 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6650 }
6651 else {
6652 warn('Invalid VNode type:', type, `(${typeof type})`);
6653 }
6654 }
6655 // set ref
6656 if (ref != null && parentComponent) {
6657 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
6658 }
6659 };
6660 const processText = (n1, n2, container, anchor) => {
6661 if (n1 == null) {
6662 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
6663 }
6664 else {
6665 const el = (n2.el = n1.el);
6666 if (n2.children !== n1.children) {
6667 hostSetText(el, n2.children);
6668 }
6669 }
6670 };
6671 const processCommentNode = (n1, n2, container, anchor) => {
6672 if (n1 == null) {
6673 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
6674 }
6675 else {
6676 // there's no support for dynamic comments
6677 n2.el = n1.el;
6678 }
6679 };
6680 const mountStaticNode = (n2, container, anchor, isSVG) => {
6681 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG, n2.el, n2.anchor);
6682 };
6683 /**
6684 * Dev / HMR only
6685 */
6686 const patchStaticNode = (n1, n2, container, isSVG) => {
6687 // static nodes are only patched during dev for HMR
6688 if (n2.children !== n1.children) {
6689 const anchor = hostNextSibling(n1.anchor);
6690 // remove existing
6691 removeStaticNode(n1);
6692 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
6693 }
6694 else {
6695 n2.el = n1.el;
6696 n2.anchor = n1.anchor;
6697 }
6698 };
6699 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
6700 let next;
6701 while (el && el !== anchor) {
6702 next = hostNextSibling(el);
6703 hostInsert(el, container, nextSibling);
6704 el = next;
6705 }
6706 hostInsert(anchor, container, nextSibling);
6707 };
6708 const removeStaticNode = ({ el, anchor }) => {
6709 let next;
6710 while (el && el !== anchor) {
6711 next = hostNextSibling(el);
6712 hostRemove(el);
6713 el = next;
6714 }
6715 hostRemove(anchor);
6716 };
6717 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6718 isSVG = isSVG || n2.type === 'svg';
6719 if (n1 == null) {
6720 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6721 }
6722 else {
6723 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6724 }
6725 };
6726 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6727 let el;
6728 let vnodeHook;
6729 const { type, props, shapeFlag, transition, dirs } = vnode;
6730 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6731 // mount children first, since some props may rely on child content
6732 // being already rendered, e.g. `<select value>`
6733 if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
6734 hostSetElementText(el, vnode.children);
6735 }
6736 else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
6737 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6738 }
6739 if (dirs) {
6740 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6741 }
6742 // scopeId
6743 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6744 // props
6745 if (props) {
6746 for (const key in props) {
6747 if (key !== 'value' && !isReservedProp(key)) {
6748 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6749 }
6750 }
6751 /**
6752 * Special case for setting value on DOM elements:
6753 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6754 * - it needs to be forced (#1471)
6755 * #2353 proposes adding another renderer option to configure this, but
6756 * the properties affects are so finite it is worth special casing it
6757 * here to reduce the complexity. (Special casing it also should not
6758 * affect non-DOM renderers)
6759 */
6760 if ('value' in props) {
6761 hostPatchProp(el, 'value', null, props.value);
6762 }
6763 if ((vnodeHook = props.onVnodeBeforeMount)) {
6764 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6765 }
6766 }
6767 {
6768 Object.defineProperty(el, '__vnode', {
6769 value: vnode,
6770 enumerable: false
6771 });
6772 Object.defineProperty(el, '__vueParentComponent', {
6773 value: parentComponent,
6774 enumerable: false
6775 });
6776 }
6777 if (dirs) {
6778 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6779 }
6780 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
6781 // #1689 For inside suspense + suspense resolved case, just call it
6782 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
6783 transition &&
6784 !transition.persisted;
6785 if (needCallTransitionHooks) {
6786 transition.beforeEnter(el);
6787 }
6788 hostInsert(el, container, anchor);
6789 if ((vnodeHook = props && props.onVnodeMounted) ||
6790 needCallTransitionHooks ||
6791 dirs) {
6792 queuePostRenderEffect(() => {
6793 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6794 needCallTransitionHooks && transition.enter(el);
6795 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6796 }, parentSuspense);
6797 }
6798 };
6799 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
6800 if (scopeId) {
6801 hostSetScopeId(el, scopeId);
6802 }
6803 if (slotScopeIds) {
6804 for (let i = 0; i < slotScopeIds.length; i++) {
6805 hostSetScopeId(el, slotScopeIds[i]);
6806 }
6807 }
6808 if (parentComponent) {
6809 let subTree = parentComponent.subTree;
6810 if (subTree.patchFlag > 0 &&
6811 subTree.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */) {
6812 subTree =
6813 filterSingleRoot(subTree.children) || subTree;
6814 }
6815 if (vnode === subTree) {
6816 const parentVNode = parentComponent.vnode;
6817 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
6818 }
6819 }
6820 };
6821 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
6822 for (let i = start; i < children.length; i++) {
6823 const child = (children[i] = optimized
6824 ? cloneIfMounted(children[i])
6825 : normalizeVNode(children[i]));
6826 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6827 }
6828 };
6829 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6830 const el = (n2.el = n1.el);
6831 let { patchFlag, dynamicChildren, dirs } = n2;
6832 // #1426 take the old vnode's patch flag into account since user may clone a
6833 // compiler-generated vnode, which de-opts to FULL_PROPS
6834 patchFlag |= n1.patchFlag & 16 /* PatchFlags.FULL_PROPS */;
6835 const oldProps = n1.props || EMPTY_OBJ;
6836 const newProps = n2.props || EMPTY_OBJ;
6837 let vnodeHook;
6838 // disable recurse in beforeUpdate hooks
6839 parentComponent && toggleRecurse(parentComponent, false);
6840 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6841 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6842 }
6843 if (dirs) {
6844 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6845 }
6846 parentComponent && toggleRecurse(parentComponent, true);
6847 if (isHmrUpdating) {
6848 // HMR updated, force full diff
6849 patchFlag = 0;
6850 optimized = false;
6851 dynamicChildren = null;
6852 }
6853 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
6854 if (dynamicChildren) {
6855 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
6856 if (parentComponent && parentComponent.type.__hmrId) {
6857 traverseStaticChildren(n1, n2);
6858 }
6859 }
6860 else if (!optimized) {
6861 // full diff
6862 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
6863 }
6864 if (patchFlag > 0) {
6865 // the presence of a patchFlag means this element's render code was
6866 // generated by the compiler and can take the fast path.
6867 // in this path old node and new node are guaranteed to have the same shape
6868 // (i.e. at the exact same position in the source template)
6869 if (patchFlag & 16 /* PatchFlags.FULL_PROPS */) {
6870 // element props contain dynamic keys, full diff needed
6871 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6872 }
6873 else {
6874 // class
6875 // this flag is matched when the element has dynamic class bindings.
6876 if (patchFlag & 2 /* PatchFlags.CLASS */) {
6877 if (oldProps.class !== newProps.class) {
6878 hostPatchProp(el, 'class', null, newProps.class, isSVG);
6879 }
6880 }
6881 // style
6882 // this flag is matched when the element has dynamic style bindings
6883 if (patchFlag & 4 /* PatchFlags.STYLE */) {
6884 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
6885 }
6886 // props
6887 // This flag is matched when the element has dynamic prop/attr bindings
6888 // other than class and style. The keys of dynamic prop/attrs are saved for
6889 // faster iteration.
6890 // Note dynamic keys like :[foo]="bar" will cause this optimization to
6891 // bail out and go through a full diff because we need to unset the old key
6892 if (patchFlag & 8 /* PatchFlags.PROPS */) {
6893 // if the flag is present then dynamicProps must be non-null
6894 const propsToUpdate = n2.dynamicProps;
6895 for (let i = 0; i < propsToUpdate.length; i++) {
6896 const key = propsToUpdate[i];
6897 const prev = oldProps[key];
6898 const next = newProps[key];
6899 // #1471 force patch value
6900 if (next !== prev || key === 'value') {
6901 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
6902 }
6903 }
6904 }
6905 }
6906 // text
6907 // This flag is matched when the element has only dynamic text children.
6908 if (patchFlag & 1 /* PatchFlags.TEXT */) {
6909 if (n1.children !== n2.children) {
6910 hostSetElementText(el, n2.children);
6911 }
6912 }
6913 }
6914 else if (!optimized && dynamicChildren == null) {
6915 // unoptimized, full diff
6916 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6917 }
6918 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
6919 queuePostRenderEffect(() => {
6920 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6921 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
6922 }, parentSuspense);
6923 }
6924 };
6925 // The fast path for blocks.
6926 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
6927 for (let i = 0; i < newChildren.length; i++) {
6928 const oldVNode = oldChildren[i];
6929 const newVNode = newChildren[i];
6930 // Determine the container (parent element) for the patch.
6931 const container =
6932 // oldVNode may be an errored async setup() component inside Suspense
6933 // which will not have a mounted element
6934 oldVNode.el &&
6935 // - In the case of a Fragment, we need to provide the actual parent
6936 // of the Fragment itself so it can move its children.
6937 (oldVNode.type === Fragment ||
6938 // - In the case of different nodes, there is going to be a replacement
6939 // which also requires the correct parent container
6940 !isSameVNodeType(oldVNode, newVNode) ||
6941 // - In the case of a component, it could contain anything.
6942 oldVNode.shapeFlag & (6 /* ShapeFlags.COMPONENT */ | 64 /* ShapeFlags.TELEPORT */))
6943 ? hostParentNode(oldVNode.el)
6944 : // In other cases, the parent container is not actually used so we
6945 // just pass the block element here to avoid a DOM parentNode call.
6946 fallbackContainer;
6947 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
6948 }
6949 };
6950 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
6951 if (oldProps !== newProps) {
6952 if (oldProps !== EMPTY_OBJ) {
6953 for (const key in oldProps) {
6954 if (!isReservedProp(key) && !(key in newProps)) {
6955 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6956 }
6957 }
6958 }
6959 for (const key in newProps) {
6960 // empty string is not valid prop
6961 if (isReservedProp(key))
6962 continue;
6963 const next = newProps[key];
6964 const prev = oldProps[key];
6965 // defer patching value
6966 if (next !== prev && key !== 'value') {
6967 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6968 }
6969 }
6970 if ('value' in newProps) {
6971 hostPatchProp(el, 'value', oldProps.value, newProps.value);
6972 }
6973 }
6974 };
6975 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6976 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
6977 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
6978 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
6979 if (// #5523 dev root fragment may inherit directives
6980 (isHmrUpdating || patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */)) {
6981 // HMR updated / Dev root fragment (w/ comments), force full diff
6982 patchFlag = 0;
6983 optimized = false;
6984 dynamicChildren = null;
6985 }
6986 // check if this is a slot fragment with :slotted scope ids
6987 if (fragmentSlotScopeIds) {
6988 slotScopeIds = slotScopeIds
6989 ? slotScopeIds.concat(fragmentSlotScopeIds)
6990 : fragmentSlotScopeIds;
6991 }
6992 if (n1 == null) {
6993 hostInsert(fragmentStartAnchor, container, anchor);
6994 hostInsert(fragmentEndAnchor, container, anchor);
6995 // a fragment can only have array children
6996 // since they are either generated by the compiler, or implicitly created
6997 // from arrays.
6998 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6999 }
7000 else {
7001 if (patchFlag > 0 &&
7002 patchFlag & 64 /* PatchFlags.STABLE_FRAGMENT */ &&
7003 dynamicChildren &&
7004 // #2715 the previous fragment could've been a BAILed one as a result
7005 // of renderSlot() with no valid children
7006 n1.dynamicChildren) {
7007 // a stable fragment (template root or <template v-for>) doesn't need to
7008 // patch children order, but it may contain dynamicChildren.
7009 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
7010 if (parentComponent && parentComponent.type.__hmrId) {
7011 traverseStaticChildren(n1, n2);
7012 }
7013 else if (
7014 // #2080 if the stable fragment has a key, it's a <template v-for> that may
7015 // get moved around. Make sure all root level vnodes inherit el.
7016 // #2134 or if it's a component root, it may also get moved around
7017 // as the component is being moved.
7018 n2.key != null ||
7019 (parentComponent && n2 === parentComponent.subTree)) {
7020 traverseStaticChildren(n1, n2, true /* shallow */);
7021 }
7022 }
7023 else {
7024 // keyed / unkeyed, or manual fragments.
7025 // for keyed & unkeyed, since they are compiler generated from v-for,
7026 // each child is guaranteed to be a block so the fragment will never
7027 // have dynamicChildren.
7028 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7029 }
7030 }
7031 };
7032 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7033 n2.slotScopeIds = slotScopeIds;
7034 if (n1 == null) {
7035 if (n2.shapeFlag & 512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */) {
7036 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
7037 }
7038 else {
7039 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
7040 }
7041 }
7042 else {
7043 updateComponent(n1, n2, optimized);
7044 }
7045 };
7046 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
7047 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
7048 if (instance.type.__hmrId) {
7049 registerHMR(instance);
7050 }
7051 {
7052 pushWarningContext(initialVNode);
7053 startMeasure(instance, `mount`);
7054 }
7055 // inject renderer internals for keepAlive
7056 if (isKeepAlive(initialVNode)) {
7057 instance.ctx.renderer = internals;
7058 }
7059 // resolve props and slots for setup context
7060 {
7061 {
7062 startMeasure(instance, `init`);
7063 }
7064 setupComponent(instance);
7065 {
7066 endMeasure(instance, `init`);
7067 }
7068 }
7069 // setup() is async. This component relies on async logic to be resolved
7070 // before proceeding
7071 if (instance.asyncDep) {
7072 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
7073 // Give it a placeholder if this is not hydration
7074 // TODO handle self-defined fallback
7075 if (!initialVNode.el) {
7076 const placeholder = (instance.subTree = createVNode(Comment));
7077 processCommentNode(null, placeholder, container, anchor);
7078 }
7079 return;
7080 }
7081 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
7082 {
7083 popWarningContext();
7084 endMeasure(instance, `mount`);
7085 }
7086 };
7087 const updateComponent = (n1, n2, optimized) => {
7088 const instance = (n2.component = n1.component);
7089 if (shouldUpdateComponent(n1, n2, optimized)) {
7090 if (instance.asyncDep &&
7091 !instance.asyncResolved) {
7092 // async & still pending - just update props and slots
7093 // since the component's reactive effect for render isn't set-up yet
7094 {
7095 pushWarningContext(n2);
7096 }
7097 updateComponentPreRender(instance, n2, optimized);
7098 {
7099 popWarningContext();
7100 }
7101 return;
7102 }
7103 else {
7104 // normal update
7105 instance.next = n2;
7106 // in case the child component is also queued, remove it to avoid
7107 // double updating the same child component in the same flush.
7108 invalidateJob(instance.update);
7109 // instance.update is the reactive effect.
7110 instance.update();
7111 }
7112 }
7113 else {
7114 // no update needed. just copy over properties
7115 n2.el = n1.el;
7116 instance.vnode = n2;
7117 }
7118 };
7119 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
7120 const componentUpdateFn = () => {
7121 if (!instance.isMounted) {
7122 let vnodeHook;
7123 const { el, props } = initialVNode;
7124 const { bm, m, parent } = instance;
7125 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
7126 toggleRecurse(instance, false);
7127 // beforeMount hook
7128 if (bm) {
7129 invokeArrayFns(bm);
7130 }
7131 // onVnodeBeforeMount
7132 if (!isAsyncWrapperVNode &&
7133 (vnodeHook = props && props.onVnodeBeforeMount)) {
7134 invokeVNodeHook(vnodeHook, parent, initialVNode);
7135 }
7136 toggleRecurse(instance, true);
7137 if (el && hydrateNode) {
7138 // vnode has adopted host node - perform hydration instead of mount.
7139 const hydrateSubTree = () => {
7140 {
7141 startMeasure(instance, `render`);
7142 }
7143 instance.subTree = renderComponentRoot(instance);
7144 {
7145 endMeasure(instance, `render`);
7146 }
7147 {
7148 startMeasure(instance, `hydrate`);
7149 }
7150 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
7151 {
7152 endMeasure(instance, `hydrate`);
7153 }
7154 };
7155 if (isAsyncWrapperVNode) {
7156 initialVNode.type.__asyncLoader().then(
7157 // note: we are moving the render call into an async callback,
7158 // which means it won't track dependencies - but it's ok because
7159 // a server-rendered async wrapper is already in resolved state
7160 // and it will never need to change.
7161 () => !instance.isUnmounted && hydrateSubTree());
7162 }
7163 else {
7164 hydrateSubTree();
7165 }
7166 }
7167 else {
7168 {
7169 startMeasure(instance, `render`);
7170 }
7171 const subTree = (instance.subTree = renderComponentRoot(instance));
7172 {
7173 endMeasure(instance, `render`);
7174 }
7175 {
7176 startMeasure(instance, `patch`);
7177 }
7178 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
7179 {
7180 endMeasure(instance, `patch`);
7181 }
7182 initialVNode.el = subTree.el;
7183 }
7184 // mounted hook
7185 if (m) {
7186 queuePostRenderEffect(m, parentSuspense);
7187 }
7188 // onVnodeMounted
7189 if (!isAsyncWrapperVNode &&
7190 (vnodeHook = props && props.onVnodeMounted)) {
7191 const scopedInitialVNode = initialVNode;
7192 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
7193 }
7194 // activated hook for keep-alive roots.
7195 // #1742 activated hook must be accessed after first render
7196 // since the hook may be injected by a child keep-alive
7197 if (initialVNode.shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */ ||
7198 (parent &&
7199 isAsyncWrapper(parent.vnode) &&
7200 parent.vnode.shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */)) {
7201 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
7202 }
7203 instance.isMounted = true;
7204 {
7205 devtoolsComponentAdded(instance);
7206 }
7207 // #2458: deference mount-only object parameters to prevent memleaks
7208 initialVNode = container = anchor = null;
7209 }
7210 else {
7211 // updateComponent
7212 // This is triggered by mutation of component's own state (next: null)
7213 // OR parent calling processComponent (next: VNode)
7214 let { next, bu, u, parent, vnode } = instance;
7215 let originNext = next;
7216 let vnodeHook;
7217 {
7218 pushWarningContext(next || instance.vnode);
7219 }
7220 // Disallow component effect recursion during pre-lifecycle hooks.
7221 toggleRecurse(instance, false);
7222 if (next) {
7223 next.el = vnode.el;
7224 updateComponentPreRender(instance, next, optimized);
7225 }
7226 else {
7227 next = vnode;
7228 }
7229 // beforeUpdate hook
7230 if (bu) {
7231 invokeArrayFns(bu);
7232 }
7233 // onVnodeBeforeUpdate
7234 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
7235 invokeVNodeHook(vnodeHook, parent, next, vnode);
7236 }
7237 toggleRecurse(instance, true);
7238 // render
7239 {
7240 startMeasure(instance, `render`);
7241 }
7242 const nextTree = renderComponentRoot(instance);
7243 {
7244 endMeasure(instance, `render`);
7245 }
7246 const prevTree = instance.subTree;
7247 instance.subTree = nextTree;
7248 {
7249 startMeasure(instance, `patch`);
7250 }
7251 patch(prevTree, nextTree,
7252 // parent may have changed if it's in a teleport
7253 hostParentNode(prevTree.el),
7254 // anchor may have changed if it's in a fragment
7255 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
7256 {
7257 endMeasure(instance, `patch`);
7258 }
7259 next.el = nextTree.el;
7260 if (originNext === null) {
7261 // self-triggered update. In case of HOC, update parent component
7262 // vnode el. HOC is indicated by parent instance's subTree pointing
7263 // to child component's vnode
7264 updateHOCHostEl(instance, nextTree.el);
7265 }
7266 // updated hook
7267 if (u) {
7268 queuePostRenderEffect(u, parentSuspense);
7269 }
7270 // onVnodeUpdated
7271 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
7272 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
7273 }
7274 {
7275 devtoolsComponentUpdated(instance);
7276 }
7277 {
7278 popWarningContext();
7279 }
7280 }
7281 };
7282 // create reactive effect for rendering
7283 const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(update), instance.scope // track it in component's effect scope
7284 ));
7285 const update = (instance.update = () => effect.run());
7286 update.id = instance.uid;
7287 // allowRecurse
7288 // #1801, #2043 component render effects should allow recursive updates
7289 toggleRecurse(instance, true);
7290 {
7291 effect.onTrack = instance.rtc
7292 ? e => invokeArrayFns(instance.rtc, e)
7293 : void 0;
7294 effect.onTrigger = instance.rtg
7295 ? e => invokeArrayFns(instance.rtg, e)
7296 : void 0;
7297 update.ownerInstance = instance;
7298 }
7299 update();
7300 };
7301 const updateComponentPreRender = (instance, nextVNode, optimized) => {
7302 nextVNode.component = instance;
7303 const prevProps = instance.vnode.props;
7304 instance.vnode = nextVNode;
7305 instance.next = null;
7306 updateProps(instance, nextVNode.props, prevProps, optimized);
7307 updateSlots(instance, nextVNode.children, optimized);
7308 pauseTracking();
7309 // props update may have triggered pre-flush watchers.
7310 // flush them before the render update.
7311 flushPreFlushCbs();
7312 resetTracking();
7313 };
7314 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
7315 const c1 = n1 && n1.children;
7316 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
7317 const c2 = n2.children;
7318 const { patchFlag, shapeFlag } = n2;
7319 // fast path
7320 if (patchFlag > 0) {
7321 if (patchFlag & 128 /* PatchFlags.KEYED_FRAGMENT */) {
7322 // this could be either fully-keyed or mixed (some keyed some not)
7323 // presence of patchFlag means children are guaranteed to be arrays
7324 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7325 return;
7326 }
7327 else if (patchFlag & 256 /* PatchFlags.UNKEYED_FRAGMENT */) {
7328 // unkeyed
7329 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7330 return;
7331 }
7332 }
7333 // children has 3 possibilities: text, array or no children.
7334 if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
7335 // text children fast path
7336 if (prevShapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7337 unmountChildren(c1, parentComponent, parentSuspense);
7338 }
7339 if (c2 !== c1) {
7340 hostSetElementText(container, c2);
7341 }
7342 }
7343 else {
7344 if (prevShapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7345 // prev children was array
7346 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7347 // two arrays, cannot assume anything, do full diff
7348 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7349 }
7350 else {
7351 // no new children, just unmount old
7352 unmountChildren(c1, parentComponent, parentSuspense, true);
7353 }
7354 }
7355 else {
7356 // prev children was text OR null
7357 // new children is array OR null
7358 if (prevShapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
7359 hostSetElementText(container, '');
7360 }
7361 // mount new if array
7362 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7363 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7364 }
7365 }
7366 }
7367 };
7368 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7369 c1 = c1 || EMPTY_ARR;
7370 c2 = c2 || EMPTY_ARR;
7371 const oldLength = c1.length;
7372 const newLength = c2.length;
7373 const commonLength = Math.min(oldLength, newLength);
7374 let i;
7375 for (i = 0; i < commonLength; i++) {
7376 const nextChild = (c2[i] = optimized
7377 ? cloneIfMounted(c2[i])
7378 : normalizeVNode(c2[i]));
7379 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7380 }
7381 if (oldLength > newLength) {
7382 // remove old
7383 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
7384 }
7385 else {
7386 // mount new
7387 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
7388 }
7389 };
7390 // can be all-keyed or mixed
7391 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7392 let i = 0;
7393 const l2 = c2.length;
7394 let e1 = c1.length - 1; // prev ending index
7395 let e2 = l2 - 1; // next ending index
7396 // 1. sync from start
7397 // (a b) c
7398 // (a b) d e
7399 while (i <= e1 && i <= e2) {
7400 const n1 = c1[i];
7401 const n2 = (c2[i] = optimized
7402 ? cloneIfMounted(c2[i])
7403 : normalizeVNode(c2[i]));
7404 if (isSameVNodeType(n1, n2)) {
7405 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7406 }
7407 else {
7408 break;
7409 }
7410 i++;
7411 }
7412 // 2. sync from end
7413 // a (b c)
7414 // d e (b c)
7415 while (i <= e1 && i <= e2) {
7416 const n1 = c1[e1];
7417 const n2 = (c2[e2] = optimized
7418 ? cloneIfMounted(c2[e2])
7419 : normalizeVNode(c2[e2]));
7420 if (isSameVNodeType(n1, n2)) {
7421 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7422 }
7423 else {
7424 break;
7425 }
7426 e1--;
7427 e2--;
7428 }
7429 // 3. common sequence + mount
7430 // (a b)
7431 // (a b) c
7432 // i = 2, e1 = 1, e2 = 2
7433 // (a b)
7434 // c (a b)
7435 // i = 0, e1 = -1, e2 = 0
7436 if (i > e1) {
7437 if (i <= e2) {
7438 const nextPos = e2 + 1;
7439 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
7440 while (i <= e2) {
7441 patch(null, (c2[i] = optimized
7442 ? cloneIfMounted(c2[i])
7443 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7444 i++;
7445 }
7446 }
7447 }
7448 // 4. common sequence + unmount
7449 // (a b) c
7450 // (a b)
7451 // i = 2, e1 = 2, e2 = 1
7452 // a (b c)
7453 // (b c)
7454 // i = 0, e1 = 0, e2 = -1
7455 else if (i > e2) {
7456 while (i <= e1) {
7457 unmount(c1[i], parentComponent, parentSuspense, true);
7458 i++;
7459 }
7460 }
7461 // 5. unknown sequence
7462 // [i ... e1 + 1]: a b [c d e] f g
7463 // [i ... e2 + 1]: a b [e d c h] f g
7464 // i = 2, e1 = 4, e2 = 5
7465 else {
7466 const s1 = i; // prev starting index
7467 const s2 = i; // next starting index
7468 // 5.1 build key:index map for newChildren
7469 const keyToNewIndexMap = new Map();
7470 for (i = s2; i <= e2; i++) {
7471 const nextChild = (c2[i] = optimized
7472 ? cloneIfMounted(c2[i])
7473 : normalizeVNode(c2[i]));
7474 if (nextChild.key != null) {
7475 if (keyToNewIndexMap.has(nextChild.key)) {
7476 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
7477 }
7478 keyToNewIndexMap.set(nextChild.key, i);
7479 }
7480 }
7481 // 5.2 loop through old children left to be patched and try to patch
7482 // matching nodes & remove nodes that are no longer present
7483 let j;
7484 let patched = 0;
7485 const toBePatched = e2 - s2 + 1;
7486 let moved = false;
7487 // used to track whether any node has moved
7488 let maxNewIndexSoFar = 0;
7489 // works as Map<newIndex, oldIndex>
7490 // Note that oldIndex is offset by +1
7491 // and oldIndex = 0 is a special value indicating the new node has
7492 // no corresponding old node.
7493 // used for determining longest stable subsequence
7494 const newIndexToOldIndexMap = new Array(toBePatched);
7495 for (i = 0; i < toBePatched; i++)
7496 newIndexToOldIndexMap[i] = 0;
7497 for (i = s1; i <= e1; i++) {
7498 const prevChild = c1[i];
7499 if (patched >= toBePatched) {
7500 // all new children have been patched so this can only be a removal
7501 unmount(prevChild, parentComponent, parentSuspense, true);
7502 continue;
7503 }
7504 let newIndex;
7505 if (prevChild.key != null) {
7506 newIndex = keyToNewIndexMap.get(prevChild.key);
7507 }
7508 else {
7509 // key-less node, try to locate a key-less node of the same type
7510 for (j = s2; j <= e2; j++) {
7511 if (newIndexToOldIndexMap[j - s2] === 0 &&
7512 isSameVNodeType(prevChild, c2[j])) {
7513 newIndex = j;
7514 break;
7515 }
7516 }
7517 }
7518 if (newIndex === undefined) {
7519 unmount(prevChild, parentComponent, parentSuspense, true);
7520 }
7521 else {
7522 newIndexToOldIndexMap[newIndex - s2] = i + 1;
7523 if (newIndex >= maxNewIndexSoFar) {
7524 maxNewIndexSoFar = newIndex;
7525 }
7526 else {
7527 moved = true;
7528 }
7529 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7530 patched++;
7531 }
7532 }
7533 // 5.3 move and mount
7534 // generate longest stable subsequence only when nodes have moved
7535 const increasingNewIndexSequence = moved
7536 ? getSequence(newIndexToOldIndexMap)
7537 : EMPTY_ARR;
7538 j = increasingNewIndexSequence.length - 1;
7539 // looping backwards so that we can use last patched node as anchor
7540 for (i = toBePatched - 1; i >= 0; i--) {
7541 const nextIndex = s2 + i;
7542 const nextChild = c2[nextIndex];
7543 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
7544 if (newIndexToOldIndexMap[i] === 0) {
7545 // mount new
7546 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7547 }
7548 else if (moved) {
7549 // move if:
7550 // There is no stable subsequence (e.g. a reverse)
7551 // OR current node is not among the stable sequence
7552 if (j < 0 || i !== increasingNewIndexSequence[j]) {
7553 move(nextChild, container, anchor, 2 /* MoveType.REORDER */);
7554 }
7555 else {
7556 j--;
7557 }
7558 }
7559 }
7560 }
7561 };
7562 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
7563 const { el, type, transition, children, shapeFlag } = vnode;
7564 if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
7565 move(vnode.component.subTree, container, anchor, moveType);
7566 return;
7567 }
7568 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
7569 vnode.suspense.move(container, anchor, moveType);
7570 return;
7571 }
7572 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
7573 type.move(vnode, container, anchor, internals);
7574 return;
7575 }
7576 if (type === Fragment) {
7577 hostInsert(el, container, anchor);
7578 for (let i = 0; i < children.length; i++) {
7579 move(children[i], container, anchor, moveType);
7580 }
7581 hostInsert(vnode.anchor, container, anchor);
7582 return;
7583 }
7584 if (type === Static) {
7585 moveStaticNode(vnode, container, anchor);
7586 return;
7587 }
7588 // single nodes
7589 const needTransition = moveType !== 2 /* MoveType.REORDER */ &&
7590 shapeFlag & 1 /* ShapeFlags.ELEMENT */ &&
7591 transition;
7592 if (needTransition) {
7593 if (moveType === 0 /* MoveType.ENTER */) {
7594 transition.beforeEnter(el);
7595 hostInsert(el, container, anchor);
7596 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
7597 }
7598 else {
7599 const { leave, delayLeave, afterLeave } = transition;
7600 const remove = () => hostInsert(el, container, anchor);
7601 const performLeave = () => {
7602 leave(el, () => {
7603 remove();
7604 afterLeave && afterLeave();
7605 });
7606 };
7607 if (delayLeave) {
7608 delayLeave(el, remove, performLeave);
7609 }
7610 else {
7611 performLeave();
7612 }
7613 }
7614 }
7615 else {
7616 hostInsert(el, container, anchor);
7617 }
7618 };
7619 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
7620 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
7621 // unset ref
7622 if (ref != null) {
7623 setRef(ref, null, parentSuspense, vnode, true);
7624 }
7625 if (shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */) {
7626 parentComponent.ctx.deactivate(vnode);
7627 return;
7628 }
7629 const shouldInvokeDirs = shapeFlag & 1 /* ShapeFlags.ELEMENT */ && dirs;
7630 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
7631 let vnodeHook;
7632 if (shouldInvokeVnodeHook &&
7633 (vnodeHook = props && props.onVnodeBeforeUnmount)) {
7634 invokeVNodeHook(vnodeHook, parentComponent, vnode);
7635 }
7636 if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
7637 unmountComponent(vnode.component, parentSuspense, doRemove);
7638 }
7639 else {
7640 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
7641 vnode.suspense.unmount(parentSuspense, doRemove);
7642 return;
7643 }
7644 if (shouldInvokeDirs) {
7645 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
7646 }
7647 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
7648 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
7649 }
7650 else if (dynamicChildren &&
7651 // #1153: fast path should not be taken for non-stable (v-for) fragments
7652 (type !== Fragment ||
7653 (patchFlag > 0 && patchFlag & 64 /* PatchFlags.STABLE_FRAGMENT */))) {
7654 // fast path for block nodes: only need to unmount dynamic children.
7655 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
7656 }
7657 else if ((type === Fragment &&
7658 patchFlag &
7659 (128 /* PatchFlags.KEYED_FRAGMENT */ | 256 /* PatchFlags.UNKEYED_FRAGMENT */)) ||
7660 (!optimized && shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */)) {
7661 unmountChildren(children, parentComponent, parentSuspense);
7662 }
7663 if (doRemove) {
7664 remove(vnode);
7665 }
7666 }
7667 if ((shouldInvokeVnodeHook &&
7668 (vnodeHook = props && props.onVnodeUnmounted)) ||
7669 shouldInvokeDirs) {
7670 queuePostRenderEffect(() => {
7671 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
7672 shouldInvokeDirs &&
7673 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
7674 }, parentSuspense);
7675 }
7676 };
7677 const remove = vnode => {
7678 const { type, el, anchor, transition } = vnode;
7679 if (type === Fragment) {
7680 if (vnode.patchFlag > 0 &&
7681 vnode.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */ &&
7682 transition &&
7683 !transition.persisted) {
7684 vnode.children.forEach(child => {
7685 if (child.type === Comment) {
7686 hostRemove(child.el);
7687 }
7688 else {
7689 remove(child);
7690 }
7691 });
7692 }
7693 else {
7694 removeFragment(el, anchor);
7695 }
7696 return;
7697 }
7698 if (type === Static) {
7699 removeStaticNode(vnode);
7700 return;
7701 }
7702 const performRemove = () => {
7703 hostRemove(el);
7704 if (transition && !transition.persisted && transition.afterLeave) {
7705 transition.afterLeave();
7706 }
7707 };
7708 if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */ &&
7709 transition &&
7710 !transition.persisted) {
7711 const { leave, delayLeave } = transition;
7712 const performLeave = () => leave(el, performRemove);
7713 if (delayLeave) {
7714 delayLeave(vnode.el, performRemove, performLeave);
7715 }
7716 else {
7717 performLeave();
7718 }
7719 }
7720 else {
7721 performRemove();
7722 }
7723 };
7724 const removeFragment = (cur, end) => {
7725 // For fragments, directly remove all contained DOM nodes.
7726 // (fragment child nodes cannot have transition)
7727 let next;
7728 while (cur !== end) {
7729 next = hostNextSibling(cur);
7730 hostRemove(cur);
7731 cur = next;
7732 }
7733 hostRemove(end);
7734 };
7735 const unmountComponent = (instance, parentSuspense, doRemove) => {
7736 if (instance.type.__hmrId) {
7737 unregisterHMR(instance);
7738 }
7739 const { bum, scope, update, subTree, um } = instance;
7740 // beforeUnmount hook
7741 if (bum) {
7742 invokeArrayFns(bum);
7743 }
7744 // stop effects in component scope
7745 scope.stop();
7746 // update may be null if a component is unmounted before its async
7747 // setup has resolved.
7748 if (update) {
7749 // so that scheduler will no longer invoke it
7750 update.active = false;
7751 unmount(subTree, instance, parentSuspense, doRemove);
7752 }
7753 // unmounted hook
7754 if (um) {
7755 queuePostRenderEffect(um, parentSuspense);
7756 }
7757 queuePostRenderEffect(() => {
7758 instance.isUnmounted = true;
7759 }, parentSuspense);
7760 // A component with async dep inside a pending suspense is unmounted before
7761 // its async dep resolves. This should remove the dep from the suspense, and
7762 // cause the suspense to resolve immediately if that was the last dep.
7763 if (parentSuspense &&
7764 parentSuspense.pendingBranch &&
7765 !parentSuspense.isUnmounted &&
7766 instance.asyncDep &&
7767 !instance.asyncResolved &&
7768 instance.suspenseId === parentSuspense.pendingId) {
7769 parentSuspense.deps--;
7770 if (parentSuspense.deps === 0) {
7771 parentSuspense.resolve();
7772 }
7773 }
7774 {
7775 devtoolsComponentRemoved(instance);
7776 }
7777 };
7778 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
7779 for (let i = start; i < children.length; i++) {
7780 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
7781 }
7782 };
7783 const getNextHostNode = vnode => {
7784 if (vnode.shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
7785 return getNextHostNode(vnode.component.subTree);
7786 }
7787 if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
7788 return vnode.suspense.next();
7789 }
7790 return hostNextSibling((vnode.anchor || vnode.el));
7791 };
7792 const render = (vnode, container, isSVG) => {
7793 if (vnode == null) {
7794 if (container._vnode) {
7795 unmount(container._vnode, null, null, true);
7796 }
7797 }
7798 else {
7799 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
7800 }
7801 flushPreFlushCbs();
7802 flushPostFlushCbs();
7803 container._vnode = vnode;
7804 };
7805 const internals = {
7806 p: patch,
7807 um: unmount,
7808 m: move,
7809 r: remove,
7810 mt: mountComponent,
7811 mc: mountChildren,
7812 pc: patchChildren,
7813 pbc: patchBlockChildren,
7814 n: getNextHostNode,
7815 o: options
7816 };
7817 let hydrate;
7818 let hydrateNode;
7819 if (createHydrationFns) {
7820 [hydrate, hydrateNode] = createHydrationFns(internals);
7821 }
7822 return {
7823 render,
7824 hydrate,
7825 createApp: createAppAPI(render, hydrate)
7826 };
7827}
7828function toggleRecurse({ effect, update }, allowed) {
7829 effect.allowRecurse = update.allowRecurse = allowed;
7830}
7831/**
7832 * #1156
7833 * When a component is HMR-enabled, we need to make sure that all static nodes
7834 * inside a block also inherit the DOM element from the previous tree so that
7835 * HMR updates (which are full updates) can retrieve the element for patching.
7836 *
7837 * #2080
7838 * Inside keyed `template` fragment static children, if a fragment is moved,
7839 * the children will always be moved. Therefore, in order to ensure correct move
7840 * position, el should be inherited from previous nodes.
7841 */
7842function traverseStaticChildren(n1, n2, shallow = false) {
7843 const ch1 = n1.children;
7844 const ch2 = n2.children;
7845 if (isArray(ch1) && isArray(ch2)) {
7846 for (let i = 0; i < ch1.length; i++) {
7847 // this is only called in the optimized path so array children are
7848 // guaranteed to be vnodes
7849 const c1 = ch1[i];
7850 let c2 = ch2[i];
7851 if (c2.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && !c2.dynamicChildren) {
7852 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* PatchFlags.HYDRATE_EVENTS */) {
7853 c2 = ch2[i] = cloneIfMounted(ch2[i]);
7854 c2.el = c1.el;
7855 }
7856 if (!shallow)
7857 traverseStaticChildren(c1, c2);
7858 }
7859 // #6852 also inherit for text nodes
7860 if (c2.type === Text) {
7861 c2.el = c1.el;
7862 }
7863 // also inherit for comment nodes, but not placeholders (e.g. v-if which
7864 // would have received .el during block patch)
7865 if (c2.type === Comment && !c2.el) {
7866 c2.el = c1.el;
7867 }
7868 }
7869 }
7870}
7871// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
7872function getSequence(arr) {
7873 const p = arr.slice();
7874 const result = [0];
7875 let i, j, u, v, c;
7876 const len = arr.length;
7877 for (i = 0; i < len; i++) {
7878 const arrI = arr[i];
7879 if (arrI !== 0) {
7880 j = result[result.length - 1];
7881 if (arr[j] < arrI) {
7882 p[i] = j;
7883 result.push(i);
7884 continue;
7885 }
7886 u = 0;
7887 v = result.length - 1;
7888 while (u < v) {
7889 c = (u + v) >> 1;
7890 if (arr[result[c]] < arrI) {
7891 u = c + 1;
7892 }
7893 else {
7894 v = c;
7895 }
7896 }
7897 if (arrI < arr[result[u]]) {
7898 if (u > 0) {
7899 p[i] = result[u - 1];
7900 }
7901 result[u] = i;
7902 }
7903 }
7904 }
7905 u = result.length;
7906 v = result[u - 1];
7907 while (u-- > 0) {
7908 result[u] = v;
7909 v = p[v];
7910 }
7911 return result;
7912}
7913
7914const isTeleport = (type) => type.__isTeleport;
7915const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
7916const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
7917const resolveTarget = (props, select) => {
7918 const targetSelector = props && props.to;
7919 if (isString(targetSelector)) {
7920 if (!select) {
7921 warn(`Current renderer does not support string target for Teleports. ` +
7922 `(missing querySelector renderer option)`);
7923 return null;
7924 }
7925 else {
7926 const target = select(targetSelector);
7927 if (!target) {
7928 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
7929 `Note the target element must exist before the component is mounted - ` +
7930 `i.e. the target cannot be rendered by the component itself, and ` +
7931 `ideally should be outside of the entire Vue component tree.`);
7932 }
7933 return target;
7934 }
7935 }
7936 else {
7937 if (!targetSelector && !isTeleportDisabled(props)) {
7938 warn(`Invalid Teleport target: ${targetSelector}`);
7939 }
7940 return targetSelector;
7941 }
7942};
7943const TeleportImpl = {
7944 __isTeleport: true,
7945 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
7946 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
7947 const disabled = isTeleportDisabled(n2.props);
7948 let { shapeFlag, children, dynamicChildren } = n2;
7949 // #3302
7950 // HMR updated, force full diff
7951 if (isHmrUpdating) {
7952 optimized = false;
7953 dynamicChildren = null;
7954 }
7955 if (n1 == null) {
7956 // insert anchors in the main view
7957 const placeholder = (n2.el = createComment('teleport start')
7958 );
7959 const mainAnchor = (n2.anchor = createComment('teleport end')
7960 );
7961 insert(placeholder, container, anchor);
7962 insert(mainAnchor, container, anchor);
7963 const target = (n2.target = resolveTarget(n2.props, querySelector));
7964 const targetAnchor = (n2.targetAnchor = createText(''));
7965 if (target) {
7966 insert(targetAnchor, target);
7967 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
7968 isSVG = isSVG || isTargetSVG(target);
7969 }
7970 else if (!disabled) {
7971 warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
7972 }
7973 const mount = (container, anchor) => {
7974 // Teleport *always* has Array children. This is enforced in both the
7975 // compiler and vnode children normalization.
7976 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7977 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7978 }
7979 };
7980 if (disabled) {
7981 mount(container, mainAnchor);
7982 }
7983 else if (target) {
7984 mount(target, targetAnchor);
7985 }
7986 }
7987 else {
7988 // update content
7989 n2.el = n1.el;
7990 const mainAnchor = (n2.anchor = n1.anchor);
7991 const target = (n2.target = n1.target);
7992 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
7993 const wasDisabled = isTeleportDisabled(n1.props);
7994 const currentContainer = wasDisabled ? container : target;
7995 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
7996 isSVG = isSVG || isTargetSVG(target);
7997 if (dynamicChildren) {
7998 // fast path when the teleport happens to be a block root
7999 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
8000 // even in block tree mode we need to make sure all root-level nodes
8001 // in the teleport inherit previous DOM references so that they can
8002 // be moved in future patches.
8003 traverseStaticChildren(n1, n2, true);
8004 }
8005 else if (!optimized) {
8006 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
8007 }
8008 if (disabled) {
8009 if (!wasDisabled) {
8010 // enabled -> disabled
8011 // move into main container
8012 moveTeleport(n2, container, mainAnchor, internals, 1 /* TeleportMoveTypes.TOGGLE */);
8013 }
8014 }
8015 else {
8016 // target changed
8017 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
8018 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
8019 if (nextTarget) {
8020 moveTeleport(n2, nextTarget, null, internals, 0 /* TeleportMoveTypes.TARGET_CHANGE */);
8021 }
8022 else {
8023 warn('Invalid Teleport target on update:', target, `(${typeof target})`);
8024 }
8025 }
8026 else if (wasDisabled) {
8027 // disabled -> enabled
8028 // move into teleport target
8029 moveTeleport(n2, target, targetAnchor, internals, 1 /* TeleportMoveTypes.TOGGLE */);
8030 }
8031 }
8032 }
8033 updateCssVars(n2);
8034 },
8035 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
8036 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
8037 if (target) {
8038 hostRemove(targetAnchor);
8039 }
8040 // an unmounted teleport should always remove its children if not disabled
8041 if (doRemove || !isTeleportDisabled(props)) {
8042 hostRemove(anchor);
8043 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
8044 for (let i = 0; i < children.length; i++) {
8045 const child = children[i];
8046 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
8047 }
8048 }
8049 }
8050 },
8051 move: moveTeleport,
8052 hydrate: hydrateTeleport
8053};
8054function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* TeleportMoveTypes.REORDER */) {
8055 // move target anchor if this is a target change.
8056 if (moveType === 0 /* TeleportMoveTypes.TARGET_CHANGE */) {
8057 insert(vnode.targetAnchor, container, parentAnchor);
8058 }
8059 const { el, anchor, shapeFlag, children, props } = vnode;
8060 const isReorder = moveType === 2 /* TeleportMoveTypes.REORDER */;
8061 // move main view anchor if this is a re-order.
8062 if (isReorder) {
8063 insert(el, container, parentAnchor);
8064 }
8065 // if this is a re-order and teleport is enabled (content is in target)
8066 // do not move children. So the opposite is: only move children if this
8067 // is not a reorder, or the teleport is disabled
8068 if (!isReorder || isTeleportDisabled(props)) {
8069 // Teleport has either Array children or no children.
8070 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
8071 for (let i = 0; i < children.length; i++) {
8072 move(children[i], container, parentAnchor, 2 /* MoveType.REORDER */);
8073 }
8074 }
8075 }
8076 // move main view anchor if this is a re-order.
8077 if (isReorder) {
8078 insert(anchor, container, parentAnchor);
8079 }
8080}
8081function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
8082 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
8083 if (target) {
8084 // if multiple teleports rendered to the same target element, we need to
8085 // pick up from where the last teleport finished instead of the first node
8086 const targetNode = target._lpa || target.firstChild;
8087 if (vnode.shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
8088 if (isTeleportDisabled(vnode.props)) {
8089 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
8090 vnode.targetAnchor = targetNode;
8091 }
8092 else {
8093 vnode.anchor = nextSibling(node);
8094 // lookahead until we find the target anchor
8095 // we cannot rely on return value of hydrateChildren() because there
8096 // could be nested teleports
8097 let targetAnchor = targetNode;
8098 while (targetAnchor) {
8099 targetAnchor = nextSibling(targetAnchor);
8100 if (targetAnchor &&
8101 targetAnchor.nodeType === 8 &&
8102 targetAnchor.data === 'teleport anchor') {
8103 vnode.targetAnchor = targetAnchor;
8104 target._lpa =
8105 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
8106 break;
8107 }
8108 }
8109 hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
8110 }
8111 }
8112 updateCssVars(vnode);
8113 }
8114 return vnode.anchor && nextSibling(vnode.anchor);
8115}
8116// Force-casted public typing for h and TSX props inference
8117const Teleport = TeleportImpl;
8118function updateCssVars(vnode) {
8119 // presence of .ut method indicates owner component uses css vars.
8120 // code path here can assume browser environment.
8121 const ctx = vnode.ctx;
8122 if (ctx && ctx.ut) {
8123 let node = vnode.children[0].el;
8124 while (node !== vnode.targetAnchor) {
8125 if (node.nodeType === 1)
8126 node.setAttribute('data-v-owner', ctx.uid);
8127 node = node.nextSibling;
8128 }
8129 ctx.ut();
8130 }
8131}
8132
8133const Fragment = Symbol('Fragment' );
8134const Text = Symbol('Text' );
8135const Comment = Symbol('Comment' );
8136const Static = Symbol('Static' );
8137// Since v-if and v-for are the two possible ways node structure can dynamically
8138// change, once we consider v-if branches and each v-for fragment a block, we
8139// can divide a template into nested blocks, and within each block the node
8140// structure would be stable. This allows us to skip most children diffing
8141// and only worry about the dynamic nodes (indicated by patch flags).
8142const blockStack = [];
8143let currentBlock = null;
8144/**
8145 * Open a block.
8146 * This must be called before `createBlock`. It cannot be part of `createBlock`
8147 * because the children of the block are evaluated before `createBlock` itself
8148 * is called. The generated code typically looks like this:
8149 *
8150 * ```js
8151 * function render() {
8152 * return (openBlock(),createBlock('div', null, [...]))
8153 * }
8154 * ```
8155 * disableTracking is true when creating a v-for fragment block, since a v-for
8156 * fragment always diffs its children.
8157 *
8158 * @private
8159 */
8160function openBlock(disableTracking = false) {
8161 blockStack.push((currentBlock = disableTracking ? null : []));
8162}
8163function closeBlock() {
8164 blockStack.pop();
8165 currentBlock = blockStack[blockStack.length - 1] || null;
8166}
8167// Whether we should be tracking dynamic child nodes inside a block.
8168// Only tracks when this value is > 0
8169// We are not using a simple boolean because this value may need to be
8170// incremented/decremented by nested usage of v-once (see below)
8171let isBlockTreeEnabled = 1;
8172/**
8173 * Block tracking sometimes needs to be disabled, for example during the
8174 * creation of a tree that needs to be cached by v-once. The compiler generates
8175 * code like this:
8176 *
8177 * ``` js
8178 * _cache[1] || (
8179 * setBlockTracking(-1),
8180 * _cache[1] = createVNode(...),
8181 * setBlockTracking(1),
8182 * _cache[1]
8183 * )
8184 * ```
8185 *
8186 * @private
8187 */
8188function setBlockTracking(value) {
8189 isBlockTreeEnabled += value;
8190}
8191function setupBlock(vnode) {
8192 // save current block children on the block vnode
8193 vnode.dynamicChildren =
8194 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
8195 // close block
8196 closeBlock();
8197 // a block is always going to be patched, so track it as a child of its
8198 // parent block
8199 if (isBlockTreeEnabled > 0 && currentBlock) {
8200 currentBlock.push(vnode);
8201 }
8202 return vnode;
8203}
8204/**
8205 * @private
8206 */
8207function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
8208 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
8209}
8210/**
8211 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
8212 * A block root keeps track of dynamic nodes within the block in the
8213 * `dynamicChildren` array.
8214 *
8215 * @private
8216 */
8217function createBlock(type, props, children, patchFlag, dynamicProps) {
8218 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
8219}
8220function isVNode(value) {
8221 return value ? value.__v_isVNode === true : false;
8222}
8223function isSameVNodeType(n1, n2) {
8224 if (n2.shapeFlag & 6 /* ShapeFlags.COMPONENT */ &&
8225 hmrDirtyComponents.has(n2.type)) {
8226 // #7042, ensure the vnode being unmounted during HMR
8227 // bitwise operations to remove keep alive flags
8228 n1.shapeFlag &= ~256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */;
8229 n2.shapeFlag &= ~512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */;
8230 // HMR only: if the component has been hot-updated, force a reload.
8231 return false;
8232 }
8233 return n1.type === n2.type && n1.key === n2.key;
8234}
8235let vnodeArgsTransformer;
8236/**
8237 * Internal API for registering an arguments transform for createVNode
8238 * used for creating stubs in the test-utils
8239 * It is *internal* but needs to be exposed for test-utils to pick up proper
8240 * typings
8241 */
8242function transformVNodeArgs(transformer) {
8243 vnodeArgsTransformer = transformer;
8244}
8245const createVNodeWithArgsTransform = (...args) => {
8246 return _createVNode(...(vnodeArgsTransformer
8247 ? vnodeArgsTransformer(args, currentRenderingInstance)
8248 : args));
8249};
8250const InternalObjectKey = `__vInternal`;
8251const normalizeKey = ({ key }) => key != null ? key : null;
8252const normalizeRef = ({ ref, ref_key, ref_for }) => {
8253 return (ref != null
8254 ? isString(ref) || isRef(ref) || isFunction(ref)
8255 ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8256 : ref
8257 : null);
8258};
8259function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ShapeFlags.ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
8260 const vnode = {
8261 __v_isVNode: true,
8262 __v_skip: true,
8263 type,
8264 props,
8265 key: props && normalizeKey(props),
8266 ref: props && normalizeRef(props),
8267 scopeId: currentScopeId,
8268 slotScopeIds: null,
8269 children,
8270 component: null,
8271 suspense: null,
8272 ssContent: null,
8273 ssFallback: null,
8274 dirs: null,
8275 transition: null,
8276 el: null,
8277 anchor: null,
8278 target: null,
8279 targetAnchor: null,
8280 staticCount: 0,
8281 shapeFlag,
8282 patchFlag,
8283 dynamicProps,
8284 dynamicChildren: null,
8285 appContext: null,
8286 ctx: currentRenderingInstance
8287 };
8288 if (needFullChildrenNormalization) {
8289 normalizeChildren(vnode, children);
8290 // normalize suspense children
8291 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
8292 type.normalize(vnode);
8293 }
8294 }
8295 else if (children) {
8296 // compiled element vnode - if children is passed, only possible types are
8297 // string or Array.
8298 vnode.shapeFlag |= isString(children)
8299 ? 8 /* ShapeFlags.TEXT_CHILDREN */
8300 : 16 /* ShapeFlags.ARRAY_CHILDREN */;
8301 }
8302 // validate key
8303 if (vnode.key !== vnode.key) {
8304 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
8305 }
8306 // track vnode for block tree
8307 if (isBlockTreeEnabled > 0 &&
8308 // avoid a block node from tracking itself
8309 !isBlockNode &&
8310 // has current parent block
8311 currentBlock &&
8312 // presence of a patch flag indicates this node needs patching on updates.
8313 // component nodes also should always be patched, because even if the
8314 // component doesn't need to update, it needs to persist the instance on to
8315 // the next vnode so that it can be properly unmounted later.
8316 (vnode.patchFlag > 0 || shapeFlag & 6 /* ShapeFlags.COMPONENT */) &&
8317 // the EVENTS flag is only for hydration and if it is the only flag, the
8318 // vnode should not be considered dynamic due to handler caching.
8319 vnode.patchFlag !== 32 /* PatchFlags.HYDRATE_EVENTS */) {
8320 currentBlock.push(vnode);
8321 }
8322 return vnode;
8323}
8324const createVNode = (createVNodeWithArgsTransform );
8325function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
8326 if (!type || type === NULL_DYNAMIC_COMPONENT) {
8327 if (!type) {
8328 warn(`Invalid vnode type when creating vnode: ${type}.`);
8329 }
8330 type = Comment;
8331 }
8332 if (isVNode(type)) {
8333 // createVNode receiving an existing vnode. This happens in cases like
8334 // <component :is="vnode"/>
8335 // #2078 make sure to merge refs during the clone instead of overwriting it
8336 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
8337 if (children) {
8338 normalizeChildren(cloned, children);
8339 }
8340 if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) {
8341 if (cloned.shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
8342 currentBlock[currentBlock.indexOf(type)] = cloned;
8343 }
8344 else {
8345 currentBlock.push(cloned);
8346 }
8347 }
8348 cloned.patchFlag |= -2 /* PatchFlags.BAIL */;
8349 return cloned;
8350 }
8351 // class component normalization.
8352 if (isClassComponent(type)) {
8353 type = type.__vccOpts;
8354 }
8355 // class & style normalization.
8356 if (props) {
8357 // for reactive or proxy objects, we need to clone it to enable mutation.
8358 props = guardReactiveProps(props);
8359 let { class: klass, style } = props;
8360 if (klass && !isString(klass)) {
8361 props.class = normalizeClass(klass);
8362 }
8363 if (isObject(style)) {
8364 // reactive state objects need to be cloned since they are likely to be
8365 // mutated
8366 if (isProxy(style) && !isArray(style)) {
8367 style = extend({}, style);
8368 }
8369 props.style = normalizeStyle(style);
8370 }
8371 }
8372 // encode the vnode type information into a bitmap
8373 const shapeFlag = isString(type)
8374 ? 1 /* ShapeFlags.ELEMENT */
8375 : isSuspense(type)
8376 ? 128 /* ShapeFlags.SUSPENSE */
8377 : isTeleport(type)
8378 ? 64 /* ShapeFlags.TELEPORT */
8379 : isObject(type)
8380 ? 4 /* ShapeFlags.STATEFUL_COMPONENT */
8381 : isFunction(type)
8382 ? 2 /* ShapeFlags.FUNCTIONAL_COMPONENT */
8383 : 0;
8384 if (shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */ && isProxy(type)) {
8385 type = toRaw(type);
8386 warn(`Vue received a Component which was made a reactive object. This can ` +
8387 `lead to unnecessary performance overhead, and should be avoided by ` +
8388 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
8389 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
8390 }
8391 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
8392}
8393function guardReactiveProps(props) {
8394 if (!props)
8395 return null;
8396 return isProxy(props) || InternalObjectKey in props
8397 ? extend({}, props)
8398 : props;
8399}
8400function cloneVNode(vnode, extraProps, mergeRef = false) {
8401 // This is intentionally NOT using spread or extend to avoid the runtime
8402 // key enumeration cost.
8403 const { props, ref, patchFlag, children } = vnode;
8404 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
8405 const cloned = {
8406 __v_isVNode: true,
8407 __v_skip: true,
8408 type: vnode.type,
8409 props: mergedProps,
8410 key: mergedProps && normalizeKey(mergedProps),
8411 ref: extraProps && extraProps.ref
8412 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
8413 // if the vnode itself already has a ref, cloneVNode will need to merge
8414 // the refs so the single vnode can be set on multiple refs
8415 mergeRef && ref
8416 ? isArray(ref)
8417 ? ref.concat(normalizeRef(extraProps))
8418 : [ref, normalizeRef(extraProps)]
8419 : normalizeRef(extraProps)
8420 : ref,
8421 scopeId: vnode.scopeId,
8422 slotScopeIds: vnode.slotScopeIds,
8423 children: patchFlag === -1 /* PatchFlags.HOISTED */ && isArray(children)
8424 ? children.map(deepCloneVNode)
8425 : children,
8426 target: vnode.target,
8427 targetAnchor: vnode.targetAnchor,
8428 staticCount: vnode.staticCount,
8429 shapeFlag: vnode.shapeFlag,
8430 // if the vnode is cloned with extra props, we can no longer assume its
8431 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
8432 // note: preserve flag for fragments since they use the flag for children
8433 // fast paths only.
8434 patchFlag: extraProps && vnode.type !== Fragment
8435 ? patchFlag === -1 // hoisted node
8436 ? 16 /* PatchFlags.FULL_PROPS */
8437 : patchFlag | 16 /* PatchFlags.FULL_PROPS */
8438 : patchFlag,
8439 dynamicProps: vnode.dynamicProps,
8440 dynamicChildren: vnode.dynamicChildren,
8441 appContext: vnode.appContext,
8442 dirs: vnode.dirs,
8443 transition: vnode.transition,
8444 // These should technically only be non-null on mounted VNodes. However,
8445 // they *should* be copied for kept-alive vnodes. So we just always copy
8446 // them since them being non-null during a mount doesn't affect the logic as
8447 // they will simply be overwritten.
8448 component: vnode.component,
8449 suspense: vnode.suspense,
8450 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
8451 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
8452 el: vnode.el,
8453 anchor: vnode.anchor,
8454 ctx: vnode.ctx,
8455 ce: vnode.ce
8456 };
8457 return cloned;
8458}
8459/**
8460 * Dev only, for HMR of hoisted vnodes reused in v-for
8461 * https://github.com/vitejs/vite/issues/2022
8462 */
8463function deepCloneVNode(vnode) {
8464 const cloned = cloneVNode(vnode);
8465 if (isArray(vnode.children)) {
8466 cloned.children = vnode.children.map(deepCloneVNode);
8467 }
8468 return cloned;
8469}
8470/**
8471 * @private
8472 */
8473function createTextVNode(text = ' ', flag = 0) {
8474 return createVNode(Text, null, text, flag);
8475}
8476/**
8477 * @private
8478 */
8479function createStaticVNode(content, numberOfNodes) {
8480 // A static vnode can contain multiple stringified elements, and the number
8481 // of elements is necessary for hydration.
8482 const vnode = createVNode(Static, null, content);
8483 vnode.staticCount = numberOfNodes;
8484 return vnode;
8485}
8486/**
8487 * @private
8488 */
8489function createCommentVNode(text = '',
8490// when used as the v-else branch, the comment node must be created as a
8491// block to ensure correct updates.
8492asBlock = false) {
8493 return asBlock
8494 ? (openBlock(), createBlock(Comment, null, text))
8495 : createVNode(Comment, null, text);
8496}
8497function normalizeVNode(child) {
8498 if (child == null || typeof child === 'boolean') {
8499 // empty placeholder
8500 return createVNode(Comment);
8501 }
8502 else if (isArray(child)) {
8503 // fragment
8504 return createVNode(Fragment, null,
8505 // #3666, avoid reference pollution when reusing vnode
8506 child.slice());
8507 }
8508 else if (typeof child === 'object') {
8509 // already vnode, this should be the most common since compiled templates
8510 // always produce all-vnode children arrays
8511 return cloneIfMounted(child);
8512 }
8513 else {
8514 // strings and numbers
8515 return createVNode(Text, null, String(child));
8516 }
8517}
8518// optimized normalization for template-compiled render fns
8519function cloneIfMounted(child) {
8520 return (child.el === null && child.patchFlag !== -1 /* PatchFlags.HOISTED */) ||
8521 child.memo
8522 ? child
8523 : cloneVNode(child);
8524}
8525function normalizeChildren(vnode, children) {
8526 let type = 0;
8527 const { shapeFlag } = vnode;
8528 if (children == null) {
8529 children = null;
8530 }
8531 else if (isArray(children)) {
8532 type = 16 /* ShapeFlags.ARRAY_CHILDREN */;
8533 }
8534 else if (typeof children === 'object') {
8535 if (shapeFlag & (1 /* ShapeFlags.ELEMENT */ | 64 /* ShapeFlags.TELEPORT */)) {
8536 // Normalize slot to plain children for plain element and Teleport
8537 const slot = children.default;
8538 if (slot) {
8539 // _c marker is added by withCtx() indicating this is a compiled slot
8540 slot._c && (slot._d = false);
8541 normalizeChildren(vnode, slot());
8542 slot._c && (slot._d = true);
8543 }
8544 return;
8545 }
8546 else {
8547 type = 32 /* ShapeFlags.SLOTS_CHILDREN */;
8548 const slotFlag = children._;
8549 if (!slotFlag && !(InternalObjectKey in children)) {
8550 children._ctx = currentRenderingInstance;
8551 }
8552 else if (slotFlag === 3 /* SlotFlags.FORWARDED */ && currentRenderingInstance) {
8553 // a child component receives forwarded slots from the parent.
8554 // its slot type is determined by its parent's slot type.
8555 if (currentRenderingInstance.slots._ === 1 /* SlotFlags.STABLE */) {
8556 children._ = 1 /* SlotFlags.STABLE */;
8557 }
8558 else {
8559 children._ = 2 /* SlotFlags.DYNAMIC */;
8560 vnode.patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */;
8561 }
8562 }
8563 }
8564 }
8565 else if (isFunction(children)) {
8566 children = { default: children, _ctx: currentRenderingInstance };
8567 type = 32 /* ShapeFlags.SLOTS_CHILDREN */;
8568 }
8569 else {
8570 children = String(children);
8571 // force teleport children to array so it can be moved around
8572 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
8573 type = 16 /* ShapeFlags.ARRAY_CHILDREN */;
8574 children = [createTextVNode(children)];
8575 }
8576 else {
8577 type = 8 /* ShapeFlags.TEXT_CHILDREN */;
8578 }
8579 }
8580 vnode.children = children;
8581 vnode.shapeFlag |= type;
8582}
8583function mergeProps(...args) {
8584 const ret = {};
8585 for (let i = 0; i < args.length; i++) {
8586 const toMerge = args[i];
8587 for (const key in toMerge) {
8588 if (key === 'class') {
8589 if (ret.class !== toMerge.class) {
8590 ret.class = normalizeClass([ret.class, toMerge.class]);
8591 }
8592 }
8593 else if (key === 'style') {
8594 ret.style = normalizeStyle([ret.style, toMerge.style]);
8595 }
8596 else if (isOn(key)) {
8597 const existing = ret[key];
8598 const incoming = toMerge[key];
8599 if (incoming &&
8600 existing !== incoming &&
8601 !(isArray(existing) && existing.includes(incoming))) {
8602 ret[key] = existing
8603 ? [].concat(existing, incoming)
8604 : incoming;
8605 }
8606 }
8607 else if (key !== '') {
8608 ret[key] = toMerge[key];
8609 }
8610 }
8611 }
8612 return ret;
8613}
8614function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8615 callWithAsyncErrorHandling(hook, instance, 7 /* ErrorCodes.VNODE_HOOK */, [
8616 vnode,
8617 prevVNode
8618 ]);
8619}
8620
8621const emptyAppContext = createAppContext();
8622let uid = 0;
8623function createComponentInstance(vnode, parent, suspense) {
8624 const type = vnode.type;
8625 // inherit parent app context - or - if root, adopt from root vnode
8626 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
8627 const instance = {
8628 uid: uid++,
8629 vnode,
8630 type,
8631 parent,
8632 appContext,
8633 root: null,
8634 next: null,
8635 subTree: null,
8636 effect: null,
8637 update: null,
8638 scope: new EffectScope(true /* detached */),
8639 render: null,
8640 proxy: null,
8641 exposed: null,
8642 exposeProxy: null,
8643 withProxy: null,
8644 provides: parent ? parent.provides : Object.create(appContext.provides),
8645 accessCache: null,
8646 renderCache: [],
8647 // local resolved assets
8648 components: null,
8649 directives: null,
8650 // resolved props and emits options
8651 propsOptions: normalizePropsOptions(type, appContext),
8652 emitsOptions: normalizeEmitsOptions(type, appContext),
8653 // emit
8654 emit: null,
8655 emitted: null,
8656 // props default value
8657 propsDefaults: EMPTY_OBJ,
8658 // inheritAttrs
8659 inheritAttrs: type.inheritAttrs,
8660 // state
8661 ctx: EMPTY_OBJ,
8662 data: EMPTY_OBJ,
8663 props: EMPTY_OBJ,
8664 attrs: EMPTY_OBJ,
8665 slots: EMPTY_OBJ,
8666 refs: EMPTY_OBJ,
8667 setupState: EMPTY_OBJ,
8668 setupContext: null,
8669 // suspense related
8670 suspense,
8671 suspenseId: suspense ? suspense.pendingId : 0,
8672 asyncDep: null,
8673 asyncResolved: false,
8674 // lifecycle hooks
8675 // not using enums here because it results in computed properties
8676 isMounted: false,
8677 isUnmounted: false,
8678 isDeactivated: false,
8679 bc: null,
8680 c: null,
8681 bm: null,
8682 m: null,
8683 bu: null,
8684 u: null,
8685 um: null,
8686 bum: null,
8687 da: null,
8688 a: null,
8689 rtg: null,
8690 rtc: null,
8691 ec: null,
8692 sp: null
8693 };
8694 {
8695 instance.ctx = createDevRenderContext(instance);
8696 }
8697 instance.root = parent ? parent.root : instance;
8698 instance.emit = emit.bind(null, instance);
8699 // apply custom element special handling
8700 if (vnode.ce) {
8701 vnode.ce(instance);
8702 }
8703 return instance;
8704}
8705let currentInstance = null;
8706const getCurrentInstance = () => currentInstance || currentRenderingInstance;
8707const setCurrentInstance = (instance) => {
8708 currentInstance = instance;
8709 instance.scope.on();
8710};
8711const unsetCurrentInstance = () => {
8712 currentInstance && currentInstance.scope.off();
8713 currentInstance = null;
8714};
8715const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
8716function validateComponentName(name, config) {
8717 const appIsNativeTag = config.isNativeTag || NO;
8718 if (isBuiltInTag(name) || appIsNativeTag(name)) {
8719 warn('Do not use built-in or reserved HTML elements as component id: ' + name);
8720 }
8721}
8722function isStatefulComponent(instance) {
8723 return instance.vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */;
8724}
8725let isInSSRComponentSetup = false;
8726function setupComponent(instance, isSSR = false) {
8727 isInSSRComponentSetup = isSSR;
8728 const { props, children } = instance.vnode;
8729 const isStateful = isStatefulComponent(instance);
8730 initProps(instance, props, isStateful, isSSR);
8731 initSlots(instance, children);
8732 const setupResult = isStateful
8733 ? setupStatefulComponent(instance, isSSR)
8734 : undefined;
8735 isInSSRComponentSetup = false;
8736 return setupResult;
8737}
8738function setupStatefulComponent(instance, isSSR) {
8739 var _a;
8740 const Component = instance.type;
8741 {
8742 if (Component.name) {
8743 validateComponentName(Component.name, instance.appContext.config);
8744 }
8745 if (Component.components) {
8746 const names = Object.keys(Component.components);
8747 for (let i = 0; i < names.length; i++) {
8748 validateComponentName(names[i], instance.appContext.config);
8749 }
8750 }
8751 if (Component.directives) {
8752 const names = Object.keys(Component.directives);
8753 for (let i = 0; i < names.length; i++) {
8754 validateDirectiveName(names[i]);
8755 }
8756 }
8757 if (Component.compilerOptions && isRuntimeOnly()) {
8758 warn(`"compilerOptions" is only supported when using a build of Vue that ` +
8759 `includes the runtime compiler. Since you are using a runtime-only ` +
8760 `build, the options should be passed via your build tool config instead.`);
8761 }
8762 }
8763 // 0. create render proxy property access cache
8764 instance.accessCache = Object.create(null);
8765 // 1. create public instance / render proxy
8766 // also mark it raw so it's never observed
8767 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
8768 {
8769 exposePropsOnRenderContext(instance);
8770 }
8771 // 2. call setup()
8772 const { setup } = Component;
8773 if (setup) {
8774 const setupContext = (instance.setupContext =
8775 setup.length > 1 ? createSetupContext(instance) : null);
8776 setCurrentInstance(instance);
8777 pauseTracking();
8778 const setupResult = callWithErrorHandling(setup, instance, 0 /* ErrorCodes.SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
8779 resetTracking();
8780 unsetCurrentInstance();
8781 if (isPromise(setupResult)) {
8782 setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
8783 if (isSSR) {
8784 // return the promise so server-renderer can wait on it
8785 return setupResult
8786 .then((resolvedResult) => {
8787 handleSetupResult(instance, resolvedResult, isSSR);
8788 })
8789 .catch(e => {
8790 handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
8791 });
8792 }
8793 else {
8794 // async setup returned Promise.
8795 // bail here and wait for re-entry.
8796 instance.asyncDep = setupResult;
8797 if (!instance.suspense) {
8798 const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
8799 warn(`Component <${name}>: setup function returned a promise, but no ` +
8800 `<Suspense> boundary was found in the parent component tree. ` +
8801 `A component with async setup() must be nested in a <Suspense> ` +
8802 `in order to be rendered.`);
8803 }
8804 }
8805 }
8806 else {
8807 handleSetupResult(instance, setupResult, isSSR);
8808 }
8809 }
8810 else {
8811 finishComponentSetup(instance, isSSR);
8812 }
8813}
8814function handleSetupResult(instance, setupResult, isSSR) {
8815 if (isFunction(setupResult)) {
8816 // setup returned an inline render function
8817 {
8818 instance.render = setupResult;
8819 }
8820 }
8821 else if (isObject(setupResult)) {
8822 if (isVNode(setupResult)) {
8823 warn(`setup() should not return VNodes directly - ` +
8824 `return a render function instead.`);
8825 }
8826 // setup returned bindings.
8827 // assuming a render function compiled from template is present.
8828 {
8829 instance.devtoolsRawSetupState = setupResult;
8830 }
8831 instance.setupState = proxyRefs(setupResult);
8832 {
8833 exposeSetupStateOnRenderContext(instance);
8834 }
8835 }
8836 else if (setupResult !== undefined) {
8837 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
8838 }
8839 finishComponentSetup(instance, isSSR);
8840}
8841let compile$1;
8842let installWithProxy;
8843/**
8844 * For runtime-dom to register the compiler.
8845 * Note the exported method uses any to avoid d.ts relying on the compiler types.
8846 */
8847function registerRuntimeCompiler(_compile) {
8848 compile$1 = _compile;
8849 installWithProxy = i => {
8850 if (i.render._rc) {
8851 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
8852 }
8853 };
8854}
8855// dev only
8856const isRuntimeOnly = () => !compile$1;
8857function finishComponentSetup(instance, isSSR, skipOptions) {
8858 const Component = instance.type;
8859 // template / render function normalization
8860 // could be already set when returned from setup()
8861 if (!instance.render) {
8862 // only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
8863 // is done by server-renderer
8864 if (!isSSR && compile$1 && !Component.render) {
8865 const template = Component.template ||
8866 resolveMergedOptions(instance).template;
8867 if (template) {
8868 {
8869 startMeasure(instance, `compile`);
8870 }
8871 const { isCustomElement, compilerOptions } = instance.appContext.config;
8872 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
8873 const finalCompilerOptions = extend(extend({
8874 isCustomElement,
8875 delimiters
8876 }, compilerOptions), componentCompilerOptions);
8877 Component.render = compile$1(template, finalCompilerOptions);
8878 {
8879 endMeasure(instance, `compile`);
8880 }
8881 }
8882 }
8883 instance.render = (Component.render || NOOP);
8884 // for runtime-compiled render functions using `with` blocks, the render
8885 // proxy used needs a different `has` handler which is more performant and
8886 // also only allows a whitelist of globals to fallthrough.
8887 if (installWithProxy) {
8888 installWithProxy(instance);
8889 }
8890 }
8891 // support for 2.x options
8892 {
8893 setCurrentInstance(instance);
8894 pauseTracking();
8895 applyOptions(instance);
8896 resetTracking();
8897 unsetCurrentInstance();
8898 }
8899 // warn missing template/render
8900 // the runtime compilation of template in SSR is done by server-render
8901 if (!Component.render && instance.render === NOOP && !isSSR) {
8902 /* istanbul ignore if */
8903 if (!compile$1 && Component.template) {
8904 warn(`Component provided template option but ` +
8905 `runtime compilation is not supported in this build of Vue.` +
8906 (` Use "vue.esm-browser.js" instead.`
8907 ) /* should not happen */);
8908 }
8909 else {
8910 warn(`Component is missing template or render function.`);
8911 }
8912 }
8913}
8914function createAttrsProxy(instance) {
8915 return new Proxy(instance.attrs, {
8916 get(target, key) {
8917 markAttrsAccessed();
8918 track(instance, "get" /* TrackOpTypes.GET */, '$attrs');
8919 return target[key];
8920 },
8921 set() {
8922 warn(`setupContext.attrs is readonly.`);
8923 return false;
8924 },
8925 deleteProperty() {
8926 warn(`setupContext.attrs is readonly.`);
8927 return false;
8928 }
8929 }
8930 );
8931}
8932function createSetupContext(instance) {
8933 const expose = exposed => {
8934 {
8935 if (instance.exposed) {
8936 warn(`expose() should be called only once per setup().`);
8937 }
8938 if (exposed != null) {
8939 let exposedType = typeof exposed;
8940 if (exposedType === 'object') {
8941 if (isArray(exposed)) {
8942 exposedType = 'array';
8943 }
8944 else if (isRef(exposed)) {
8945 exposedType = 'ref';
8946 }
8947 }
8948 if (exposedType !== 'object') {
8949 warn(`expose() should be passed a plain object, received ${exposedType}.`);
8950 }
8951 }
8952 }
8953 instance.exposed = exposed || {};
8954 };
8955 let attrs;
8956 {
8957 // We use getters in dev in case libs like test-utils overwrite instance
8958 // properties (overwrites should not be done in prod)
8959 return Object.freeze({
8960 get attrs() {
8961 return attrs || (attrs = createAttrsProxy(instance));
8962 },
8963 get slots() {
8964 return shallowReadonly(instance.slots);
8965 },
8966 get emit() {
8967 return (event, ...args) => instance.emit(event, ...args);
8968 },
8969 expose
8970 });
8971 }
8972}
8973function getExposeProxy(instance) {
8974 if (instance.exposed) {
8975 return (instance.exposeProxy ||
8976 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
8977 get(target, key) {
8978 if (key in target) {
8979 return target[key];
8980 }
8981 else if (key in publicPropertiesMap) {
8982 return publicPropertiesMap[key](instance);
8983 }
8984 },
8985 has(target, key) {
8986 return key in target || key in publicPropertiesMap;
8987 }
8988 })));
8989 }
8990}
8991const classifyRE = /(?:^|[-_])(\w)/g;
8992const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
8993function getComponentName(Component, includeInferred = true) {
8994 return isFunction(Component)
8995 ? Component.displayName || Component.name
8996 : Component.name || (includeInferred && Component.__name);
8997}
8998/* istanbul ignore next */
8999function formatComponentName(instance, Component, isRoot = false) {
9000 let name = getComponentName(Component);
9001 if (!name && Component.__file) {
9002 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
9003 if (match) {
9004 name = match[1];
9005 }
9006 }
9007 if (!name && instance && instance.parent) {
9008 // try to infer the name based on reverse resolution
9009 const inferFromRegistry = (registry) => {
9010 for (const key in registry) {
9011 if (registry[key] === Component) {
9012 return key;
9013 }
9014 }
9015 };
9016 name =
9017 inferFromRegistry(instance.components ||
9018 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
9019 }
9020 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
9021}
9022function isClassComponent(value) {
9023 return isFunction(value) && '__vccOpts' in value;
9024}
9025
9026const computed = ((getterOrOptions, debugOptions) => {
9027 // @ts-ignore
9028 return computed$1(getterOrOptions, debugOptions, isInSSRComponentSetup);
9029});
9030
9031// dev only
9032const warnRuntimeUsage = (method) => warn(`${method}() is a compiler-hint helper that is only usable inside ` +
9033 `<script setup> of a single file component. Its arguments should be ` +
9034 `compiled away and passing it at runtime has no effect.`);
9035// implementation
9036function defineProps() {
9037 {
9038 warnRuntimeUsage(`defineProps`);
9039 }
9040 return null;
9041}
9042// implementation
9043function defineEmits() {
9044 {
9045 warnRuntimeUsage(`defineEmits`);
9046 }
9047 return null;
9048}
9049/**
9050 * Vue `<script setup>` compiler macro for declaring a component's exposed
9051 * instance properties when it is accessed by a parent component via template
9052 * refs.
9053 *
9054 * `<script setup>` components are closed by default - i.e. variables inside
9055 * the `<script setup>` scope is not exposed to parent unless explicitly exposed
9056 * via `defineExpose`.
9057 *
9058 * This is only usable inside `<script setup>`, is compiled away in the
9059 * output and should **not** be actually called at runtime.
9060 */
9061function defineExpose(exposed) {
9062 {
9063 warnRuntimeUsage(`defineExpose`);
9064 }
9065}
9066/**
9067 * Vue `<script setup>` compiler macro for providing props default values when
9068 * using type-based `defineProps` declaration.
9069 *
9070 * Example usage:
9071 * ```ts
9072 * withDefaults(defineProps<{
9073 * size?: number
9074 * labels?: string[]
9075 * }>(), {
9076 * size: 3,
9077 * labels: () => ['default label']
9078 * })
9079 * ```
9080 *
9081 * This is only usable inside `<script setup>`, is compiled away in the output
9082 * and should **not** be actually called at runtime.
9083 */
9084function withDefaults(props, defaults) {
9085 {
9086 warnRuntimeUsage(`withDefaults`);
9087 }
9088 return null;
9089}
9090function useSlots() {
9091 return getContext().slots;
9092}
9093function useAttrs() {
9094 return getContext().attrs;
9095}
9096function getContext() {
9097 const i = getCurrentInstance();
9098 if (!i) {
9099 warn(`useContext() called without active instance.`);
9100 }
9101 return i.setupContext || (i.setupContext = createSetupContext(i));
9102}
9103/**
9104 * Runtime helper for merging default declarations. Imported by compiled code
9105 * only.
9106 * @internal
9107 */
9108function mergeDefaults(raw, defaults) {
9109 const props = isArray(raw)
9110 ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {})
9111 : raw;
9112 for (const key in defaults) {
9113 const opt = props[key];
9114 if (opt) {
9115 if (isArray(opt) || isFunction(opt)) {
9116 props[key] = { type: opt, default: defaults[key] };
9117 }
9118 else {
9119 opt.default = defaults[key];
9120 }
9121 }
9122 else if (opt === null) {
9123 props[key] = { default: defaults[key] };
9124 }
9125 else {
9126 warn(`props default key "${key}" has no corresponding declaration.`);
9127 }
9128 }
9129 return props;
9130}
9131/**
9132 * Used to create a proxy for the rest element when destructuring props with
9133 * defineProps().
9134 * @internal
9135 */
9136function createPropsRestProxy(props, excludedKeys) {
9137 const ret = {};
9138 for (const key in props) {
9139 if (!excludedKeys.includes(key)) {
9140 Object.defineProperty(ret, key, {
9141 enumerable: true,
9142 get: () => props[key]
9143 });
9144 }
9145 }
9146 return ret;
9147}
9148/**
9149 * `<script setup>` helper for persisting the current instance context over
9150 * async/await flows.
9151 *
9152 * `@vue/compiler-sfc` converts the following:
9153 *
9154 * ```ts
9155 * const x = await foo()
9156 * ```
9157 *
9158 * into:
9159 *
9160 * ```ts
9161 * let __temp, __restore
9162 * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
9163 * ```
9164 * @internal
9165 */
9166function withAsyncContext(getAwaitable) {
9167 const ctx = getCurrentInstance();
9168 if (!ctx) {
9169 warn(`withAsyncContext called without active current instance. ` +
9170 `This is likely a bug.`);
9171 }
9172 let awaitable = getAwaitable();
9173 unsetCurrentInstance();
9174 if (isPromise(awaitable)) {
9175 awaitable = awaitable.catch(e => {
9176 setCurrentInstance(ctx);
9177 throw e;
9178 });
9179 }
9180 return [awaitable, () => setCurrentInstance(ctx)];
9181}
9182
9183// Actual implementation
9184function h(type, propsOrChildren, children) {
9185 const l = arguments.length;
9186 if (l === 2) {
9187 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
9188 // single vnode without props
9189 if (isVNode(propsOrChildren)) {
9190 return createVNode(type, null, [propsOrChildren]);
9191 }
9192 // props without children
9193 return createVNode(type, propsOrChildren);
9194 }
9195 else {
9196 // omit props
9197 return createVNode(type, null, propsOrChildren);
9198 }
9199 }
9200 else {
9201 if (l > 3) {
9202 children = Array.prototype.slice.call(arguments, 2);
9203 }
9204 else if (l === 3 && isVNode(children)) {
9205 children = [children];
9206 }
9207 return createVNode(type, propsOrChildren, children);
9208 }
9209}
9210
9211const ssrContextKey = Symbol(`ssrContext` );
9212const useSSRContext = () => {
9213 {
9214 const ctx = inject(ssrContextKey);
9215 if (!ctx) {
9216 warn(`Server rendering context not provided. Make sure to only call ` +
9217 `useSSRContext() conditionally in the server build.`);
9218 }
9219 return ctx;
9220 }
9221};
9222
9223function initCustomFormatter() {
9224 /* eslint-disable no-restricted-globals */
9225 if (typeof window === 'undefined') {
9226 return;
9227 }
9228 const vueStyle = { style: 'color:#3ba776' };
9229 const numberStyle = { style: 'color:#0b1bc9' };
9230 const stringStyle = { style: 'color:#b62e24' };
9231 const keywordStyle = { style: 'color:#9d288c' };
9232 // custom formatter for Chrome
9233 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
9234 const formatter = {
9235 header(obj) {
9236 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
9237 if (!isObject(obj)) {
9238 return null;
9239 }
9240 if (obj.__isVue) {
9241 return ['div', vueStyle, `VueInstance`];
9242 }
9243 else if (isRef(obj)) {
9244 return [
9245 'div',
9246 {},
9247 ['span', vueStyle, genRefFlag(obj)],
9248 '<',
9249 formatValue(obj.value),
9250 `>`
9251 ];
9252 }
9253 else if (isReactive(obj)) {
9254 return [
9255 'div',
9256 {},
9257 ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
9258 '<',
9259 formatValue(obj),
9260 `>${isReadonly(obj) ? ` (readonly)` : ``}`
9261 ];
9262 }
9263 else if (isReadonly(obj)) {
9264 return [
9265 'div',
9266 {},
9267 ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
9268 '<',
9269 formatValue(obj),
9270 '>'
9271 ];
9272 }
9273 return null;
9274 },
9275 hasBody(obj) {
9276 return obj && obj.__isVue;
9277 },
9278 body(obj) {
9279 if (obj && obj.__isVue) {
9280 return [
9281 'div',
9282 {},
9283 ...formatInstance(obj.$)
9284 ];
9285 }
9286 }
9287 };
9288 function formatInstance(instance) {
9289 const blocks = [];
9290 if (instance.type.props && instance.props) {
9291 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
9292 }
9293 if (instance.setupState !== EMPTY_OBJ) {
9294 blocks.push(createInstanceBlock('setup', instance.setupState));
9295 }
9296 if (instance.data !== EMPTY_OBJ) {
9297 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
9298 }
9299 const computed = extractKeys(instance, 'computed');
9300 if (computed) {
9301 blocks.push(createInstanceBlock('computed', computed));
9302 }
9303 const injected = extractKeys(instance, 'inject');
9304 if (injected) {
9305 blocks.push(createInstanceBlock('injected', injected));
9306 }
9307 blocks.push([
9308 'div',
9309 {},
9310 [
9311 'span',
9312 {
9313 style: keywordStyle.style + ';opacity:0.66'
9314 },
9315 '$ (internal): '
9316 ],
9317 ['object', { object: instance }]
9318 ]);
9319 return blocks;
9320 }
9321 function createInstanceBlock(type, target) {
9322 target = extend({}, target);
9323 if (!Object.keys(target).length) {
9324 return ['span', {}];
9325 }
9326 return [
9327 'div',
9328 { style: 'line-height:1.25em;margin-bottom:0.6em' },
9329 [
9330 'div',
9331 {
9332 style: 'color:#476582'
9333 },
9334 type
9335 ],
9336 [
9337 'div',
9338 {
9339 style: 'padding-left:1.25em'
9340 },
9341 ...Object.keys(target).map(key => {
9342 return [
9343 'div',
9344 {},
9345 ['span', keywordStyle, key + ': '],
9346 formatValue(target[key], false)
9347 ];
9348 })
9349 ]
9350 ];
9351 }
9352 function formatValue(v, asRaw = true) {
9353 if (typeof v === 'number') {
9354 return ['span', numberStyle, v];
9355 }
9356 else if (typeof v === 'string') {
9357 return ['span', stringStyle, JSON.stringify(v)];
9358 }
9359 else if (typeof v === 'boolean') {
9360 return ['span', keywordStyle, v];
9361 }
9362 else if (isObject(v)) {
9363 return ['object', { object: asRaw ? toRaw(v) : v }];
9364 }
9365 else {
9366 return ['span', stringStyle, String(v)];
9367 }
9368 }
9369 function extractKeys(instance, type) {
9370 const Comp = instance.type;
9371 if (isFunction(Comp)) {
9372 return;
9373 }
9374 const extracted = {};
9375 for (const key in instance.ctx) {
9376 if (isKeyOfType(Comp, key, type)) {
9377 extracted[key] = instance.ctx[key];
9378 }
9379 }
9380 return extracted;
9381 }
9382 function isKeyOfType(Comp, key, type) {
9383 const opts = Comp[type];
9384 if ((isArray(opts) && opts.includes(key)) ||
9385 (isObject(opts) && key in opts)) {
9386 return true;
9387 }
9388 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
9389 return true;
9390 }
9391 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
9392 return true;
9393 }
9394 }
9395 function genRefFlag(v) {
9396 if (isShallow(v)) {
9397 return `ShallowRef`;
9398 }
9399 if (v.effect) {
9400 return `ComputedRef`;
9401 }
9402 return `Ref`;
9403 }
9404 if (window.devtoolsFormatters) {
9405 window.devtoolsFormatters.push(formatter);
9406 }
9407 else {
9408 window.devtoolsFormatters = [formatter];
9409 }
9410}
9411
9412function withMemo(memo, render, cache, index) {
9413 const cached = cache[index];
9414 if (cached && isMemoSame(cached, memo)) {
9415 return cached;
9416 }
9417 const ret = render();
9418 // shallow clone
9419 ret.memo = memo.slice();
9420 return (cache[index] = ret);
9421}
9422function isMemoSame(cached, memo) {
9423 const prev = cached.memo;
9424 if (prev.length != memo.length) {
9425 return false;
9426 }
9427 for (let i = 0; i < prev.length; i++) {
9428 if (hasChanged(prev[i], memo[i])) {
9429 return false;
9430 }
9431 }
9432 // make sure to let parent block track it when returning cached
9433 if (isBlockTreeEnabled > 0 && currentBlock) {
9434 currentBlock.push(cached);
9435 }
9436 return true;
9437}
9438
9439// Core API ------------------------------------------------------------------
9440const version = "3.2.47";
9441/**
9442 * SSR utils for \@vue/server-renderer. Only exposed in ssr-possible builds.
9443 * @internal
9444 */
9445const ssrUtils = (null);
9446/**
9447 * @internal only exposed in compat builds
9448 */
9449const resolveFilter = null;
9450/**
9451 * @internal only exposed in compat builds.
9452 */
9453const compatUtils = (null);
9454
9455const svgNS = 'http://www.w3.org/2000/svg';
9456const doc = (typeof document !== 'undefined' ? document : null);
9457const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
9458const nodeOps = {
9459 insert: (child, parent, anchor) => {
9460 parent.insertBefore(child, anchor || null);
9461 },
9462 remove: child => {
9463 const parent = child.parentNode;
9464 if (parent) {
9465 parent.removeChild(child);
9466 }
9467 },
9468 createElement: (tag, isSVG, is, props) => {
9469 const el = isSVG
9470 ? doc.createElementNS(svgNS, tag)
9471 : doc.createElement(tag, is ? { is } : undefined);
9472 if (tag === 'select' && props && props.multiple != null) {
9473 el.setAttribute('multiple', props.multiple);
9474 }
9475 return el;
9476 },
9477 createText: text => doc.createTextNode(text),
9478 createComment: text => doc.createComment(text),
9479 setText: (node, text) => {
9480 node.nodeValue = text;
9481 },
9482 setElementText: (el, text) => {
9483 el.textContent = text;
9484 },
9485 parentNode: node => node.parentNode,
9486 nextSibling: node => node.nextSibling,
9487 querySelector: selector => doc.querySelector(selector),
9488 setScopeId(el, id) {
9489 el.setAttribute(id, '');
9490 },
9491 // __UNSAFE__
9492 // Reason: innerHTML.
9493 // Static content here can only come from compiled templates.
9494 // As long as the user only uses trusted templates, this is safe.
9495 insertStaticContent(content, parent, anchor, isSVG, start, end) {
9496 // <parent> before | first ... last | anchor </parent>
9497 const before = anchor ? anchor.previousSibling : parent.lastChild;
9498 // #5308 can only take cached path if:
9499 // - has a single root node
9500 // - nextSibling info is still available
9501 if (start && (start === end || start.nextSibling)) {
9502 // cached
9503 while (true) {
9504 parent.insertBefore(start.cloneNode(true), anchor);
9505 if (start === end || !(start = start.nextSibling))
9506 break;
9507 }
9508 }
9509 else {
9510 // fresh insert
9511 templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
9512 const template = templateContainer.content;
9513 if (isSVG) {
9514 // remove outer svg wrapper
9515 const wrapper = template.firstChild;
9516 while (wrapper.firstChild) {
9517 template.appendChild(wrapper.firstChild);
9518 }
9519 template.removeChild(wrapper);
9520 }
9521 parent.insertBefore(template, anchor);
9522 }
9523 return [
9524 // first
9525 before ? before.nextSibling : parent.firstChild,
9526 // last
9527 anchor ? anchor.previousSibling : parent.lastChild
9528 ];
9529 }
9530};
9531
9532// compiler should normalize class + :class bindings on the same element
9533// into a single binding ['staticClass', dynamic]
9534function patchClass(el, value, isSVG) {
9535 // directly setting className should be faster than setAttribute in theory
9536 // if this is an element during a transition, take the temporary transition
9537 // classes into account.
9538 const transitionClasses = el._vtc;
9539 if (transitionClasses) {
9540 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
9541 }
9542 if (value == null) {
9543 el.removeAttribute('class');
9544 }
9545 else if (isSVG) {
9546 el.setAttribute('class', value);
9547 }
9548 else {
9549 el.className = value;
9550 }
9551}
9552
9553function patchStyle(el, prev, next) {
9554 const style = el.style;
9555 const isCssString = isString(next);
9556 if (next && !isCssString) {
9557 if (prev && !isString(prev)) {
9558 for (const key in prev) {
9559 if (next[key] == null) {
9560 setStyle(style, key, '');
9561 }
9562 }
9563 }
9564 for (const key in next) {
9565 setStyle(style, key, next[key]);
9566 }
9567 }
9568 else {
9569 const currentDisplay = style.display;
9570 if (isCssString) {
9571 if (prev !== next) {
9572 style.cssText = next;
9573 }
9574 }
9575 else if (prev) {
9576 el.removeAttribute('style');
9577 }
9578 // indicates that the `display` of the element is controlled by `v-show`,
9579 // so we always keep the current `display` value regardless of the `style`
9580 // value, thus handing over control to `v-show`.
9581 if ('_vod' in el) {
9582 style.display = currentDisplay;
9583 }
9584 }
9585}
9586const semicolonRE = /[^\\];\s*$/;
9587const importantRE = /\s*!important$/;
9588function setStyle(style, name, val) {
9589 if (isArray(val)) {
9590 val.forEach(v => setStyle(style, name, v));
9591 }
9592 else {
9593 if (val == null)
9594 val = '';
9595 {
9596 if (semicolonRE.test(val)) {
9597 warn(`Unexpected semicolon at the end of '${name}' style value: '${val}'`);
9598 }
9599 }
9600 if (name.startsWith('--')) {
9601 // custom property definition
9602 style.setProperty(name, val);
9603 }
9604 else {
9605 const prefixed = autoPrefix(style, name);
9606 if (importantRE.test(val)) {
9607 // !important
9608 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
9609 }
9610 else {
9611 style[prefixed] = val;
9612 }
9613 }
9614 }
9615}
9616const prefixes = ['Webkit', 'Moz', 'ms'];
9617const prefixCache = {};
9618function autoPrefix(style, rawName) {
9619 const cached = prefixCache[rawName];
9620 if (cached) {
9621 return cached;
9622 }
9623 let name = camelize(rawName);
9624 if (name !== 'filter' && name in style) {
9625 return (prefixCache[rawName] = name);
9626 }
9627 name = capitalize(name);
9628 for (let i = 0; i < prefixes.length; i++) {
9629 const prefixed = prefixes[i] + name;
9630 if (prefixed in style) {
9631 return (prefixCache[rawName] = prefixed);
9632 }
9633 }
9634 return rawName;
9635}
9636
9637const xlinkNS = 'http://www.w3.org/1999/xlink';
9638function patchAttr(el, key, value, isSVG, instance) {
9639 if (isSVG && key.startsWith('xlink:')) {
9640 if (value == null) {
9641 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
9642 }
9643 else {
9644 el.setAttributeNS(xlinkNS, key, value);
9645 }
9646 }
9647 else {
9648 // note we are only checking boolean attributes that don't have a
9649 // corresponding dom prop of the same name here.
9650 const isBoolean = isSpecialBooleanAttr(key);
9651 if (value == null || (isBoolean && !includeBooleanAttr(value))) {
9652 el.removeAttribute(key);
9653 }
9654 else {
9655 el.setAttribute(key, isBoolean ? '' : value);
9656 }
9657 }
9658}
9659
9660// __UNSAFE__
9661// functions. The user is responsible for using them with only trusted content.
9662function patchDOMProp(el, key, value,
9663// the following args are passed only due to potential innerHTML/textContent
9664// overriding existing VNodes, in which case the old tree must be properly
9665// unmounted.
9666prevChildren, parentComponent, parentSuspense, unmountChildren) {
9667 if (key === 'innerHTML' || key === 'textContent') {
9668 if (prevChildren) {
9669 unmountChildren(prevChildren, parentComponent, parentSuspense);
9670 }
9671 el[key] = value == null ? '' : value;
9672 return;
9673 }
9674 if (key === 'value' &&
9675 el.tagName !== 'PROGRESS' &&
9676 // custom elements may use _value internally
9677 !el.tagName.includes('-')) {
9678 // store value as _value as well since
9679 // non-string values will be stringified.
9680 el._value = value;
9681 const newValue = value == null ? '' : value;
9682 if (el.value !== newValue ||
9683 // #4956: always set for OPTION elements because its value falls back to
9684 // textContent if no value attribute is present. And setting .value for
9685 // OPTION has no side effect
9686 el.tagName === 'OPTION') {
9687 el.value = newValue;
9688 }
9689 if (value == null) {
9690 el.removeAttribute(key);
9691 }
9692 return;
9693 }
9694 let needRemove = false;
9695 if (value === '' || value == null) {
9696 const type = typeof el[key];
9697 if (type === 'boolean') {
9698 // e.g. <select multiple> compiles to { multiple: '' }
9699 value = includeBooleanAttr(value);
9700 }
9701 else if (value == null && type === 'string') {
9702 // e.g. <div :id="null">
9703 value = '';
9704 needRemove = true;
9705 }
9706 else if (type === 'number') {
9707 // e.g. <img :width="null">
9708 value = 0;
9709 needRemove = true;
9710 }
9711 }
9712 // some properties perform value validation and throw,
9713 // some properties has getter, no setter, will error in 'use strict'
9714 // eg. <select :type="null"></select> <select :willValidate="null"></select>
9715 try {
9716 el[key] = value;
9717 }
9718 catch (e) {
9719 // do not warn if value is auto-coerced from nullish values
9720 if (!needRemove) {
9721 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9722 `value ${value} is invalid.`, e);
9723 }
9724 }
9725 needRemove && el.removeAttribute(key);
9726}
9727
9728function addEventListener(el, event, handler, options) {
9729 el.addEventListener(event, handler, options);
9730}
9731function removeEventListener(el, event, handler, options) {
9732 el.removeEventListener(event, handler, options);
9733}
9734function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9735 // vei = vue event invokers
9736 const invokers = el._vei || (el._vei = {});
9737 const existingInvoker = invokers[rawName];
9738 if (nextValue && existingInvoker) {
9739 // patch
9740 existingInvoker.value = nextValue;
9741 }
9742 else {
9743 const [name, options] = parseName(rawName);
9744 if (nextValue) {
9745 // add
9746 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9747 addEventListener(el, name, invoker, options);
9748 }
9749 else if (existingInvoker) {
9750 // remove
9751 removeEventListener(el, name, existingInvoker, options);
9752 invokers[rawName] = undefined;
9753 }
9754 }
9755}
9756const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9757function parseName(name) {
9758 let options;
9759 if (optionsModifierRE.test(name)) {
9760 options = {};
9761 let m;
9762 while ((m = name.match(optionsModifierRE))) {
9763 name = name.slice(0, name.length - m[0].length);
9764 options[m[0].toLowerCase()] = true;
9765 }
9766 }
9767 const event = name[2] === ':' ? name.slice(3) : hyphenate(name.slice(2));
9768 return [event, options];
9769}
9770// To avoid the overhead of repeatedly calling Date.now(), we cache
9771// and use the same timestamp for all event listeners attached in the same tick.
9772let cachedNow = 0;
9773const p = /*#__PURE__*/ Promise.resolve();
9774const getNow = () => cachedNow || (p.then(() => (cachedNow = 0)), (cachedNow = Date.now()));
9775function createInvoker(initialValue, instance) {
9776 const invoker = (e) => {
9777 // async edge case vuejs/vue#6566
9778 // inner click event triggers patch, event handler
9779 // attached to outer element during patch, and triggered again. This
9780 // happens because browsers fire microtask ticks between event propagation.
9781 // this no longer happens for templates in Vue 3, but could still be
9782 // theoretically possible for hand-written render functions.
9783 // the solution: we save the timestamp when a handler is attached,
9784 // and also attach the timestamp to any event that was handled by vue
9785 // for the first time (to avoid inconsistent event timestamp implementations
9786 // or events fired from iframes, e.g. #2513)
9787 // The handler would only fire if the event passed to it was fired
9788 // AFTER it was attached.
9789 if (!e._vts) {
9790 e._vts = Date.now();
9791 }
9792 else if (e._vts <= invoker.attached) {
9793 return;
9794 }
9795 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* ErrorCodes.NATIVE_EVENT_HANDLER */, [e]);
9796 };
9797 invoker.value = initialValue;
9798 invoker.attached = getNow();
9799 return invoker;
9800}
9801function patchStopImmediatePropagation(e, value) {
9802 if (isArray(value)) {
9803 const originalStop = e.stopImmediatePropagation;
9804 e.stopImmediatePropagation = () => {
9805 originalStop.call(e);
9806 e._stopped = true;
9807 };
9808 return value.map(fn => (e) => !e._stopped && fn && fn(e));
9809 }
9810 else {
9811 return value;
9812 }
9813}
9814
9815const nativeOnRE = /^on[a-z]/;
9816const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9817 if (key === 'class') {
9818 patchClass(el, nextValue, isSVG);
9819 }
9820 else if (key === 'style') {
9821 patchStyle(el, prevValue, nextValue);
9822 }
9823 else if (isOn(key)) {
9824 // ignore v-model listeners
9825 if (!isModelListener(key)) {
9826 patchEvent(el, key, prevValue, nextValue, parentComponent);
9827 }
9828 }
9829 else if (key[0] === '.'
9830 ? ((key = key.slice(1)), true)
9831 : key[0] === '^'
9832 ? ((key = key.slice(1)), false)
9833 : shouldSetAsProp(el, key, nextValue, isSVG)) {
9834 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9835 }
9836 else {
9837 // special case for <input v-model type="checkbox"> with
9838 // :true-value & :false-value
9839 // store value as dom properties since non-string values will be
9840 // stringified.
9841 if (key === 'true-value') {
9842 el._trueValue = nextValue;
9843 }
9844 else if (key === 'false-value') {
9845 el._falseValue = nextValue;
9846 }
9847 patchAttr(el, key, nextValue, isSVG);
9848 }
9849};
9850function shouldSetAsProp(el, key, value, isSVG) {
9851 if (isSVG) {
9852 // most keys must be set as attribute on svg elements to work
9853 // ...except innerHTML & textContent
9854 if (key === 'innerHTML' || key === 'textContent') {
9855 return true;
9856 }
9857 // or native onclick with function values
9858 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9859 return true;
9860 }
9861 return false;
9862 }
9863 // these are enumerated attrs, however their corresponding DOM properties
9864 // are actually booleans - this leads to setting it with a string "false"
9865 // value leading it to be coerced to `true`, so we need to always treat
9866 // them as attributes.
9867 // Note that `contentEditable` doesn't have this problem: its DOM
9868 // property is also enumerated string values.
9869 if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
9870 return false;
9871 }
9872 // #1787, #2840 form property on form elements is readonly and must be set as
9873 // attribute.
9874 if (key === 'form') {
9875 return false;
9876 }
9877 // #1526 <input list> must be set as attribute
9878 if (key === 'list' && el.tagName === 'INPUT') {
9879 return false;
9880 }
9881 // #2766 <textarea type> must be set as attribute
9882 if (key === 'type' && el.tagName === 'TEXTAREA') {
9883 return false;
9884 }
9885 // native onclick with string value, must be set as attribute
9886 if (nativeOnRE.test(key) && isString(value)) {
9887 return false;
9888 }
9889 return key in el;
9890}
9891
9892function defineCustomElement(options, hydrate) {
9893 const Comp = defineComponent(options);
9894 class VueCustomElement extends VueElement {
9895 constructor(initialProps) {
9896 super(Comp, initialProps, hydrate);
9897 }
9898 }
9899 VueCustomElement.def = Comp;
9900 return VueCustomElement;
9901}
9902const defineSSRCustomElement = ((options) => {
9903 // @ts-ignore
9904 return defineCustomElement(options, hydrate);
9905});
9906const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
9907});
9908class VueElement extends BaseClass {
9909 constructor(_def, _props = {}, hydrate) {
9910 super();
9911 this._def = _def;
9912 this._props = _props;
9913 /**
9914 * @internal
9915 */
9916 this._instance = null;
9917 this._connected = false;
9918 this._resolved = false;
9919 this._numberProps = null;
9920 if (this.shadowRoot && hydrate) {
9921 hydrate(this._createVNode(), this.shadowRoot);
9922 }
9923 else {
9924 if (this.shadowRoot) {
9925 warn(`Custom element has pre-rendered declarative shadow root but is not ` +
9926 `defined as hydratable. Use \`defineSSRCustomElement\`.`);
9927 }
9928 this.attachShadow({ mode: 'open' });
9929 if (!this._def.__asyncLoader) {
9930 // for sync component defs we can immediately resolve props
9931 this._resolveProps(this._def);
9932 }
9933 }
9934 }
9935 connectedCallback() {
9936 this._connected = true;
9937 if (!this._instance) {
9938 if (this._resolved) {
9939 this._update();
9940 }
9941 else {
9942 this._resolveDef();
9943 }
9944 }
9945 }
9946 disconnectedCallback() {
9947 this._connected = false;
9948 nextTick(() => {
9949 if (!this._connected) {
9950 render(null, this.shadowRoot);
9951 this._instance = null;
9952 }
9953 });
9954 }
9955 /**
9956 * resolve inner component definition (handle possible async component)
9957 */
9958 _resolveDef() {
9959 this._resolved = true;
9960 // set initial attrs
9961 for (let i = 0; i < this.attributes.length; i++) {
9962 this._setAttr(this.attributes[i].name);
9963 }
9964 // watch future attr changes
9965 new MutationObserver(mutations => {
9966 for (const m of mutations) {
9967 this._setAttr(m.attributeName);
9968 }
9969 }).observe(this, { attributes: true });
9970 const resolve = (def, isAsync = false) => {
9971 const { props, styles } = def;
9972 // cast Number-type props set before resolve
9973 let numberProps;
9974 if (props && !isArray(props)) {
9975 for (const key in props) {
9976 const opt = props[key];
9977 if (opt === Number || (opt && opt.type === Number)) {
9978 if (key in this._props) {
9979 this._props[key] = toNumber(this._props[key]);
9980 }
9981 (numberProps || (numberProps = Object.create(null)))[camelize(key)] = true;
9982 }
9983 }
9984 }
9985 this._numberProps = numberProps;
9986 if (isAsync) {
9987 // defining getter/setters on prototype
9988 // for sync defs, this already happened in the constructor
9989 this._resolveProps(def);
9990 }
9991 // apply CSS
9992 this._applyStyles(styles);
9993 // initial render
9994 this._update();
9995 };
9996 const asyncDef = this._def.__asyncLoader;
9997 if (asyncDef) {
9998 asyncDef().then(def => resolve(def, true));
9999 }
10000 else {
10001 resolve(this._def);
10002 }
10003 }
10004 _resolveProps(def) {
10005 const { props } = def;
10006 const declaredPropKeys = isArray(props) ? props : Object.keys(props || {});
10007 // check if there are props set pre-upgrade or connect
10008 for (const key of Object.keys(this)) {
10009 if (key[0] !== '_' && declaredPropKeys.includes(key)) {
10010 this._setProp(key, this[key], true, false);
10011 }
10012 }
10013 // defining getter/setters on prototype
10014 for (const key of declaredPropKeys.map(camelize)) {
10015 Object.defineProperty(this, key, {
10016 get() {
10017 return this._getProp(key);
10018 },
10019 set(val) {
10020 this._setProp(key, val);
10021 }
10022 });
10023 }
10024 }
10025 _setAttr(key) {
10026 let value = this.getAttribute(key);
10027 const camelKey = camelize(key);
10028 if (this._numberProps && this._numberProps[camelKey]) {
10029 value = toNumber(value);
10030 }
10031 this._setProp(camelKey, value, false);
10032 }
10033 /**
10034 * @internal
10035 */
10036 _getProp(key) {
10037 return this._props[key];
10038 }
10039 /**
10040 * @internal
10041 */
10042 _setProp(key, val, shouldReflect = true, shouldUpdate = true) {
10043 if (val !== this._props[key]) {
10044 this._props[key] = val;
10045 if (shouldUpdate && this._instance) {
10046 this._update();
10047 }
10048 // reflect
10049 if (shouldReflect) {
10050 if (val === true) {
10051 this.setAttribute(hyphenate(key), '');
10052 }
10053 else if (typeof val === 'string' || typeof val === 'number') {
10054 this.setAttribute(hyphenate(key), val + '');
10055 }
10056 else if (!val) {
10057 this.removeAttribute(hyphenate(key));
10058 }
10059 }
10060 }
10061 }
10062 _update() {
10063 render(this._createVNode(), this.shadowRoot);
10064 }
10065 _createVNode() {
10066 const vnode = createVNode(this._def, extend({}, this._props));
10067 if (!this._instance) {
10068 vnode.ce = instance => {
10069 this._instance = instance;
10070 instance.isCE = true;
10071 // HMR
10072 {
10073 instance.ceReload = newStyles => {
10074 // always reset styles
10075 if (this._styles) {
10076 this._styles.forEach(s => this.shadowRoot.removeChild(s));
10077 this._styles.length = 0;
10078 }
10079 this._applyStyles(newStyles);
10080 this._instance = null;
10081 this._update();
10082 };
10083 }
10084 const dispatch = (event, args) => {
10085 this.dispatchEvent(new CustomEvent(event, {
10086 detail: args
10087 }));
10088 };
10089 // intercept emit
10090 instance.emit = (event, ...args) => {
10091 // dispatch both the raw and hyphenated versions of an event
10092 // to match Vue behavior
10093 dispatch(event, args);
10094 if (hyphenate(event) !== event) {
10095 dispatch(hyphenate(event), args);
10096 }
10097 };
10098 // locate nearest Vue custom element parent for provide/inject
10099 let parent = this;
10100 while ((parent =
10101 parent && (parent.parentNode || parent.host))) {
10102 if (parent instanceof VueElement) {
10103 instance.parent = parent._instance;
10104 instance.provides = parent._instance.provides;
10105 break;
10106 }
10107 }
10108 };
10109 }
10110 return vnode;
10111 }
10112 _applyStyles(styles) {
10113 if (styles) {
10114 styles.forEach(css => {
10115 const s = document.createElement('style');
10116 s.textContent = css;
10117 this.shadowRoot.appendChild(s);
10118 // record for HMR
10119 {
10120 (this._styles || (this._styles = [])).push(s);
10121 }
10122 });
10123 }
10124 }
10125}
10126
10127function useCssModule(name = '$style') {
10128 /* istanbul ignore else */
10129 {
10130 const instance = getCurrentInstance();
10131 if (!instance) {
10132 warn(`useCssModule must be called inside setup()`);
10133 return EMPTY_OBJ;
10134 }
10135 const modules = instance.type.__cssModules;
10136 if (!modules) {
10137 warn(`Current instance does not have CSS modules injected.`);
10138 return EMPTY_OBJ;
10139 }
10140 const mod = modules[name];
10141 if (!mod) {
10142 warn(`Current instance does not have CSS module named "${name}".`);
10143 return EMPTY_OBJ;
10144 }
10145 return mod;
10146 }
10147}
10148
10149/**
10150 * Runtime helper for SFC's CSS variable injection feature.
10151 * @private
10152 */
10153function useCssVars(getter) {
10154 const instance = getCurrentInstance();
10155 /* istanbul ignore next */
10156 if (!instance) {
10157 warn(`useCssVars is called without current active component instance.`);
10158 return;
10159 }
10160 const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => {
10161 Array.from(document.querySelectorAll(`[data-v-owner="${instance.uid}"]`)).forEach(node => setVarsOnNode(node, vars));
10162 });
10163 const setVars = () => {
10164 const vars = getter(instance.proxy);
10165 setVarsOnVNode(instance.subTree, vars);
10166 updateTeleports(vars);
10167 };
10168 watchPostEffect(setVars);
10169 onMounted(() => {
10170 const ob = new MutationObserver(setVars);
10171 ob.observe(instance.subTree.el.parentNode, { childList: true });
10172 onUnmounted(() => ob.disconnect());
10173 });
10174}
10175function setVarsOnVNode(vnode, vars) {
10176 if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
10177 const suspense = vnode.suspense;
10178 vnode = suspense.activeBranch;
10179 if (suspense.pendingBranch && !suspense.isHydrating) {
10180 suspense.effects.push(() => {
10181 setVarsOnVNode(suspense.activeBranch, vars);
10182 });
10183 }
10184 }
10185 // drill down HOCs until it's a non-component vnode
10186 while (vnode.component) {
10187 vnode = vnode.component.subTree;
10188 }
10189 if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && vnode.el) {
10190 setVarsOnNode(vnode.el, vars);
10191 }
10192 else if (vnode.type === Fragment) {
10193 vnode.children.forEach(c => setVarsOnVNode(c, vars));
10194 }
10195 else if (vnode.type === Static) {
10196 let { el, anchor } = vnode;
10197 while (el) {
10198 setVarsOnNode(el, vars);
10199 if (el === anchor)
10200 break;
10201 el = el.nextSibling;
10202 }
10203 }
10204}
10205function setVarsOnNode(el, vars) {
10206 if (el.nodeType === 1) {
10207 const style = el.style;
10208 for (const key in vars) {
10209 style.setProperty(`--${key}`, vars[key]);
10210 }
10211 }
10212}
10213
10214const TRANSITION$1 = 'transition';
10215const ANIMATION = 'animation';
10216// DOM Transition is a higher-order-component based on the platform-agnostic
10217// base Transition component, with DOM-specific logic.
10218const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
10219Transition.displayName = 'Transition';
10220const DOMTransitionPropsValidators = {
10221 name: String,
10222 type: String,
10223 css: {
10224 type: Boolean,
10225 default: true
10226 },
10227 duration: [String, Number, Object],
10228 enterFromClass: String,
10229 enterActiveClass: String,
10230 enterToClass: String,
10231 appearFromClass: String,
10232 appearActiveClass: String,
10233 appearToClass: String,
10234 leaveFromClass: String,
10235 leaveActiveClass: String,
10236 leaveToClass: String
10237};
10238const TransitionPropsValidators = (Transition.props =
10239 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
10240/**
10241 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
10242 * with custom HOCs.
10243 */
10244const callHook = (hook, args = []) => {
10245 if (isArray(hook)) {
10246 hook.forEach(h => h(...args));
10247 }
10248 else if (hook) {
10249 hook(...args);
10250 }
10251};
10252/**
10253 * Check if a hook expects a callback (2nd arg), which means the user
10254 * intends to explicitly control the end of the transition.
10255 */
10256const hasExplicitCallback = (hook) => {
10257 return hook
10258 ? isArray(hook)
10259 ? hook.some(h => h.length > 1)
10260 : hook.length > 1
10261 : false;
10262};
10263function resolveTransitionProps(rawProps) {
10264 const baseProps = {};
10265 for (const key in rawProps) {
10266 if (!(key in DOMTransitionPropsValidators)) {
10267 baseProps[key] = rawProps[key];
10268 }
10269 }
10270 if (rawProps.css === false) {
10271 return baseProps;
10272 }
10273 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;
10274 const durations = normalizeDuration(duration);
10275 const enterDuration = durations && durations[0];
10276 const leaveDuration = durations && durations[1];
10277 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
10278 const finishEnter = (el, isAppear, done) => {
10279 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
10280 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
10281 done && done();
10282 };
10283 const finishLeave = (el, done) => {
10284 el._isLeaving = false;
10285 removeTransitionClass(el, leaveFromClass);
10286 removeTransitionClass(el, leaveToClass);
10287 removeTransitionClass(el, leaveActiveClass);
10288 done && done();
10289 };
10290 const makeEnterHook = (isAppear) => {
10291 return (el, done) => {
10292 const hook = isAppear ? onAppear : onEnter;
10293 const resolve = () => finishEnter(el, isAppear, done);
10294 callHook(hook, [el, resolve]);
10295 nextFrame(() => {
10296 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
10297 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
10298 if (!hasExplicitCallback(hook)) {
10299 whenTransitionEnds(el, type, enterDuration, resolve);
10300 }
10301 });
10302 };
10303 };
10304 return extend(baseProps, {
10305 onBeforeEnter(el) {
10306 callHook(onBeforeEnter, [el]);
10307 addTransitionClass(el, enterFromClass);
10308 addTransitionClass(el, enterActiveClass);
10309 },
10310 onBeforeAppear(el) {
10311 callHook(onBeforeAppear, [el]);
10312 addTransitionClass(el, appearFromClass);
10313 addTransitionClass(el, appearActiveClass);
10314 },
10315 onEnter: makeEnterHook(false),
10316 onAppear: makeEnterHook(true),
10317 onLeave(el, done) {
10318 el._isLeaving = true;
10319 const resolve = () => finishLeave(el, done);
10320 addTransitionClass(el, leaveFromClass);
10321 // force reflow so *-leave-from classes immediately take effect (#2593)
10322 forceReflow();
10323 addTransitionClass(el, leaveActiveClass);
10324 nextFrame(() => {
10325 if (!el._isLeaving) {
10326 // cancelled
10327 return;
10328 }
10329 removeTransitionClass(el, leaveFromClass);
10330 addTransitionClass(el, leaveToClass);
10331 if (!hasExplicitCallback(onLeave)) {
10332 whenTransitionEnds(el, type, leaveDuration, resolve);
10333 }
10334 });
10335 callHook(onLeave, [el, resolve]);
10336 },
10337 onEnterCancelled(el) {
10338 finishEnter(el, false);
10339 callHook(onEnterCancelled, [el]);
10340 },
10341 onAppearCancelled(el) {
10342 finishEnter(el, true);
10343 callHook(onAppearCancelled, [el]);
10344 },
10345 onLeaveCancelled(el) {
10346 finishLeave(el);
10347 callHook(onLeaveCancelled, [el]);
10348 }
10349 });
10350}
10351function normalizeDuration(duration) {
10352 if (duration == null) {
10353 return null;
10354 }
10355 else if (isObject(duration)) {
10356 return [NumberOf(duration.enter), NumberOf(duration.leave)];
10357 }
10358 else {
10359 const n = NumberOf(duration);
10360 return [n, n];
10361 }
10362}
10363function NumberOf(val) {
10364 const res = toNumber(val);
10365 {
10366 assertNumber(res, '<transition> explicit duration');
10367 }
10368 return res;
10369}
10370function addTransitionClass(el, cls) {
10371 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
10372 (el._vtc ||
10373 (el._vtc = new Set())).add(cls);
10374}
10375function removeTransitionClass(el, cls) {
10376 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
10377 const { _vtc } = el;
10378 if (_vtc) {
10379 _vtc.delete(cls);
10380 if (!_vtc.size) {
10381 el._vtc = undefined;
10382 }
10383 }
10384}
10385function nextFrame(cb) {
10386 requestAnimationFrame(() => {
10387 requestAnimationFrame(cb);
10388 });
10389}
10390let endId = 0;
10391function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
10392 const id = (el._endId = ++endId);
10393 const resolveIfNotStale = () => {
10394 if (id === el._endId) {
10395 resolve();
10396 }
10397 };
10398 if (explicitTimeout) {
10399 return setTimeout(resolveIfNotStale, explicitTimeout);
10400 }
10401 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
10402 if (!type) {
10403 return resolve();
10404 }
10405 const endEvent = type + 'end';
10406 let ended = 0;
10407 const end = () => {
10408 el.removeEventListener(endEvent, onEnd);
10409 resolveIfNotStale();
10410 };
10411 const onEnd = (e) => {
10412 if (e.target === el && ++ended >= propCount) {
10413 end();
10414 }
10415 };
10416 setTimeout(() => {
10417 if (ended < propCount) {
10418 end();
10419 }
10420 }, timeout + 1);
10421 el.addEventListener(endEvent, onEnd);
10422}
10423function getTransitionInfo(el, expectedType) {
10424 const styles = window.getComputedStyle(el);
10425 // JSDOM may return undefined for transition properties
10426 const getStyleProperties = (key) => (styles[key] || '').split(', ');
10427 const transitionDelays = getStyleProperties(`${TRANSITION$1}Delay`);
10428 const transitionDurations = getStyleProperties(`${TRANSITION$1}Duration`);
10429 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
10430 const animationDelays = getStyleProperties(`${ANIMATION}Delay`);
10431 const animationDurations = getStyleProperties(`${ANIMATION}Duration`);
10432 const animationTimeout = getTimeout(animationDelays, animationDurations);
10433 let type = null;
10434 let timeout = 0;
10435 let propCount = 0;
10436 /* istanbul ignore if */
10437 if (expectedType === TRANSITION$1) {
10438 if (transitionTimeout > 0) {
10439 type = TRANSITION$1;
10440 timeout = transitionTimeout;
10441 propCount = transitionDurations.length;
10442 }
10443 }
10444 else if (expectedType === ANIMATION) {
10445 if (animationTimeout > 0) {
10446 type = ANIMATION;
10447 timeout = animationTimeout;
10448 propCount = animationDurations.length;
10449 }
10450 }
10451 else {
10452 timeout = Math.max(transitionTimeout, animationTimeout);
10453 type =
10454 timeout > 0
10455 ? transitionTimeout > animationTimeout
10456 ? TRANSITION$1
10457 : ANIMATION
10458 : null;
10459 propCount = type
10460 ? type === TRANSITION$1
10461 ? transitionDurations.length
10462 : animationDurations.length
10463 : 0;
10464 }
10465 const hasTransform = type === TRANSITION$1 &&
10466 /\b(transform|all)(,|$)/.test(getStyleProperties(`${TRANSITION$1}Property`).toString());
10467 return {
10468 type,
10469 timeout,
10470 propCount,
10471 hasTransform
10472 };
10473}
10474function getTimeout(delays, durations) {
10475 while (delays.length < durations.length) {
10476 delays = delays.concat(delays);
10477 }
10478 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
10479}
10480// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
10481// numbers in a locale-dependent way, using a comma instead of a dot.
10482// If comma is not replaced with a dot, the input will be rounded down
10483// (i.e. acting as a floor function) causing unexpected behaviors
10484function toMs(s) {
10485 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
10486}
10487// synchronously force layout to put elements into a certain state
10488function forceReflow() {
10489 return document.body.offsetHeight;
10490}
10491
10492const positionMap = new WeakMap();
10493const newPositionMap = new WeakMap();
10494const TransitionGroupImpl = {
10495 name: 'TransitionGroup',
10496 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
10497 tag: String,
10498 moveClass: String
10499 }),
10500 setup(props, { slots }) {
10501 const instance = getCurrentInstance();
10502 const state = useTransitionState();
10503 let prevChildren;
10504 let children;
10505 onUpdated(() => {
10506 // children is guaranteed to exist after initial render
10507 if (!prevChildren.length) {
10508 return;
10509 }
10510 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
10511 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
10512 return;
10513 }
10514 // we divide the work into three loops to avoid mixing DOM reads and writes
10515 // in each iteration - which helps prevent layout thrashing.
10516 prevChildren.forEach(callPendingCbs);
10517 prevChildren.forEach(recordPosition);
10518 const movedChildren = prevChildren.filter(applyTranslation);
10519 // force reflow to put everything in position
10520 forceReflow();
10521 movedChildren.forEach(c => {
10522 const el = c.el;
10523 const style = el.style;
10524 addTransitionClass(el, moveClass);
10525 style.transform = style.webkitTransform = style.transitionDuration = '';
10526 const cb = (el._moveCb = (e) => {
10527 if (e && e.target !== el) {
10528 return;
10529 }
10530 if (!e || /transform$/.test(e.propertyName)) {
10531 el.removeEventListener('transitionend', cb);
10532 el._moveCb = null;
10533 removeTransitionClass(el, moveClass);
10534 }
10535 });
10536 el.addEventListener('transitionend', cb);
10537 });
10538 });
10539 return () => {
10540 const rawProps = toRaw(props);
10541 const cssTransitionProps = resolveTransitionProps(rawProps);
10542 let tag = rawProps.tag || Fragment;
10543 prevChildren = children;
10544 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
10545 for (let i = 0; i < children.length; i++) {
10546 const child = children[i];
10547 if (child.key != null) {
10548 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10549 }
10550 else {
10551 warn(`<TransitionGroup> children must be keyed.`);
10552 }
10553 }
10554 if (prevChildren) {
10555 for (let i = 0; i < prevChildren.length; i++) {
10556 const child = prevChildren[i];
10557 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10558 positionMap.set(child, child.el.getBoundingClientRect());
10559 }
10560 }
10561 return createVNode(tag, null, children);
10562 };
10563 }
10564};
10565/**
10566 * TransitionGroup does not support "mode" so we need to remove it from the
10567 * props declarations, but direct delete operation is considered a side effect
10568 * and will make the entire transition feature non-tree-shakeable, so we do it
10569 * in a function and mark the function's invocation as pure.
10570 */
10571const removeMode = (props) => delete props.mode;
10572/*#__PURE__*/ removeMode(TransitionGroupImpl.props);
10573const TransitionGroup = TransitionGroupImpl;
10574function callPendingCbs(c) {
10575 const el = c.el;
10576 if (el._moveCb) {
10577 el._moveCb();
10578 }
10579 if (el._enterCb) {
10580 el._enterCb();
10581 }
10582}
10583function recordPosition(c) {
10584 newPositionMap.set(c, c.el.getBoundingClientRect());
10585}
10586function applyTranslation(c) {
10587 const oldPos = positionMap.get(c);
10588 const newPos = newPositionMap.get(c);
10589 const dx = oldPos.left - newPos.left;
10590 const dy = oldPos.top - newPos.top;
10591 if (dx || dy) {
10592 const s = c.el.style;
10593 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
10594 s.transitionDuration = '0s';
10595 return c;
10596 }
10597}
10598function hasCSSTransform(el, root, moveClass) {
10599 // Detect whether an element with the move class applied has
10600 // CSS transitions. Since the element may be inside an entering
10601 // transition at this very moment, we make a clone of it and remove
10602 // all other transition classes applied to ensure only the move class
10603 // is applied.
10604 const clone = el.cloneNode();
10605 if (el._vtc) {
10606 el._vtc.forEach(cls => {
10607 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
10608 });
10609 }
10610 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
10611 clone.style.display = 'none';
10612 const container = (root.nodeType === 1 ? root : root.parentNode);
10613 container.appendChild(clone);
10614 const { hasTransform } = getTransitionInfo(clone);
10615 container.removeChild(clone);
10616 return hasTransform;
10617}
10618
10619const getModelAssigner = (vnode) => {
10620 const fn = vnode.props['onUpdate:modelValue'] ||
10621 (false );
10622 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
10623};
10624function onCompositionStart(e) {
10625 e.target.composing = true;
10626}
10627function onCompositionEnd(e) {
10628 const target = e.target;
10629 if (target.composing) {
10630 target.composing = false;
10631 target.dispatchEvent(new Event('input'));
10632 }
10633}
10634// We are exporting the v-model runtime directly as vnode hooks so that it can
10635// be tree-shaken in case v-model is never used.
10636const vModelText = {
10637 created(el, { modifiers: { lazy, trim, number } }, vnode) {
10638 el._assign = getModelAssigner(vnode);
10639 const castToNumber = number || (vnode.props && vnode.props.type === 'number');
10640 addEventListener(el, lazy ? 'change' : 'input', e => {
10641 if (e.target.composing)
10642 return;
10643 let domValue = el.value;
10644 if (trim) {
10645 domValue = domValue.trim();
10646 }
10647 if (castToNumber) {
10648 domValue = looseToNumber(domValue);
10649 }
10650 el._assign(domValue);
10651 });
10652 if (trim) {
10653 addEventListener(el, 'change', () => {
10654 el.value = el.value.trim();
10655 });
10656 }
10657 if (!lazy) {
10658 addEventListener(el, 'compositionstart', onCompositionStart);
10659 addEventListener(el, 'compositionend', onCompositionEnd);
10660 // Safari < 10.2 & UIWebView doesn't fire compositionend when
10661 // switching focus before confirming composition choice
10662 // this also fixes the issue where some browsers e.g. iOS Chrome
10663 // fires "change" instead of "input" on autocomplete.
10664 addEventListener(el, 'change', onCompositionEnd);
10665 }
10666 },
10667 // set value on mounted so it's after min/max for type="range"
10668 mounted(el, { value }) {
10669 el.value = value == null ? '' : value;
10670 },
10671 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
10672 el._assign = getModelAssigner(vnode);
10673 // avoid clearing unresolved text. #2302
10674 if (el.composing)
10675 return;
10676 if (document.activeElement === el && el.type !== 'range') {
10677 if (lazy) {
10678 return;
10679 }
10680 if (trim && el.value.trim() === value) {
10681 return;
10682 }
10683 if ((number || el.type === 'number') &&
10684 looseToNumber(el.value) === value) {
10685 return;
10686 }
10687 }
10688 const newValue = value == null ? '' : value;
10689 if (el.value !== newValue) {
10690 el.value = newValue;
10691 }
10692 }
10693};
10694const vModelCheckbox = {
10695 // #4096 array checkboxes need to be deep traversed
10696 deep: true,
10697 created(el, _, vnode) {
10698 el._assign = getModelAssigner(vnode);
10699 addEventListener(el, 'change', () => {
10700 const modelValue = el._modelValue;
10701 const elementValue = getValue(el);
10702 const checked = el.checked;
10703 const assign = el._assign;
10704 if (isArray(modelValue)) {
10705 const index = looseIndexOf(modelValue, elementValue);
10706 const found = index !== -1;
10707 if (checked && !found) {
10708 assign(modelValue.concat(elementValue));
10709 }
10710 else if (!checked && found) {
10711 const filtered = [...modelValue];
10712 filtered.splice(index, 1);
10713 assign(filtered);
10714 }
10715 }
10716 else if (isSet(modelValue)) {
10717 const cloned = new Set(modelValue);
10718 if (checked) {
10719 cloned.add(elementValue);
10720 }
10721 else {
10722 cloned.delete(elementValue);
10723 }
10724 assign(cloned);
10725 }
10726 else {
10727 assign(getCheckboxValue(el, checked));
10728 }
10729 });
10730 },
10731 // set initial checked on mount to wait for true-value/false-value
10732 mounted: setChecked,
10733 beforeUpdate(el, binding, vnode) {
10734 el._assign = getModelAssigner(vnode);
10735 setChecked(el, binding, vnode);
10736 }
10737};
10738function setChecked(el, { value, oldValue }, vnode) {
10739 el._modelValue = value;
10740 if (isArray(value)) {
10741 el.checked = looseIndexOf(value, vnode.props.value) > -1;
10742 }
10743 else if (isSet(value)) {
10744 el.checked = value.has(vnode.props.value);
10745 }
10746 else if (value !== oldValue) {
10747 el.checked = looseEqual(value, getCheckboxValue(el, true));
10748 }
10749}
10750const vModelRadio = {
10751 created(el, { value }, vnode) {
10752 el.checked = looseEqual(value, vnode.props.value);
10753 el._assign = getModelAssigner(vnode);
10754 addEventListener(el, 'change', () => {
10755 el._assign(getValue(el));
10756 });
10757 },
10758 beforeUpdate(el, { value, oldValue }, vnode) {
10759 el._assign = getModelAssigner(vnode);
10760 if (value !== oldValue) {
10761 el.checked = looseEqual(value, vnode.props.value);
10762 }
10763 }
10764};
10765const vModelSelect = {
10766 // <select multiple> value need to be deep traversed
10767 deep: true,
10768 created(el, { value, modifiers: { number } }, vnode) {
10769 const isSetModel = isSet(value);
10770 addEventListener(el, 'change', () => {
10771 const selectedVal = Array.prototype.filter
10772 .call(el.options, (o) => o.selected)
10773 .map((o) => number ? looseToNumber(getValue(o)) : getValue(o));
10774 el._assign(el.multiple
10775 ? isSetModel
10776 ? new Set(selectedVal)
10777 : selectedVal
10778 : selectedVal[0]);
10779 });
10780 el._assign = getModelAssigner(vnode);
10781 },
10782 // set value in mounted & updated because <select> relies on its children
10783 // <option>s.
10784 mounted(el, { value }) {
10785 setSelected(el, value);
10786 },
10787 beforeUpdate(el, _binding, vnode) {
10788 el._assign = getModelAssigner(vnode);
10789 },
10790 updated(el, { value }) {
10791 setSelected(el, value);
10792 }
10793};
10794function setSelected(el, value) {
10795 const isMultiple = el.multiple;
10796 if (isMultiple && !isArray(value) && !isSet(value)) {
10797 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
10798 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
10799 return;
10800 }
10801 for (let i = 0, l = el.options.length; i < l; i++) {
10802 const option = el.options[i];
10803 const optionValue = getValue(option);
10804 if (isMultiple) {
10805 if (isArray(value)) {
10806 option.selected = looseIndexOf(value, optionValue) > -1;
10807 }
10808 else {
10809 option.selected = value.has(optionValue);
10810 }
10811 }
10812 else {
10813 if (looseEqual(getValue(option), value)) {
10814 if (el.selectedIndex !== i)
10815 el.selectedIndex = i;
10816 return;
10817 }
10818 }
10819 }
10820 if (!isMultiple && el.selectedIndex !== -1) {
10821 el.selectedIndex = -1;
10822 }
10823}
10824// retrieve raw value set via :value bindings
10825function getValue(el) {
10826 return '_value' in el ? el._value : el.value;
10827}
10828// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
10829function getCheckboxValue(el, checked) {
10830 const key = checked ? '_trueValue' : '_falseValue';
10831 return key in el ? el[key] : checked;
10832}
10833const vModelDynamic = {
10834 created(el, binding, vnode) {
10835 callModelHook(el, binding, vnode, null, 'created');
10836 },
10837 mounted(el, binding, vnode) {
10838 callModelHook(el, binding, vnode, null, 'mounted');
10839 },
10840 beforeUpdate(el, binding, vnode, prevVNode) {
10841 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
10842 },
10843 updated(el, binding, vnode, prevVNode) {
10844 callModelHook(el, binding, vnode, prevVNode, 'updated');
10845 }
10846};
10847function resolveDynamicModel(tagName, type) {
10848 switch (tagName) {
10849 case 'SELECT':
10850 return vModelSelect;
10851 case 'TEXTAREA':
10852 return vModelText;
10853 default:
10854 switch (type) {
10855 case 'checkbox':
10856 return vModelCheckbox;
10857 case 'radio':
10858 return vModelRadio;
10859 default:
10860 return vModelText;
10861 }
10862 }
10863}
10864function callModelHook(el, binding, vnode, prevVNode, hook) {
10865 const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
10866 const fn = modelToUse[hook];
10867 fn && fn(el, binding, vnode, prevVNode);
10868}
10869
10870const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
10871const modifierGuards = {
10872 stop: e => e.stopPropagation(),
10873 prevent: e => e.preventDefault(),
10874 self: e => e.target !== e.currentTarget,
10875 ctrl: e => !e.ctrlKey,
10876 shift: e => !e.shiftKey,
10877 alt: e => !e.altKey,
10878 meta: e => !e.metaKey,
10879 left: e => 'button' in e && e.button !== 0,
10880 middle: e => 'button' in e && e.button !== 1,
10881 right: e => 'button' in e && e.button !== 2,
10882 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
10883};
10884/**
10885 * @private
10886 */
10887const withModifiers = (fn, modifiers) => {
10888 return (event, ...args) => {
10889 for (let i = 0; i < modifiers.length; i++) {
10890 const guard = modifierGuards[modifiers[i]];
10891 if (guard && guard(event, modifiers))
10892 return;
10893 }
10894 return fn(event, ...args);
10895 };
10896};
10897// Kept for 2.x compat.
10898// Note: IE11 compat for `spacebar` and `del` is removed for now.
10899const keyNames = {
10900 esc: 'escape',
10901 space: ' ',
10902 up: 'arrow-up',
10903 left: 'arrow-left',
10904 right: 'arrow-right',
10905 down: 'arrow-down',
10906 delete: 'backspace'
10907};
10908/**
10909 * @private
10910 */
10911const withKeys = (fn, modifiers) => {
10912 return (event) => {
10913 if (!('key' in event)) {
10914 return;
10915 }
10916 const eventKey = hyphenate(event.key);
10917 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
10918 return fn(event);
10919 }
10920 };
10921};
10922
10923const vShow = {
10924 beforeMount(el, { value }, { transition }) {
10925 el._vod = el.style.display === 'none' ? '' : el.style.display;
10926 if (transition && value) {
10927 transition.beforeEnter(el);
10928 }
10929 else {
10930 setDisplay(el, value);
10931 }
10932 },
10933 mounted(el, { value }, { transition }) {
10934 if (transition && value) {
10935 transition.enter(el);
10936 }
10937 },
10938 updated(el, { value, oldValue }, { transition }) {
10939 if (!value === !oldValue)
10940 return;
10941 if (transition) {
10942 if (value) {
10943 transition.beforeEnter(el);
10944 setDisplay(el, true);
10945 transition.enter(el);
10946 }
10947 else {
10948 transition.leave(el, () => {
10949 setDisplay(el, false);
10950 });
10951 }
10952 }
10953 else {
10954 setDisplay(el, value);
10955 }
10956 },
10957 beforeUnmount(el, { value }) {
10958 setDisplay(el, value);
10959 }
10960};
10961function setDisplay(el, value) {
10962 el.style.display = value ? el._vod : 'none';
10963}
10964
10965const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps);
10966// lazy create the renderer - this makes core renderer logic tree-shakable
10967// in case the user only imports reactivity utilities from Vue.
10968let renderer;
10969let enabledHydration = false;
10970function ensureRenderer() {
10971 return (renderer ||
10972 (renderer = createRenderer(rendererOptions)));
10973}
10974function ensureHydrationRenderer() {
10975 renderer = enabledHydration
10976 ? renderer
10977 : createHydrationRenderer(rendererOptions);
10978 enabledHydration = true;
10979 return renderer;
10980}
10981// use explicit type casts here to avoid import() calls in rolled-up d.ts
10982const render = ((...args) => {
10983 ensureRenderer().render(...args);
10984});
10985const hydrate = ((...args) => {
10986 ensureHydrationRenderer().hydrate(...args);
10987});
10988const createApp = ((...args) => {
10989 const app = ensureRenderer().createApp(...args);
10990 {
10991 injectNativeTagCheck(app);
10992 injectCompilerOptionsCheck(app);
10993 }
10994 const { mount } = app;
10995 app.mount = (containerOrSelector) => {
10996 const container = normalizeContainer(containerOrSelector);
10997 if (!container)
10998 return;
10999 const component = app._component;
11000 if (!isFunction(component) && !component.render && !component.template) {
11001 // __UNSAFE__
11002 // Reason: potential execution of JS expressions in in-DOM template.
11003 // The user must make sure the in-DOM template is trusted. If it's
11004 // rendered by the server, the template should not contain any user data.
11005 component.template = container.innerHTML;
11006 }
11007 // clear content before mounting
11008 container.innerHTML = '';
11009 const proxy = mount(container, false, container instanceof SVGElement);
11010 if (container instanceof Element) {
11011 container.removeAttribute('v-cloak');
11012 container.setAttribute('data-v-app', '');
11013 }
11014 return proxy;
11015 };
11016 return app;
11017});
11018const createSSRApp = ((...args) => {
11019 const app = ensureHydrationRenderer().createApp(...args);
11020 {
11021 injectNativeTagCheck(app);
11022 injectCompilerOptionsCheck(app);
11023 }
11024 const { mount } = app;
11025 app.mount = (containerOrSelector) => {
11026 const container = normalizeContainer(containerOrSelector);
11027 if (container) {
11028 return mount(container, true, container instanceof SVGElement);
11029 }
11030 };
11031 return app;
11032});
11033function injectNativeTagCheck(app) {
11034 // Inject `isNativeTag`
11035 // this is used for component name validation (dev only)
11036 Object.defineProperty(app.config, 'isNativeTag', {
11037 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
11038 writable: false
11039 });
11040}
11041// dev only
11042function injectCompilerOptionsCheck(app) {
11043 if (isRuntimeOnly()) {
11044 const isCustomElement = app.config.isCustomElement;
11045 Object.defineProperty(app.config, 'isCustomElement', {
11046 get() {
11047 return isCustomElement;
11048 },
11049 set() {
11050 warn(`The \`isCustomElement\` config option is deprecated. Use ` +
11051 `\`compilerOptions.isCustomElement\` instead.`);
11052 }
11053 });
11054 const compilerOptions = app.config.compilerOptions;
11055 const msg = `The \`compilerOptions\` config option is only respected when using ` +
11056 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
11057 `Since you are using the runtime-only build, \`compilerOptions\` ` +
11058 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
11059 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
11060 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
11061 `- 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`;
11062 Object.defineProperty(app.config, 'compilerOptions', {
11063 get() {
11064 warn(msg);
11065 return compilerOptions;
11066 },
11067 set() {
11068 warn(msg);
11069 }
11070 });
11071 }
11072}
11073function normalizeContainer(container) {
11074 if (isString(container)) {
11075 const res = document.querySelector(container);
11076 if (!res) {
11077 warn(`Failed to mount app: mount target selector "${container}" returned null.`);
11078 }
11079 return res;
11080 }
11081 if (window.ShadowRoot &&
11082 container instanceof window.ShadowRoot &&
11083 container.mode === 'closed') {
11084 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
11085 }
11086 return container;
11087}
11088/**
11089 * @internal
11090 */
11091const initDirectivesForSSR = NOOP;
11092
11093var runtimeDom = /*#__PURE__*/Object.freeze({
11094 __proto__: null,
11095 BaseTransition: BaseTransition,
11096 Comment: Comment,
11097 EffectScope: EffectScope,
11098 Fragment: Fragment,
11099 KeepAlive: KeepAlive,
11100 ReactiveEffect: ReactiveEffect,
11101 Static: Static,
11102 Suspense: Suspense,
11103 Teleport: Teleport,
11104 Text: Text,
11105 Transition: Transition,
11106 TransitionGroup: TransitionGroup,
11107 VueElement: VueElement,
11108 assertNumber: assertNumber,
11109 callWithAsyncErrorHandling: callWithAsyncErrorHandling,
11110 callWithErrorHandling: callWithErrorHandling,
11111 camelize: camelize,
11112 capitalize: capitalize,
11113 cloneVNode: cloneVNode,
11114 compatUtils: compatUtils,
11115 computed: computed,
11116 createApp: createApp,
11117 createBlock: createBlock,
11118 createCommentVNode: createCommentVNode,
11119 createElementBlock: createElementBlock,
11120 createElementVNode: createBaseVNode,
11121 createHydrationRenderer: createHydrationRenderer,
11122 createPropsRestProxy: createPropsRestProxy,
11123 createRenderer: createRenderer,
11124 createSSRApp: createSSRApp,
11125 createSlots: createSlots,
11126 createStaticVNode: createStaticVNode,
11127 createTextVNode: createTextVNode,
11128 createVNode: createVNode,
11129 customRef: customRef,
11130 defineAsyncComponent: defineAsyncComponent,
11131 defineComponent: defineComponent,
11132 defineCustomElement: defineCustomElement,
11133 defineEmits: defineEmits,
11134 defineExpose: defineExpose,
11135 defineProps: defineProps,
11136 defineSSRCustomElement: defineSSRCustomElement,
11137 get devtools () { return devtools; },
11138 effect: effect,
11139 effectScope: effectScope,
11140 getCurrentInstance: getCurrentInstance,
11141 getCurrentScope: getCurrentScope,
11142 getTransitionRawChildren: getTransitionRawChildren,
11143 guardReactiveProps: guardReactiveProps,
11144 h: h,
11145 handleError: handleError,
11146 hydrate: hydrate,
11147 initCustomFormatter: initCustomFormatter,
11148 initDirectivesForSSR: initDirectivesForSSR,
11149 inject: inject,
11150 isMemoSame: isMemoSame,
11151 isProxy: isProxy,
11152 isReactive: isReactive,
11153 isReadonly: isReadonly,
11154 isRef: isRef,
11155 isRuntimeOnly: isRuntimeOnly,
11156 isShallow: isShallow,
11157 isVNode: isVNode,
11158 markRaw: markRaw,
11159 mergeDefaults: mergeDefaults,
11160 mergeProps: mergeProps,
11161 nextTick: nextTick,
11162 normalizeClass: normalizeClass,
11163 normalizeProps: normalizeProps,
11164 normalizeStyle: normalizeStyle,
11165 onActivated: onActivated,
11166 onBeforeMount: onBeforeMount,
11167 onBeforeUnmount: onBeforeUnmount,
11168 onBeforeUpdate: onBeforeUpdate,
11169 onDeactivated: onDeactivated,
11170 onErrorCaptured: onErrorCaptured,
11171 onMounted: onMounted,
11172 onRenderTracked: onRenderTracked,
11173 onRenderTriggered: onRenderTriggered,
11174 onScopeDispose: onScopeDispose,
11175 onServerPrefetch: onServerPrefetch,
11176 onUnmounted: onUnmounted,
11177 onUpdated: onUpdated,
11178 openBlock: openBlock,
11179 popScopeId: popScopeId,
11180 provide: provide,
11181 proxyRefs: proxyRefs,
11182 pushScopeId: pushScopeId,
11183 queuePostFlushCb: queuePostFlushCb,
11184 reactive: reactive,
11185 readonly: readonly,
11186 ref: ref,
11187 registerRuntimeCompiler: registerRuntimeCompiler,
11188 render: render,
11189 renderList: renderList,
11190 renderSlot: renderSlot,
11191 resolveComponent: resolveComponent,
11192 resolveDirective: resolveDirective,
11193 resolveDynamicComponent: resolveDynamicComponent,
11194 resolveFilter: resolveFilter,
11195 resolveTransitionHooks: resolveTransitionHooks,
11196 setBlockTracking: setBlockTracking,
11197 setDevtoolsHook: setDevtoolsHook,
11198 setTransitionHooks: setTransitionHooks,
11199 shallowReactive: shallowReactive,
11200 shallowReadonly: shallowReadonly,
11201 shallowRef: shallowRef,
11202 ssrContextKey: ssrContextKey,
11203 ssrUtils: ssrUtils,
11204 stop: stop,
11205 toDisplayString: toDisplayString,
11206 toHandlerKey: toHandlerKey,
11207 toHandlers: toHandlers,
11208 toRaw: toRaw,
11209 toRef: toRef,
11210 toRefs: toRefs,
11211 transformVNodeArgs: transformVNodeArgs,
11212 triggerRef: triggerRef,
11213 unref: unref,
11214 useAttrs: useAttrs,
11215 useCssModule: useCssModule,
11216 useCssVars: useCssVars,
11217 useSSRContext: useSSRContext,
11218 useSlots: useSlots,
11219 useTransitionState: useTransitionState,
11220 vModelCheckbox: vModelCheckbox,
11221 vModelDynamic: vModelDynamic,
11222 vModelRadio: vModelRadio,
11223 vModelSelect: vModelSelect,
11224 vModelText: vModelText,
11225 vShow: vShow,
11226 version: version,
11227 warn: warn,
11228 watch: watch,
11229 watchEffect: watchEffect,
11230 watchPostEffect: watchPostEffect,
11231 watchSyncEffect: watchSyncEffect,
11232 withAsyncContext: withAsyncContext,
11233 withCtx: withCtx,
11234 withDefaults: withDefaults,
11235 withDirectives: withDirectives,
11236 withKeys: withKeys,
11237 withMemo: withMemo,
11238 withModifiers: withModifiers,
11239 withScopeId: withScopeId
11240});
11241
11242function initDev() {
11243 {
11244 /* istanbul ignore if */
11245 {
11246 console.info(`You are running a development build of Vue.\n` +
11247 `Make sure to use the production build (*.prod.js) when deploying for production.`);
11248 }
11249 initCustomFormatter();
11250 }
11251}
11252
11253function defaultOnError(error) {
11254 throw error;
11255}
11256function defaultOnWarn(msg) {
11257 console.warn(`[Vue warn] ${msg.message}`);
11258}
11259function createCompilerError(code, loc, messages, additionalMessage) {
11260 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
11261 ;
11262 const error = new SyntaxError(String(msg));
11263 error.code = code;
11264 error.loc = loc;
11265 return error;
11266}
11267const errorMessages = {
11268 // parse errors
11269 [0 /* ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
11270 [1 /* ErrorCodes.CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
11271 [2 /* ErrorCodes.DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
11272 [3 /* ErrorCodes.END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
11273 [4 /* ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
11274 [5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
11275 [6 /* ErrorCodes.EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
11276 [7 /* ErrorCodes.EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
11277 [8 /* ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
11278 [9 /* ErrorCodes.EOF_IN_TAG */]: 'Unexpected EOF in tag.',
11279 [10 /* ErrorCodes.INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
11280 [11 /* ErrorCodes.INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
11281 [12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
11282 [13 /* ErrorCodes.MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
11283 [14 /* ErrorCodes.MISSING_END_TAG_NAME */]: 'End tag name was expected.',
11284 [15 /* ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
11285 [16 /* ErrorCodes.NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
11286 [17 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
11287 [18 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
11288 [19 /* ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
11289 [21 /* ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
11290 [20 /* ErrorCodes.UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
11291 [22 /* ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
11292 // Vue-specific parse errors
11293 [23 /* ErrorCodes.X_INVALID_END_TAG */]: 'Invalid end tag.',
11294 [24 /* ErrorCodes.X_MISSING_END_TAG */]: 'Element is missing end tag.',
11295 [25 /* ErrorCodes.X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
11296 [27 /* ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
11297 'Note that dynamic directive argument cannot contain spaces.',
11298 [26 /* ErrorCodes.X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
11299 // transform errors
11300 [28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
11301 [29 /* ErrorCodes.X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
11302 [30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
11303 [31 /* ErrorCodes.X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
11304 [32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
11305 [33 /* ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
11306 [34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
11307 [35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
11308 [36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
11309 [37 /* ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>. ` +
11310 `When there are multiple named slots, all slots should use <template> ` +
11311 `syntax to avoid scope ambiguity.`,
11312 [38 /* ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
11313 [39 /* ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
11314 `default slot. These children will be ignored.`,
11315 [40 /* ErrorCodes.X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
11316 [41 /* ErrorCodes.X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
11317 [42 /* ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
11318 [43 /* ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
11319 [44 /* ErrorCodes.X_V_MODEL_ON_PROPS */]: `v-model cannot be used on a prop, because local prop bindings are not writable.\nUse a v-bind binding combined with a v-on listener that emits update:x event instead.`,
11320 [45 /* ErrorCodes.X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
11321 [46 /* ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
11322 // generic errors
11323 [47 /* ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
11324 [48 /* ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
11325 [49 /* ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
11326 [50 /* ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
11327 // just to fulfill types
11328 [51 /* ErrorCodes.__EXTEND_POINT__ */]: ``
11329};
11330
11331const FRAGMENT = Symbol(`Fragment` );
11332const TELEPORT = Symbol(`Teleport` );
11333const SUSPENSE = Symbol(`Suspense` );
11334const KEEP_ALIVE = Symbol(`KeepAlive` );
11335const BASE_TRANSITION = Symbol(`BaseTransition` );
11336const OPEN_BLOCK = Symbol(`openBlock` );
11337const CREATE_BLOCK = Symbol(`createBlock` );
11338const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` );
11339const CREATE_VNODE = Symbol(`createVNode` );
11340const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` );
11341const CREATE_COMMENT = Symbol(`createCommentVNode` );
11342const CREATE_TEXT = Symbol(`createTextVNode` );
11343const CREATE_STATIC = Symbol(`createStaticVNode` );
11344const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
11345const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
11346const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
11347const RESOLVE_FILTER = Symbol(`resolveFilter` );
11348const WITH_DIRECTIVES = Symbol(`withDirectives` );
11349const RENDER_LIST = Symbol(`renderList` );
11350const RENDER_SLOT = Symbol(`renderSlot` );
11351const CREATE_SLOTS = Symbol(`createSlots` );
11352const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
11353const MERGE_PROPS = Symbol(`mergeProps` );
11354const NORMALIZE_CLASS = Symbol(`normalizeClass` );
11355const NORMALIZE_STYLE = Symbol(`normalizeStyle` );
11356const NORMALIZE_PROPS = Symbol(`normalizeProps` );
11357const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` );
11358const TO_HANDLERS = Symbol(`toHandlers` );
11359const CAMELIZE = Symbol(`camelize` );
11360const CAPITALIZE = Symbol(`capitalize` );
11361const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
11362const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
11363const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
11364const POP_SCOPE_ID = Symbol(`popScopeId` );
11365const WITH_CTX = Symbol(`withCtx` );
11366const UNREF = Symbol(`unref` );
11367const IS_REF = Symbol(`isRef` );
11368const WITH_MEMO = Symbol(`withMemo` );
11369const IS_MEMO_SAME = Symbol(`isMemoSame` );
11370// Name mapping for runtime helpers that need to be imported from 'vue' in
11371// generated code. Make sure these are correctly exported in the runtime!
11372const helperNameMap = {
11373 [FRAGMENT]: `Fragment`,
11374 [TELEPORT]: `Teleport`,
11375 [SUSPENSE]: `Suspense`,
11376 [KEEP_ALIVE]: `KeepAlive`,
11377 [BASE_TRANSITION]: `BaseTransition`,
11378 [OPEN_BLOCK]: `openBlock`,
11379 [CREATE_BLOCK]: `createBlock`,
11380 [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
11381 [CREATE_VNODE]: `createVNode`,
11382 [CREATE_ELEMENT_VNODE]: `createElementVNode`,
11383 [CREATE_COMMENT]: `createCommentVNode`,
11384 [CREATE_TEXT]: `createTextVNode`,
11385 [CREATE_STATIC]: `createStaticVNode`,
11386 [RESOLVE_COMPONENT]: `resolveComponent`,
11387 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
11388 [RESOLVE_DIRECTIVE]: `resolveDirective`,
11389 [RESOLVE_FILTER]: `resolveFilter`,
11390 [WITH_DIRECTIVES]: `withDirectives`,
11391 [RENDER_LIST]: `renderList`,
11392 [RENDER_SLOT]: `renderSlot`,
11393 [CREATE_SLOTS]: `createSlots`,
11394 [TO_DISPLAY_STRING]: `toDisplayString`,
11395 [MERGE_PROPS]: `mergeProps`,
11396 [NORMALIZE_CLASS]: `normalizeClass`,
11397 [NORMALIZE_STYLE]: `normalizeStyle`,
11398 [NORMALIZE_PROPS]: `normalizeProps`,
11399 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
11400 [TO_HANDLERS]: `toHandlers`,
11401 [CAMELIZE]: `camelize`,
11402 [CAPITALIZE]: `capitalize`,
11403 [TO_HANDLER_KEY]: `toHandlerKey`,
11404 [SET_BLOCK_TRACKING]: `setBlockTracking`,
11405 [PUSH_SCOPE_ID]: `pushScopeId`,
11406 [POP_SCOPE_ID]: `popScopeId`,
11407 [WITH_CTX]: `withCtx`,
11408 [UNREF]: `unref`,
11409 [IS_REF]: `isRef`,
11410 [WITH_MEMO]: `withMemo`,
11411 [IS_MEMO_SAME]: `isMemoSame`
11412};
11413function registerRuntimeHelpers(helpers) {
11414 Object.getOwnPropertySymbols(helpers).forEach(s => {
11415 helperNameMap[s] = helpers[s];
11416 });
11417}
11418
11419// AST Utilities ---------------------------------------------------------------
11420// Some expressions, e.g. sequence and conditional expressions, are never
11421// associated with template nodes, so their source locations are just a stub.
11422// Container types like CompoundExpression also don't need a real location.
11423const locStub = {
11424 source: '',
11425 start: { line: 1, column: 1, offset: 0 },
11426 end: { line: 1, column: 1, offset: 0 }
11427};
11428function createRoot(children, loc = locStub) {
11429 return {
11430 type: 0 /* NodeTypes.ROOT */,
11431 children,
11432 helpers: new Set(),
11433 components: [],
11434 directives: [],
11435 hoists: [],
11436 imports: [],
11437 cached: 0,
11438 temps: 0,
11439 codegenNode: undefined,
11440 loc
11441 };
11442}
11443function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
11444 if (context) {
11445 if (isBlock) {
11446 context.helper(OPEN_BLOCK);
11447 context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
11448 }
11449 else {
11450 context.helper(getVNodeHelper(context.inSSR, isComponent));
11451 }
11452 if (directives) {
11453 context.helper(WITH_DIRECTIVES);
11454 }
11455 }
11456 return {
11457 type: 13 /* NodeTypes.VNODE_CALL */,
11458 tag,
11459 props,
11460 children,
11461 patchFlag,
11462 dynamicProps,
11463 directives,
11464 isBlock,
11465 disableTracking,
11466 isComponent,
11467 loc
11468 };
11469}
11470function createArrayExpression(elements, loc = locStub) {
11471 return {
11472 type: 17 /* NodeTypes.JS_ARRAY_EXPRESSION */,
11473 loc,
11474 elements
11475 };
11476}
11477function createObjectExpression(properties, loc = locStub) {
11478 return {
11479 type: 15 /* NodeTypes.JS_OBJECT_EXPRESSION */,
11480 loc,
11481 properties
11482 };
11483}
11484function createObjectProperty(key, value) {
11485 return {
11486 type: 16 /* NodeTypes.JS_PROPERTY */,
11487 loc: locStub,
11488 key: isString(key) ? createSimpleExpression(key, true) : key,
11489 value
11490 };
11491}
11492function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* ConstantTypes.NOT_CONSTANT */) {
11493 return {
11494 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
11495 loc,
11496 content,
11497 isStatic,
11498 constType: isStatic ? 3 /* ConstantTypes.CAN_STRINGIFY */ : constType
11499 };
11500}
11501function createCompoundExpression(children, loc = locStub) {
11502 return {
11503 type: 8 /* NodeTypes.COMPOUND_EXPRESSION */,
11504 loc,
11505 children
11506 };
11507}
11508function createCallExpression(callee, args = [], loc = locStub) {
11509 return {
11510 type: 14 /* NodeTypes.JS_CALL_EXPRESSION */,
11511 loc,
11512 callee,
11513 arguments: args
11514 };
11515}
11516function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
11517 return {
11518 type: 18 /* NodeTypes.JS_FUNCTION_EXPRESSION */,
11519 params,
11520 returns,
11521 newline,
11522 isSlot,
11523 loc
11524 };
11525}
11526function createConditionalExpression(test, consequent, alternate, newline = true) {
11527 return {
11528 type: 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */,
11529 test,
11530 consequent,
11531 alternate,
11532 newline,
11533 loc: locStub
11534 };
11535}
11536function createCacheExpression(index, value, isVNode = false) {
11537 return {
11538 type: 20 /* NodeTypes.JS_CACHE_EXPRESSION */,
11539 index,
11540 value,
11541 isVNode,
11542 loc: locStub
11543 };
11544}
11545function createBlockStatement(body) {
11546 return {
11547 type: 21 /* NodeTypes.JS_BLOCK_STATEMENT */,
11548 body,
11549 loc: locStub
11550 };
11551}
11552
11553const isStaticExp = (p) => p.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && p.isStatic;
11554const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
11555function isCoreComponent(tag) {
11556 if (isBuiltInType(tag, 'Teleport')) {
11557 return TELEPORT;
11558 }
11559 else if (isBuiltInType(tag, 'Suspense')) {
11560 return SUSPENSE;
11561 }
11562 else if (isBuiltInType(tag, 'KeepAlive')) {
11563 return KEEP_ALIVE;
11564 }
11565 else if (isBuiltInType(tag, 'BaseTransition')) {
11566 return BASE_TRANSITION;
11567 }
11568}
11569const nonIdentifierRE = /^\d|[^\$\w]/;
11570const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
11571const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
11572const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
11573const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
11574/**
11575 * Simple lexer to check if an expression is a member expression. This is
11576 * lax and only checks validity at the root level (i.e. does not validate exps
11577 * inside square brackets), but it's ok since these are only used on template
11578 * expressions and false positives are invalid expressions in the first place.
11579 */
11580const isMemberExpressionBrowser = (path) => {
11581 // remove whitespaces around . or [ first
11582 path = path.trim().replace(whitespaceRE, s => s.trim());
11583 let state = 0 /* MemberExpLexState.inMemberExp */;
11584 let stateStack = [];
11585 let currentOpenBracketCount = 0;
11586 let currentOpenParensCount = 0;
11587 let currentStringType = null;
11588 for (let i = 0; i < path.length; i++) {
11589 const char = path.charAt(i);
11590 switch (state) {
11591 case 0 /* MemberExpLexState.inMemberExp */:
11592 if (char === '[') {
11593 stateStack.push(state);
11594 state = 1 /* MemberExpLexState.inBrackets */;
11595 currentOpenBracketCount++;
11596 }
11597 else if (char === '(') {
11598 stateStack.push(state);
11599 state = 2 /* MemberExpLexState.inParens */;
11600 currentOpenParensCount++;
11601 }
11602 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
11603 return false;
11604 }
11605 break;
11606 case 1 /* MemberExpLexState.inBrackets */:
11607 if (char === `'` || char === `"` || char === '`') {
11608 stateStack.push(state);
11609 state = 3 /* MemberExpLexState.inString */;
11610 currentStringType = char;
11611 }
11612 else if (char === `[`) {
11613 currentOpenBracketCount++;
11614 }
11615 else if (char === `]`) {
11616 if (!--currentOpenBracketCount) {
11617 state = stateStack.pop();
11618 }
11619 }
11620 break;
11621 case 2 /* MemberExpLexState.inParens */:
11622 if (char === `'` || char === `"` || char === '`') {
11623 stateStack.push(state);
11624 state = 3 /* MemberExpLexState.inString */;
11625 currentStringType = char;
11626 }
11627 else if (char === `(`) {
11628 currentOpenParensCount++;
11629 }
11630 else if (char === `)`) {
11631 // if the exp ends as a call then it should not be considered valid
11632 if (i === path.length - 1) {
11633 return false;
11634 }
11635 if (!--currentOpenParensCount) {
11636 state = stateStack.pop();
11637 }
11638 }
11639 break;
11640 case 3 /* MemberExpLexState.inString */:
11641 if (char === currentStringType) {
11642 state = stateStack.pop();
11643 currentStringType = null;
11644 }
11645 break;
11646 }
11647 }
11648 return !currentOpenBracketCount && !currentOpenParensCount;
11649};
11650const isMemberExpression = isMemberExpressionBrowser
11651 ;
11652function getInnerRange(loc, offset, length) {
11653 const source = loc.source.slice(offset, offset + length);
11654 const newLoc = {
11655 source,
11656 start: advancePositionWithClone(loc.start, loc.source, offset),
11657 end: loc.end
11658 };
11659 if (length != null) {
11660 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
11661 }
11662 return newLoc;
11663}
11664function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
11665 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
11666}
11667// advance by mutation without cloning (for performance reasons), since this
11668// gets called a lot in the parser
11669function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
11670 let linesCount = 0;
11671 let lastNewLinePos = -1;
11672 for (let i = 0; i < numberOfCharacters; i++) {
11673 if (source.charCodeAt(i) === 10 /* newline char code */) {
11674 linesCount++;
11675 lastNewLinePos = i;
11676 }
11677 }
11678 pos.offset += numberOfCharacters;
11679 pos.line += linesCount;
11680 pos.column =
11681 lastNewLinePos === -1
11682 ? pos.column + numberOfCharacters
11683 : numberOfCharacters - lastNewLinePos;
11684 return pos;
11685}
11686function assert(condition, msg) {
11687 /* istanbul ignore if */
11688 if (!condition) {
11689 throw new Error(msg || `unexpected compiler condition`);
11690 }
11691}
11692function findDir(node, name, allowEmpty = false) {
11693 for (let i = 0; i < node.props.length; i++) {
11694 const p = node.props[i];
11695 if (p.type === 7 /* NodeTypes.DIRECTIVE */ &&
11696 (allowEmpty || p.exp) &&
11697 (isString(name) ? p.name === name : name.test(p.name))) {
11698 return p;
11699 }
11700 }
11701}
11702function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11703 for (let i = 0; i < node.props.length; i++) {
11704 const p = node.props[i];
11705 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
11706 if (dynamicOnly)
11707 continue;
11708 if (p.name === name && (p.value || allowEmpty)) {
11709 return p;
11710 }
11711 }
11712 else if (p.name === 'bind' &&
11713 (p.exp || allowEmpty) &&
11714 isStaticArgOf(p.arg, name)) {
11715 return p;
11716 }
11717 }
11718}
11719function isStaticArgOf(arg, name) {
11720 return !!(arg && isStaticExp(arg) && arg.content === name);
11721}
11722function hasDynamicKeyVBind(node) {
11723 return node.props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ &&
11724 p.name === 'bind' &&
11725 (!p.arg || // v-bind="obj"
11726 p.arg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
11727 !p.arg.isStatic) // v-bind:[foo]
11728 );
11729}
11730function isText$1(node) {
11731 return node.type === 5 /* NodeTypes.INTERPOLATION */ || node.type === 2 /* NodeTypes.TEXT */;
11732}
11733function isVSlot(p) {
11734 return p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'slot';
11735}
11736function isTemplateNode(node) {
11737 return (node.type === 1 /* NodeTypes.ELEMENT */ && node.tagType === 3 /* ElementTypes.TEMPLATE */);
11738}
11739function isSlotOutlet(node) {
11740 return node.type === 1 /* NodeTypes.ELEMENT */ && node.tagType === 2 /* ElementTypes.SLOT */;
11741}
11742function getVNodeHelper(ssr, isComponent) {
11743 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
11744}
11745function getVNodeBlockHelper(ssr, isComponent) {
11746 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
11747}
11748const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
11749function getUnnormalizedProps(props, callPath = []) {
11750 if (props &&
11751 !isString(props) &&
11752 props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
11753 const callee = props.callee;
11754 if (!isString(callee) && propsHelperSet.has(callee)) {
11755 return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
11756 }
11757 }
11758 return [props, callPath];
11759}
11760function injectProp(node, prop, context) {
11761 let propsWithInjection;
11762 /**
11763 * 1. mergeProps(...)
11764 * 2. toHandlers(...)
11765 * 3. normalizeProps(...)
11766 * 4. normalizeProps(guardReactiveProps(...))
11767 *
11768 * we need to get the real props before normalization
11769 */
11770 let props = node.type === 13 /* NodeTypes.VNODE_CALL */ ? node.props : node.arguments[2];
11771 let callPath = [];
11772 let parentCall;
11773 if (props &&
11774 !isString(props) &&
11775 props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
11776 const ret = getUnnormalizedProps(props);
11777 props = ret[0];
11778 callPath = ret[1];
11779 parentCall = callPath[callPath.length - 1];
11780 }
11781 if (props == null || isString(props)) {
11782 propsWithInjection = createObjectExpression([prop]);
11783 }
11784 else if (props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
11785 // merged props... add ours
11786 // only inject key to object literal if it's the first argument so that
11787 // if doesn't override user provided keys
11788 const first = props.arguments[0];
11789 if (!isString(first) && first.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) {
11790 // #6631
11791 if (!hasProp(prop, first)) {
11792 first.properties.unshift(prop);
11793 }
11794 }
11795 else {
11796 if (props.callee === TO_HANDLERS) {
11797 // #2366
11798 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11799 createObjectExpression([prop]),
11800 props
11801 ]);
11802 }
11803 else {
11804 props.arguments.unshift(createObjectExpression([prop]));
11805 }
11806 }
11807 !propsWithInjection && (propsWithInjection = props);
11808 }
11809 else if (props.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) {
11810 if (!hasProp(prop, props)) {
11811 props.properties.unshift(prop);
11812 }
11813 propsWithInjection = props;
11814 }
11815 else {
11816 // single v-bind with expression, return a merged replacement
11817 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11818 createObjectExpression([prop]),
11819 props
11820 ]);
11821 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
11822 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
11823 // the `guardReactiveProps` will no longer be needed
11824 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
11825 parentCall = callPath[callPath.length - 2];
11826 }
11827 }
11828 if (node.type === 13 /* NodeTypes.VNODE_CALL */) {
11829 if (parentCall) {
11830 parentCall.arguments[0] = propsWithInjection;
11831 }
11832 else {
11833 node.props = propsWithInjection;
11834 }
11835 }
11836 else {
11837 if (parentCall) {
11838 parentCall.arguments[0] = propsWithInjection;
11839 }
11840 else {
11841 node.arguments[2] = propsWithInjection;
11842 }
11843 }
11844}
11845// check existing key to avoid overriding user provided keys
11846function hasProp(prop, props) {
11847 let result = false;
11848 if (prop.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
11849 const propKeyName = prop.key.content;
11850 result = props.properties.some(p => p.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
11851 p.key.content === propKeyName);
11852 }
11853 return result;
11854}
11855function toValidAssetId(name, type) {
11856 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
11857 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
11858 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
11859 })}`;
11860}
11861function getMemoedVNodeCall(node) {
11862 if (node.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
11863 return node.arguments[1].returns;
11864 }
11865 else {
11866 return node;
11867 }
11868}
11869function makeBlock(node, { helper, removeHelper, inSSR }) {
11870 if (!node.isBlock) {
11871 node.isBlock = true;
11872 removeHelper(getVNodeHelper(inSSR, node.isComponent));
11873 helper(OPEN_BLOCK);
11874 helper(getVNodeBlockHelper(inSSR, node.isComponent));
11875 }
11876}
11877
11878const deprecationData = {
11879 ["COMPILER_IS_ON_ELEMENT" /* CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT */]: {
11880 message: `Platform-native elements with "is" prop will no longer be ` +
11881 `treated as components in Vue 3 unless the "is" value is explicitly ` +
11882 `prefixed with "vue:".`,
11883 link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
11884 },
11885 ["COMPILER_V_BIND_SYNC" /* CompilerDeprecationTypes.COMPILER_V_BIND_SYNC */]: {
11886 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
11887 `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
11888 `\`v-model:${key}\`.`,
11889 link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
11890 },
11891 ["COMPILER_V_BIND_PROP" /* CompilerDeprecationTypes.COMPILER_V_BIND_PROP */]: {
11892 message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
11893 `Vue 3 will automatically set a binding as DOM property when appropriate.`
11894 },
11895 ["COMPILER_V_BIND_OBJECT_ORDER" /* CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER */]: {
11896 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
11897 `object spread: it will now overwrite an existing non-mergeable attribute ` +
11898 `that appears before v-bind in the case of conflict. ` +
11899 `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
11900 `You can also suppress this warning if the usage is intended.`,
11901 link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
11902 },
11903 ["COMPILER_V_ON_NATIVE" /* CompilerDeprecationTypes.COMPILER_V_ON_NATIVE */]: {
11904 message: `.native modifier for v-on has been removed as is no longer necessary.`,
11905 link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
11906 },
11907 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* CompilerDeprecationTypes.COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
11908 message: `v-if / v-for precedence when used on the same element has changed ` +
11909 `in Vue 3: v-if now takes higher precedence and will no longer have ` +
11910 `access to v-for scope variables. It is best to avoid the ambiguity ` +
11911 `with <template> tags or use a computed property that filters v-for ` +
11912 `data source.`,
11913 link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
11914 },
11915 ["COMPILER_NATIVE_TEMPLATE" /* CompilerDeprecationTypes.COMPILER_NATIVE_TEMPLATE */]: {
11916 message: `<template> with no special directives will render as a native template ` +
11917 `element instead of its inner content in Vue 3.`
11918 },
11919 ["COMPILER_INLINE_TEMPLATE" /* CompilerDeprecationTypes.COMPILER_INLINE_TEMPLATE */]: {
11920 message: `"inline-template" has been removed in Vue 3.`,
11921 link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
11922 },
11923 ["COMPILER_FILTER" /* CompilerDeprecationTypes.COMPILER_FILTERS */]: {
11924 message: `filters have been removed in Vue 3. ` +
11925 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
11926 `Use method calls or computed properties instead.`,
11927 link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
11928 }
11929};
11930function getCompatValue(key, context) {
11931 const config = context.options
11932 ? context.options.compatConfig
11933 : context.compatConfig;
11934 const value = config && config[key];
11935 if (key === 'MODE') {
11936 return value || 3; // compiler defaults to v3 behavior
11937 }
11938 else {
11939 return value;
11940 }
11941}
11942function isCompatEnabled(key, context) {
11943 const mode = getCompatValue('MODE', context);
11944 const value = getCompatValue(key, context);
11945 // in v3 mode, only enable if explicitly set to true
11946 // otherwise enable for any non-false value
11947 return mode === 3 ? value === true : value !== false;
11948}
11949function checkCompatEnabled(key, context, loc, ...args) {
11950 const enabled = isCompatEnabled(key, context);
11951 if (enabled) {
11952 warnDeprecation(key, context, loc, ...args);
11953 }
11954 return enabled;
11955}
11956function warnDeprecation(key, context, loc, ...args) {
11957 const val = getCompatValue(key, context);
11958 if (val === 'suppress-warning') {
11959 return;
11960 }
11961 const { message, link } = deprecationData[key];
11962 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
11963 const err = new SyntaxError(msg);
11964 err.code = key;
11965 if (loc)
11966 err.loc = loc;
11967 context.onWarn(err);
11968}
11969
11970// The default decoder only provides escapes for characters reserved as part of
11971// the template syntax, and is only used if the custom renderer did not provide
11972// a platform-specific decoder.
11973const decodeRE = /&(gt|lt|amp|apos|quot);/g;
11974const decodeMap = {
11975 gt: '>',
11976 lt: '<',
11977 amp: '&',
11978 apos: "'",
11979 quot: '"'
11980};
11981const defaultParserOptions = {
11982 delimiters: [`{{`, `}}`],
11983 getNamespace: () => 0 /* Namespaces.HTML */,
11984 getTextMode: () => 0 /* TextModes.DATA */,
11985 isVoidTag: NO,
11986 isPreTag: NO,
11987 isCustomElement: NO,
11988 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
11989 onError: defaultOnError,
11990 onWarn: defaultOnWarn,
11991 comments: true
11992};
11993function baseParse(content, options = {}) {
11994 const context = createParserContext(content, options);
11995 const start = getCursor(context);
11996 return createRoot(parseChildren(context, 0 /* TextModes.DATA */, []), getSelection(context, start));
11997}
11998function createParserContext(content, rawOptions) {
11999 const options = extend({}, defaultParserOptions);
12000 let key;
12001 for (key in rawOptions) {
12002 // @ts-ignore
12003 options[key] =
12004 rawOptions[key] === undefined
12005 ? defaultParserOptions[key]
12006 : rawOptions[key];
12007 }
12008 return {
12009 options,
12010 column: 1,
12011 line: 1,
12012 offset: 0,
12013 originalSource: content,
12014 source: content,
12015 inPre: false,
12016 inVPre: false,
12017 onWarn: options.onWarn
12018 };
12019}
12020function parseChildren(context, mode, ancestors) {
12021 const parent = last(ancestors);
12022 const ns = parent ? parent.ns : 0 /* Namespaces.HTML */;
12023 const nodes = [];
12024 while (!isEnd(context, mode, ancestors)) {
12025 const s = context.source;
12026 let node = undefined;
12027 if (mode === 0 /* TextModes.DATA */ || mode === 1 /* TextModes.RCDATA */) {
12028 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
12029 // '{{'
12030 node = parseInterpolation(context, mode);
12031 }
12032 else if (mode === 0 /* TextModes.DATA */ && s[0] === '<') {
12033 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
12034 if (s.length === 1) {
12035 emitError(context, 5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */, 1);
12036 }
12037 else if (s[1] === '!') {
12038 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
12039 if (startsWith(s, '<!--')) {
12040 node = parseComment(context);
12041 }
12042 else if (startsWith(s, '<!DOCTYPE')) {
12043 // Ignore DOCTYPE by a limitation.
12044 node = parseBogusComment(context);
12045 }
12046 else if (startsWith(s, '<![CDATA[')) {
12047 if (ns !== 0 /* Namespaces.HTML */) {
12048 node = parseCDATA(context, ancestors);
12049 }
12050 else {
12051 emitError(context, 1 /* ErrorCodes.CDATA_IN_HTML_CONTENT */);
12052 node = parseBogusComment(context);
12053 }
12054 }
12055 else {
12056 emitError(context, 11 /* ErrorCodes.INCORRECTLY_OPENED_COMMENT */);
12057 node = parseBogusComment(context);
12058 }
12059 }
12060 else if (s[1] === '/') {
12061 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
12062 if (s.length === 2) {
12063 emitError(context, 5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */, 2);
12064 }
12065 else if (s[2] === '>') {
12066 emitError(context, 14 /* ErrorCodes.MISSING_END_TAG_NAME */, 2);
12067 advanceBy(context, 3);
12068 continue;
12069 }
12070 else if (/[a-z]/i.test(s[2])) {
12071 emitError(context, 23 /* ErrorCodes.X_INVALID_END_TAG */);
12072 parseTag(context, 1 /* TagType.End */, parent);
12073 continue;
12074 }
12075 else {
12076 emitError(context, 12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
12077 node = parseBogusComment(context);
12078 }
12079 }
12080 else if (/[a-z]/i.test(s[1])) {
12081 node = parseElement(context, ancestors);
12082 }
12083 else if (s[1] === '?') {
12084 emitError(context, 21 /* ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
12085 node = parseBogusComment(context);
12086 }
12087 else {
12088 emitError(context, 12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
12089 }
12090 }
12091 }
12092 if (!node) {
12093 node = parseText(context, mode);
12094 }
12095 if (isArray(node)) {
12096 for (let i = 0; i < node.length; i++) {
12097 pushNode(nodes, node[i]);
12098 }
12099 }
12100 else {
12101 pushNode(nodes, node);
12102 }
12103 }
12104 // Whitespace handling strategy like v2
12105 let removedWhitespace = false;
12106 if (mode !== 2 /* TextModes.RAWTEXT */ && mode !== 1 /* TextModes.RCDATA */) {
12107 const shouldCondense = context.options.whitespace !== 'preserve';
12108 for (let i = 0; i < nodes.length; i++) {
12109 const node = nodes[i];
12110 if (node.type === 2 /* NodeTypes.TEXT */) {
12111 if (!context.inPre) {
12112 if (!/[^\t\r\n\f ]/.test(node.content)) {
12113 const prev = nodes[i - 1];
12114 const next = nodes[i + 1];
12115 // Remove if:
12116 // - the whitespace is the first or last node, or:
12117 // - (condense mode) the whitespace is between twos comments, or:
12118 // - (condense mode) the whitespace is between comment and element, or:
12119 // - (condense mode) the whitespace is between two elements AND contains newline
12120 if (!prev ||
12121 !next ||
12122 (shouldCondense &&
12123 ((prev.type === 3 /* NodeTypes.COMMENT */ &&
12124 next.type === 3 /* NodeTypes.COMMENT */) ||
12125 (prev.type === 3 /* NodeTypes.COMMENT */ &&
12126 next.type === 1 /* NodeTypes.ELEMENT */) ||
12127 (prev.type === 1 /* NodeTypes.ELEMENT */ &&
12128 next.type === 3 /* NodeTypes.COMMENT */) ||
12129 (prev.type === 1 /* NodeTypes.ELEMENT */ &&
12130 next.type === 1 /* NodeTypes.ELEMENT */ &&
12131 /[\r\n]/.test(node.content))))) {
12132 removedWhitespace = true;
12133 nodes[i] = null;
12134 }
12135 else {
12136 // Otherwise, the whitespace is condensed into a single space
12137 node.content = ' ';
12138 }
12139 }
12140 else if (shouldCondense) {
12141 // in condense mode, consecutive whitespaces in text are condensed
12142 // down to a single space.
12143 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
12144 }
12145 }
12146 else {
12147 // #6410 normalize windows newlines in <pre>:
12148 // in SSR, browsers normalize server-rendered \r\n into a single \n
12149 // in the DOM
12150 node.content = node.content.replace(/\r\n/g, '\n');
12151 }
12152 }
12153 // Remove comment nodes if desired by configuration.
12154 else if (node.type === 3 /* NodeTypes.COMMENT */ && !context.options.comments) {
12155 removedWhitespace = true;
12156 nodes[i] = null;
12157 }
12158 }
12159 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
12160 // remove leading newline per html spec
12161 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
12162 const first = nodes[0];
12163 if (first && first.type === 2 /* NodeTypes.TEXT */) {
12164 first.content = first.content.replace(/^\r?\n/, '');
12165 }
12166 }
12167 }
12168 return removedWhitespace ? nodes.filter(Boolean) : nodes;
12169}
12170function pushNode(nodes, node) {
12171 if (node.type === 2 /* NodeTypes.TEXT */) {
12172 const prev = last(nodes);
12173 // Merge if both this and the previous node are text and those are
12174 // consecutive. This happens for cases like "a < b".
12175 if (prev &&
12176 prev.type === 2 /* NodeTypes.TEXT */ &&
12177 prev.loc.end.offset === node.loc.start.offset) {
12178 prev.content += node.content;
12179 prev.loc.end = node.loc.end;
12180 prev.loc.source += node.loc.source;
12181 return;
12182 }
12183 }
12184 nodes.push(node);
12185}
12186function parseCDATA(context, ancestors) {
12187 advanceBy(context, 9);
12188 const nodes = parseChildren(context, 3 /* TextModes.CDATA */, ancestors);
12189 if (context.source.length === 0) {
12190 emitError(context, 6 /* ErrorCodes.EOF_IN_CDATA */);
12191 }
12192 else {
12193 advanceBy(context, 3);
12194 }
12195 return nodes;
12196}
12197function parseComment(context) {
12198 const start = getCursor(context);
12199 let content;
12200 // Regular comment.
12201 const match = /--(\!)?>/.exec(context.source);
12202 if (!match) {
12203 content = context.source.slice(4);
12204 advanceBy(context, context.source.length);
12205 emitError(context, 7 /* ErrorCodes.EOF_IN_COMMENT */);
12206 }
12207 else {
12208 if (match.index <= 3) {
12209 emitError(context, 0 /* ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
12210 }
12211 if (match[1]) {
12212 emitError(context, 10 /* ErrorCodes.INCORRECTLY_CLOSED_COMMENT */);
12213 }
12214 content = context.source.slice(4, match.index);
12215 // Advancing with reporting nested comments.
12216 const s = context.source.slice(0, match.index);
12217 let prevIndex = 1, nestedIndex = 0;
12218 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
12219 advanceBy(context, nestedIndex - prevIndex + 1);
12220 if (nestedIndex + 4 < s.length) {
12221 emitError(context, 16 /* ErrorCodes.NESTED_COMMENT */);
12222 }
12223 prevIndex = nestedIndex + 1;
12224 }
12225 advanceBy(context, match.index + match[0].length - prevIndex + 1);
12226 }
12227 return {
12228 type: 3 /* NodeTypes.COMMENT */,
12229 content,
12230 loc: getSelection(context, start)
12231 };
12232}
12233function parseBogusComment(context) {
12234 const start = getCursor(context);
12235 const contentStart = context.source[1] === '?' ? 1 : 2;
12236 let content;
12237 const closeIndex = context.source.indexOf('>');
12238 if (closeIndex === -1) {
12239 content = context.source.slice(contentStart);
12240 advanceBy(context, context.source.length);
12241 }
12242 else {
12243 content = context.source.slice(contentStart, closeIndex);
12244 advanceBy(context, closeIndex + 1);
12245 }
12246 return {
12247 type: 3 /* NodeTypes.COMMENT */,
12248 content,
12249 loc: getSelection(context, start)
12250 };
12251}
12252function parseElement(context, ancestors) {
12253 // Start tag.
12254 const wasInPre = context.inPre;
12255 const wasInVPre = context.inVPre;
12256 const parent = last(ancestors);
12257 const element = parseTag(context, 0 /* TagType.Start */, parent);
12258 const isPreBoundary = context.inPre && !wasInPre;
12259 const isVPreBoundary = context.inVPre && !wasInVPre;
12260 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
12261 // #4030 self-closing <pre> tag
12262 if (isPreBoundary) {
12263 context.inPre = false;
12264 }
12265 if (isVPreBoundary) {
12266 context.inVPre = false;
12267 }
12268 return element;
12269 }
12270 // Children.
12271 ancestors.push(element);
12272 const mode = context.options.getTextMode(element, parent);
12273 const children = parseChildren(context, mode, ancestors);
12274 ancestors.pop();
12275 element.children = children;
12276 // End tag.
12277 if (startsWithEndTagOpen(context.source, element.tag)) {
12278 parseTag(context, 1 /* TagType.End */, parent);
12279 }
12280 else {
12281 emitError(context, 24 /* ErrorCodes.X_MISSING_END_TAG */, 0, element.loc.start);
12282 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
12283 const first = children[0];
12284 if (first && startsWith(first.loc.source, '<!--')) {
12285 emitError(context, 8 /* ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
12286 }
12287 }
12288 }
12289 element.loc = getSelection(context, element.loc.start);
12290 if (isPreBoundary) {
12291 context.inPre = false;
12292 }
12293 if (isVPreBoundary) {
12294 context.inVPre = false;
12295 }
12296 return element;
12297}
12298const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
12299function parseTag(context, type, parent) {
12300 // Tag open.
12301 const start = getCursor(context);
12302 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
12303 const tag = match[1];
12304 const ns = context.options.getNamespace(tag, parent);
12305 advanceBy(context, match[0].length);
12306 advanceSpaces(context);
12307 // save current state in case we need to re-parse attributes with v-pre
12308 const cursor = getCursor(context);
12309 const currentSource = context.source;
12310 // check <pre> tag
12311 if (context.options.isPreTag(tag)) {
12312 context.inPre = true;
12313 }
12314 // Attributes.
12315 let props = parseAttributes(context, type);
12316 // check v-pre
12317 if (type === 0 /* TagType.Start */ &&
12318 !context.inVPre &&
12319 props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'pre')) {
12320 context.inVPre = true;
12321 // reset context
12322 extend(context, cursor);
12323 context.source = currentSource;
12324 // re-parse attrs and filter out v-pre itself
12325 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
12326 }
12327 // Tag close.
12328 let isSelfClosing = false;
12329 if (context.source.length === 0) {
12330 emitError(context, 9 /* ErrorCodes.EOF_IN_TAG */);
12331 }
12332 else {
12333 isSelfClosing = startsWith(context.source, '/>');
12334 if (type === 1 /* TagType.End */ && isSelfClosing) {
12335 emitError(context, 4 /* ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS */);
12336 }
12337 advanceBy(context, isSelfClosing ? 2 : 1);
12338 }
12339 if (type === 1 /* TagType.End */) {
12340 return;
12341 }
12342 let tagType = 0 /* ElementTypes.ELEMENT */;
12343 if (!context.inVPre) {
12344 if (tag === 'slot') {
12345 tagType = 2 /* ElementTypes.SLOT */;
12346 }
12347 else if (tag === 'template') {
12348 if (props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
12349 tagType = 3 /* ElementTypes.TEMPLATE */;
12350 }
12351 }
12352 else if (isComponent(tag, props, context)) {
12353 tagType = 1 /* ElementTypes.COMPONENT */;
12354 }
12355 }
12356 return {
12357 type: 1 /* NodeTypes.ELEMENT */,
12358 ns,
12359 tag,
12360 tagType,
12361 props,
12362 isSelfClosing,
12363 children: [],
12364 loc: getSelection(context, start),
12365 codegenNode: undefined // to be created during transform phase
12366 };
12367}
12368function isComponent(tag, props, context) {
12369 const options = context.options;
12370 if (options.isCustomElement(tag)) {
12371 return false;
12372 }
12373 if (tag === 'component' ||
12374 /^[A-Z]/.test(tag) ||
12375 isCoreComponent(tag) ||
12376 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
12377 (options.isNativeTag && !options.isNativeTag(tag))) {
12378 return true;
12379 }
12380 // at this point the tag should be a native tag, but check for potential "is"
12381 // casting
12382 for (let i = 0; i < props.length; i++) {
12383 const p = props[i];
12384 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
12385 if (p.name === 'is' && p.value) {
12386 if (p.value.content.startsWith('vue:')) {
12387 return true;
12388 }
12389 }
12390 }
12391 else {
12392 // directive
12393 // v-is (TODO Deprecate)
12394 if (p.name === 'is') {
12395 return true;
12396 }
12397 else if (
12398 // :is on plain element - only treat as component in compat mode
12399 p.name === 'bind' &&
12400 isStaticArgOf(p.arg, 'is') &&
12401 false &&
12402 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
12403 return true;
12404 }
12405 }
12406 }
12407}
12408function parseAttributes(context, type) {
12409 const props = [];
12410 const attributeNames = new Set();
12411 while (context.source.length > 0 &&
12412 !startsWith(context.source, '>') &&
12413 !startsWith(context.source, '/>')) {
12414 if (startsWith(context.source, '/')) {
12415 emitError(context, 22 /* ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG */);
12416 advanceBy(context, 1);
12417 advanceSpaces(context);
12418 continue;
12419 }
12420 if (type === 1 /* TagType.End */) {
12421 emitError(context, 3 /* ErrorCodes.END_TAG_WITH_ATTRIBUTES */);
12422 }
12423 const attr = parseAttribute(context, attributeNames);
12424 // Trim whitespace between class
12425 // https://github.com/vuejs/core/issues/4251
12426 if (attr.type === 6 /* NodeTypes.ATTRIBUTE */ &&
12427 attr.value &&
12428 attr.name === 'class') {
12429 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
12430 }
12431 if (type === 0 /* TagType.Start */) {
12432 props.push(attr);
12433 }
12434 if (/^[^\t\r\n\f />]/.test(context.source)) {
12435 emitError(context, 15 /* ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
12436 }
12437 advanceSpaces(context);
12438 }
12439 return props;
12440}
12441function parseAttribute(context, nameSet) {
12442 // Name.
12443 const start = getCursor(context);
12444 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
12445 const name = match[0];
12446 if (nameSet.has(name)) {
12447 emitError(context, 2 /* ErrorCodes.DUPLICATE_ATTRIBUTE */);
12448 }
12449 nameSet.add(name);
12450 if (name[0] === '=') {
12451 emitError(context, 19 /* ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
12452 }
12453 {
12454 const pattern = /["'<]/g;
12455 let m;
12456 while ((m = pattern.exec(name))) {
12457 emitError(context, 17 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
12458 }
12459 }
12460 advanceBy(context, name.length);
12461 // Value
12462 let value = undefined;
12463 if (/^[\t\r\n\f ]*=/.test(context.source)) {
12464 advanceSpaces(context);
12465 advanceBy(context, 1);
12466 advanceSpaces(context);
12467 value = parseAttributeValue(context);
12468 if (!value) {
12469 emitError(context, 13 /* ErrorCodes.MISSING_ATTRIBUTE_VALUE */);
12470 }
12471 }
12472 const loc = getSelection(context, start);
12473 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
12474 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
12475 let isPropShorthand = startsWith(name, '.');
12476 let dirName = match[1] ||
12477 (isPropShorthand || startsWith(name, ':')
12478 ? 'bind'
12479 : startsWith(name, '@')
12480 ? 'on'
12481 : 'slot');
12482 let arg;
12483 if (match[2]) {
12484 const isSlot = dirName === 'slot';
12485 const startOffset = name.lastIndexOf(match[2]);
12486 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
12487 let content = match[2];
12488 let isStatic = true;
12489 if (content.startsWith('[')) {
12490 isStatic = false;
12491 if (!content.endsWith(']')) {
12492 emitError(context, 27 /* ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
12493 content = content.slice(1);
12494 }
12495 else {
12496 content = content.slice(1, content.length - 1);
12497 }
12498 }
12499 else if (isSlot) {
12500 // #1241 special case for v-slot: vuetify relies extensively on slot
12501 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
12502 // supports such usage so we are keeping it consistent with 2.x.
12503 content += match[3] || '';
12504 }
12505 arg = {
12506 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
12507 content,
12508 isStatic,
12509 constType: isStatic
12510 ? 3 /* ConstantTypes.CAN_STRINGIFY */
12511 : 0 /* ConstantTypes.NOT_CONSTANT */,
12512 loc
12513 };
12514 }
12515 if (value && value.isQuoted) {
12516 const valueLoc = value.loc;
12517 valueLoc.start.offset++;
12518 valueLoc.start.column++;
12519 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
12520 valueLoc.source = valueLoc.source.slice(1, -1);
12521 }
12522 const modifiers = match[3] ? match[3].slice(1).split('.') : [];
12523 if (isPropShorthand)
12524 modifiers.push('prop');
12525 return {
12526 type: 7 /* NodeTypes.DIRECTIVE */,
12527 name: dirName,
12528 exp: value && {
12529 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
12530 content: value.content,
12531 isStatic: false,
12532 // Treat as non-constant by default. This can be potentially set to
12533 // other values by `transformExpression` to make it eligible for hoisting.
12534 constType: 0 /* ConstantTypes.NOT_CONSTANT */,
12535 loc: value.loc
12536 },
12537 arg,
12538 modifiers,
12539 loc
12540 };
12541 }
12542 // missing directive name or illegal directive name
12543 if (!context.inVPre && startsWith(name, 'v-')) {
12544 emitError(context, 26 /* ErrorCodes.X_MISSING_DIRECTIVE_NAME */);
12545 }
12546 return {
12547 type: 6 /* NodeTypes.ATTRIBUTE */,
12548 name,
12549 value: value && {
12550 type: 2 /* NodeTypes.TEXT */,
12551 content: value.content,
12552 loc: value.loc
12553 },
12554 loc
12555 };
12556}
12557function parseAttributeValue(context) {
12558 const start = getCursor(context);
12559 let content;
12560 const quote = context.source[0];
12561 const isQuoted = quote === `"` || quote === `'`;
12562 if (isQuoted) {
12563 // Quoted value.
12564 advanceBy(context, 1);
12565 const endIndex = context.source.indexOf(quote);
12566 if (endIndex === -1) {
12567 content = parseTextData(context, context.source.length, 4 /* TextModes.ATTRIBUTE_VALUE */);
12568 }
12569 else {
12570 content = parseTextData(context, endIndex, 4 /* TextModes.ATTRIBUTE_VALUE */);
12571 advanceBy(context, 1);
12572 }
12573 }
12574 else {
12575 // Unquoted
12576 const match = /^[^\t\r\n\f >]+/.exec(context.source);
12577 if (!match) {
12578 return undefined;
12579 }
12580 const unexpectedChars = /["'<=`]/g;
12581 let m;
12582 while ((m = unexpectedChars.exec(match[0]))) {
12583 emitError(context, 18 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
12584 }
12585 content = parseTextData(context, match[0].length, 4 /* TextModes.ATTRIBUTE_VALUE */);
12586 }
12587 return { content, isQuoted, loc: getSelection(context, start) };
12588}
12589function parseInterpolation(context, mode) {
12590 const [open, close] = context.options.delimiters;
12591 const closeIndex = context.source.indexOf(close, open.length);
12592 if (closeIndex === -1) {
12593 emitError(context, 25 /* ErrorCodes.X_MISSING_INTERPOLATION_END */);
12594 return undefined;
12595 }
12596 const start = getCursor(context);
12597 advanceBy(context, open.length);
12598 const innerStart = getCursor(context);
12599 const innerEnd = getCursor(context);
12600 const rawContentLength = closeIndex - open.length;
12601 const rawContent = context.source.slice(0, rawContentLength);
12602 const preTrimContent = parseTextData(context, rawContentLength, mode);
12603 const content = preTrimContent.trim();
12604 const startOffset = preTrimContent.indexOf(content);
12605 if (startOffset > 0) {
12606 advancePositionWithMutation(innerStart, rawContent, startOffset);
12607 }
12608 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
12609 advancePositionWithMutation(innerEnd, rawContent, endOffset);
12610 advanceBy(context, close.length);
12611 return {
12612 type: 5 /* NodeTypes.INTERPOLATION */,
12613 content: {
12614 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
12615 isStatic: false,
12616 // Set `isConstant` to false by default and will decide in transformExpression
12617 constType: 0 /* ConstantTypes.NOT_CONSTANT */,
12618 content,
12619 loc: getSelection(context, innerStart, innerEnd)
12620 },
12621 loc: getSelection(context, start)
12622 };
12623}
12624function parseText(context, mode) {
12625 const endTokens = mode === 3 /* TextModes.CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
12626 let endIndex = context.source.length;
12627 for (let i = 0; i < endTokens.length; i++) {
12628 const index = context.source.indexOf(endTokens[i], 1);
12629 if (index !== -1 && endIndex > index) {
12630 endIndex = index;
12631 }
12632 }
12633 const start = getCursor(context);
12634 const content = parseTextData(context, endIndex, mode);
12635 return {
12636 type: 2 /* NodeTypes.TEXT */,
12637 content,
12638 loc: getSelection(context, start)
12639 };
12640}
12641/**
12642 * Get text data with a given length from the current location.
12643 * This translates HTML entities in the text data.
12644 */
12645function parseTextData(context, length, mode) {
12646 const rawText = context.source.slice(0, length);
12647 advanceBy(context, length);
12648 if (mode === 2 /* TextModes.RAWTEXT */ ||
12649 mode === 3 /* TextModes.CDATA */ ||
12650 !rawText.includes('&')) {
12651 return rawText;
12652 }
12653 else {
12654 // DATA or RCDATA containing "&"". Entity decoding required.
12655 return context.options.decodeEntities(rawText, mode === 4 /* TextModes.ATTRIBUTE_VALUE */);
12656 }
12657}
12658function getCursor(context) {
12659 const { column, line, offset } = context;
12660 return { column, line, offset };
12661}
12662function getSelection(context, start, end) {
12663 end = end || getCursor(context);
12664 return {
12665 start,
12666 end,
12667 source: context.originalSource.slice(start.offset, end.offset)
12668 };
12669}
12670function last(xs) {
12671 return xs[xs.length - 1];
12672}
12673function startsWith(source, searchString) {
12674 return source.startsWith(searchString);
12675}
12676function advanceBy(context, numberOfCharacters) {
12677 const { source } = context;
12678 advancePositionWithMutation(context, source, numberOfCharacters);
12679 context.source = source.slice(numberOfCharacters);
12680}
12681function advanceSpaces(context) {
12682 const match = /^[\t\r\n\f ]+/.exec(context.source);
12683 if (match) {
12684 advanceBy(context, match[0].length);
12685 }
12686}
12687function getNewPosition(context, start, numberOfCharacters) {
12688 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
12689}
12690function emitError(context, code, offset, loc = getCursor(context)) {
12691 if (offset) {
12692 loc.offset += offset;
12693 loc.column += offset;
12694 }
12695 context.options.onError(createCompilerError(code, {
12696 start: loc,
12697 end: loc,
12698 source: ''
12699 }));
12700}
12701function isEnd(context, mode, ancestors) {
12702 const s = context.source;
12703 switch (mode) {
12704 case 0 /* TextModes.DATA */:
12705 if (startsWith(s, '</')) {
12706 // TODO: probably bad performance
12707 for (let i = ancestors.length - 1; i >= 0; --i) {
12708 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
12709 return true;
12710 }
12711 }
12712 }
12713 break;
12714 case 1 /* TextModes.RCDATA */:
12715 case 2 /* TextModes.RAWTEXT */: {
12716 const parent = last(ancestors);
12717 if (parent && startsWithEndTagOpen(s, parent.tag)) {
12718 return true;
12719 }
12720 break;
12721 }
12722 case 3 /* TextModes.CDATA */:
12723 if (startsWith(s, ']]>')) {
12724 return true;
12725 }
12726 break;
12727 }
12728 return !s;
12729}
12730function startsWithEndTagOpen(source, tag) {
12731 return (startsWith(source, '</') &&
12732 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
12733 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
12734}
12735
12736function hoistStatic(root, context) {
12737 walk(root, context,
12738 // Root node is unfortunately non-hoistable due to potential parent
12739 // fallthrough attributes.
12740 isSingleElementRoot(root, root.children[0]));
12741}
12742function isSingleElementRoot(root, child) {
12743 const { children } = root;
12744 return (children.length === 1 &&
12745 child.type === 1 /* NodeTypes.ELEMENT */ &&
12746 !isSlotOutlet(child));
12747}
12748function walk(node, context, doNotHoistNode = false) {
12749 const { children } = node;
12750 const originalCount = children.length;
12751 let hoistedCount = 0;
12752 for (let i = 0; i < children.length; i++) {
12753 const child = children[i];
12754 // only plain elements & text calls are eligible for hoisting.
12755 if (child.type === 1 /* NodeTypes.ELEMENT */ &&
12756 child.tagType === 0 /* ElementTypes.ELEMENT */) {
12757 const constantType = doNotHoistNode
12758 ? 0 /* ConstantTypes.NOT_CONSTANT */
12759 : getConstantType(child, context);
12760 if (constantType > 0 /* ConstantTypes.NOT_CONSTANT */) {
12761 if (constantType >= 2 /* ConstantTypes.CAN_HOIST */) {
12762 child.codegenNode.patchFlag =
12763 -1 /* PatchFlags.HOISTED */ + (` /* HOISTED */` );
12764 child.codegenNode = context.hoist(child.codegenNode);
12765 hoistedCount++;
12766 continue;
12767 }
12768 }
12769 else {
12770 // node may contain dynamic children, but its props may be eligible for
12771 // hoisting.
12772 const codegenNode = child.codegenNode;
12773 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
12774 const flag = getPatchFlag(codegenNode);
12775 if ((!flag ||
12776 flag === 512 /* PatchFlags.NEED_PATCH */ ||
12777 flag === 1 /* PatchFlags.TEXT */) &&
12778 getGeneratedPropsConstantType(child, context) >=
12779 2 /* ConstantTypes.CAN_HOIST */) {
12780 const props = getNodeProps(child);
12781 if (props) {
12782 codegenNode.props = context.hoist(props);
12783 }
12784 }
12785 if (codegenNode.dynamicProps) {
12786 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
12787 }
12788 }
12789 }
12790 }
12791 // walk further
12792 if (child.type === 1 /* NodeTypes.ELEMENT */) {
12793 const isComponent = child.tagType === 1 /* ElementTypes.COMPONENT */;
12794 if (isComponent) {
12795 context.scopes.vSlot++;
12796 }
12797 walk(child, context);
12798 if (isComponent) {
12799 context.scopes.vSlot--;
12800 }
12801 }
12802 else if (child.type === 11 /* NodeTypes.FOR */) {
12803 // Do not hoist v-for single child because it has to be a block
12804 walk(child, context, child.children.length === 1);
12805 }
12806 else if (child.type === 9 /* NodeTypes.IF */) {
12807 for (let i = 0; i < child.branches.length; i++) {
12808 // Do not hoist v-if single child because it has to be a block
12809 walk(child.branches[i], context, child.branches[i].children.length === 1);
12810 }
12811 }
12812 }
12813 if (hoistedCount && context.transformHoist) {
12814 context.transformHoist(children, context, node);
12815 }
12816 // all children were hoisted - the entire children array is hoistable.
12817 if (hoistedCount &&
12818 hoistedCount === originalCount &&
12819 node.type === 1 /* NodeTypes.ELEMENT */ &&
12820 node.tagType === 0 /* ElementTypes.ELEMENT */ &&
12821 node.codegenNode &&
12822 node.codegenNode.type === 13 /* NodeTypes.VNODE_CALL */ &&
12823 isArray(node.codegenNode.children)) {
12824 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
12825 }
12826}
12827function getConstantType(node, context) {
12828 const { constantCache } = context;
12829 switch (node.type) {
12830 case 1 /* NodeTypes.ELEMENT */:
12831 if (node.tagType !== 0 /* ElementTypes.ELEMENT */) {
12832 return 0 /* ConstantTypes.NOT_CONSTANT */;
12833 }
12834 const cached = constantCache.get(node);
12835 if (cached !== undefined) {
12836 return cached;
12837 }
12838 const codegenNode = node.codegenNode;
12839 if (codegenNode.type !== 13 /* NodeTypes.VNODE_CALL */) {
12840 return 0 /* ConstantTypes.NOT_CONSTANT */;
12841 }
12842 if (codegenNode.isBlock &&
12843 node.tag !== 'svg' &&
12844 node.tag !== 'foreignObject') {
12845 return 0 /* ConstantTypes.NOT_CONSTANT */;
12846 }
12847 const flag = getPatchFlag(codegenNode);
12848 if (!flag) {
12849 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */;
12850 // Element itself has no patch flag. However we still need to check:
12851 // 1. Even for a node with no patch flag, it is possible for it to contain
12852 // non-hoistable expressions that refers to scope variables, e.g. compiler
12853 // injected keys or cached event handlers. Therefore we need to always
12854 // check the codegenNode's props to be sure.
12855 const generatedPropsType = getGeneratedPropsConstantType(node, context);
12856 if (generatedPropsType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12857 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12858 return 0 /* ConstantTypes.NOT_CONSTANT */;
12859 }
12860 if (generatedPropsType < returnType) {
12861 returnType = generatedPropsType;
12862 }
12863 // 2. its children.
12864 for (let i = 0; i < node.children.length; i++) {
12865 const childType = getConstantType(node.children[i], context);
12866 if (childType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12867 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12868 return 0 /* ConstantTypes.NOT_CONSTANT */;
12869 }
12870 if (childType < returnType) {
12871 returnType = childType;
12872 }
12873 }
12874 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
12875 // type, check if any of the props can cause the type to be lowered
12876 // we can skip can_patch because it's guaranteed by the absence of a
12877 // patchFlag.
12878 if (returnType > 1 /* ConstantTypes.CAN_SKIP_PATCH */) {
12879 for (let i = 0; i < node.props.length; i++) {
12880 const p = node.props[i];
12881 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'bind' && p.exp) {
12882 const expType = getConstantType(p.exp, context);
12883 if (expType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12884 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12885 return 0 /* ConstantTypes.NOT_CONSTANT */;
12886 }
12887 if (expType < returnType) {
12888 returnType = expType;
12889 }
12890 }
12891 }
12892 }
12893 // only svg/foreignObject could be block here, however if they are
12894 // static then they don't need to be blocks since there will be no
12895 // nested updates.
12896 if (codegenNode.isBlock) {
12897 // except set custom directives.
12898 for (let i = 0; i < node.props.length; i++) {
12899 const p = node.props[i];
12900 if (p.type === 7 /* NodeTypes.DIRECTIVE */) {
12901 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12902 return 0 /* ConstantTypes.NOT_CONSTANT */;
12903 }
12904 }
12905 context.removeHelper(OPEN_BLOCK);
12906 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
12907 codegenNode.isBlock = false;
12908 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
12909 }
12910 constantCache.set(node, returnType);
12911 return returnType;
12912 }
12913 else {
12914 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12915 return 0 /* ConstantTypes.NOT_CONSTANT */;
12916 }
12917 case 2 /* NodeTypes.TEXT */:
12918 case 3 /* NodeTypes.COMMENT */:
12919 return 3 /* ConstantTypes.CAN_STRINGIFY */;
12920 case 9 /* NodeTypes.IF */:
12921 case 11 /* NodeTypes.FOR */:
12922 case 10 /* NodeTypes.IF_BRANCH */:
12923 return 0 /* ConstantTypes.NOT_CONSTANT */;
12924 case 5 /* NodeTypes.INTERPOLATION */:
12925 case 12 /* NodeTypes.TEXT_CALL */:
12926 return getConstantType(node.content, context);
12927 case 4 /* NodeTypes.SIMPLE_EXPRESSION */:
12928 return node.constType;
12929 case 8 /* NodeTypes.COMPOUND_EXPRESSION */:
12930 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */;
12931 for (let i = 0; i < node.children.length; i++) {
12932 const child = node.children[i];
12933 if (isString(child) || isSymbol(child)) {
12934 continue;
12935 }
12936 const childType = getConstantType(child, context);
12937 if (childType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12938 return 0 /* ConstantTypes.NOT_CONSTANT */;
12939 }
12940 else if (childType < returnType) {
12941 returnType = childType;
12942 }
12943 }
12944 return returnType;
12945 default:
12946 return 0 /* ConstantTypes.NOT_CONSTANT */;
12947 }
12948}
12949const allowHoistedHelperSet = new Set([
12950 NORMALIZE_CLASS,
12951 NORMALIZE_STYLE,
12952 NORMALIZE_PROPS,
12953 GUARD_REACTIVE_PROPS
12954]);
12955function getConstantTypeOfHelperCall(value, context) {
12956 if (value.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */ &&
12957 !isString(value.callee) &&
12958 allowHoistedHelperSet.has(value.callee)) {
12959 const arg = value.arguments[0];
12960 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
12961 return getConstantType(arg, context);
12962 }
12963 else if (arg.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
12964 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
12965 return getConstantTypeOfHelperCall(arg, context);
12966 }
12967 }
12968 return 0 /* ConstantTypes.NOT_CONSTANT */;
12969}
12970function getGeneratedPropsConstantType(node, context) {
12971 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */;
12972 const props = getNodeProps(node);
12973 if (props && props.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) {
12974 const { properties } = props;
12975 for (let i = 0; i < properties.length; i++) {
12976 const { key, value } = properties[i];
12977 const keyType = getConstantType(key, context);
12978 if (keyType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12979 return keyType;
12980 }
12981 if (keyType < returnType) {
12982 returnType = keyType;
12983 }
12984 let valueType;
12985 if (value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
12986 valueType = getConstantType(value, context);
12987 }
12988 else if (value.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
12989 // some helper calls can be hoisted,
12990 // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12991 // in this case we need to respect the ConstantType of the helper's arguments
12992 valueType = getConstantTypeOfHelperCall(value, context);
12993 }
12994 else {
12995 valueType = 0 /* ConstantTypes.NOT_CONSTANT */;
12996 }
12997 if (valueType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12998 return valueType;
12999 }
13000 if (valueType < returnType) {
13001 returnType = valueType;
13002 }
13003 }
13004 }
13005 return returnType;
13006}
13007function getNodeProps(node) {
13008 const codegenNode = node.codegenNode;
13009 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
13010 return codegenNode.props;
13011 }
13012}
13013function getPatchFlag(node) {
13014 const flag = node.patchFlag;
13015 return flag ? parseInt(flag, 10) : undefined;
13016}
13017
13018function 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 }) {
13019 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
13020 const context = {
13021 // options
13022 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
13023 prefixIdentifiers,
13024 hoistStatic,
13025 cacheHandlers,
13026 nodeTransforms,
13027 directiveTransforms,
13028 transformHoist,
13029 isBuiltInComponent,
13030 isCustomElement,
13031 expressionPlugins,
13032 scopeId,
13033 slotted,
13034 ssr,
13035 inSSR,
13036 ssrCssVars,
13037 bindingMetadata,
13038 inline,
13039 isTS,
13040 onError,
13041 onWarn,
13042 compatConfig,
13043 // state
13044 root,
13045 helpers: new Map(),
13046 components: new Set(),
13047 directives: new Set(),
13048 hoists: [],
13049 imports: [],
13050 constantCache: new Map(),
13051 temps: 0,
13052 cached: 0,
13053 identifiers: Object.create(null),
13054 scopes: {
13055 vFor: 0,
13056 vSlot: 0,
13057 vPre: 0,
13058 vOnce: 0
13059 },
13060 parent: null,
13061 currentNode: root,
13062 childIndex: 0,
13063 inVOnce: false,
13064 // methods
13065 helper(name) {
13066 const count = context.helpers.get(name) || 0;
13067 context.helpers.set(name, count + 1);
13068 return name;
13069 },
13070 removeHelper(name) {
13071 const count = context.helpers.get(name);
13072 if (count) {
13073 const currentCount = count - 1;
13074 if (!currentCount) {
13075 context.helpers.delete(name);
13076 }
13077 else {
13078 context.helpers.set(name, currentCount);
13079 }
13080 }
13081 },
13082 helperString(name) {
13083 return `_${helperNameMap[context.helper(name)]}`;
13084 },
13085 replaceNode(node) {
13086 /* istanbul ignore if */
13087 {
13088 if (!context.currentNode) {
13089 throw new Error(`Node being replaced is already removed.`);
13090 }
13091 if (!context.parent) {
13092 throw new Error(`Cannot replace root node.`);
13093 }
13094 }
13095 context.parent.children[context.childIndex] = context.currentNode = node;
13096 },
13097 removeNode(node) {
13098 if (!context.parent) {
13099 throw new Error(`Cannot remove root node.`);
13100 }
13101 const list = context.parent.children;
13102 const removalIndex = node
13103 ? list.indexOf(node)
13104 : context.currentNode
13105 ? context.childIndex
13106 : -1;
13107 /* istanbul ignore if */
13108 if (removalIndex < 0) {
13109 throw new Error(`node being removed is not a child of current parent`);
13110 }
13111 if (!node || node === context.currentNode) {
13112 // current node removed
13113 context.currentNode = null;
13114 context.onNodeRemoved();
13115 }
13116 else {
13117 // sibling node removed
13118 if (context.childIndex > removalIndex) {
13119 context.childIndex--;
13120 context.onNodeRemoved();
13121 }
13122 }
13123 context.parent.children.splice(removalIndex, 1);
13124 },
13125 onNodeRemoved: () => { },
13126 addIdentifiers(exp) {
13127 },
13128 removeIdentifiers(exp) {
13129 },
13130 hoist(exp) {
13131 if (isString(exp))
13132 exp = createSimpleExpression(exp);
13133 context.hoists.push(exp);
13134 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* ConstantTypes.CAN_HOIST */);
13135 identifier.hoisted = exp;
13136 return identifier;
13137 },
13138 cache(exp, isVNode = false) {
13139 return createCacheExpression(context.cached++, exp, isVNode);
13140 }
13141 };
13142 return context;
13143}
13144function transform(root, options) {
13145 const context = createTransformContext(root, options);
13146 traverseNode(root, context);
13147 if (options.hoistStatic) {
13148 hoistStatic(root, context);
13149 }
13150 if (!options.ssr) {
13151 createRootCodegen(root, context);
13152 }
13153 // finalize meta information
13154 root.helpers = new Set([...context.helpers.keys()]);
13155 root.components = [...context.components];
13156 root.directives = [...context.directives];
13157 root.imports = context.imports;
13158 root.hoists = context.hoists;
13159 root.temps = context.temps;
13160 root.cached = context.cached;
13161}
13162function createRootCodegen(root, context) {
13163 const { helper } = context;
13164 const { children } = root;
13165 if (children.length === 1) {
13166 const child = children[0];
13167 // if the single child is an element, turn it into a block.
13168 if (isSingleElementRoot(root, child) && child.codegenNode) {
13169 // single element root is never hoisted so codegenNode will never be
13170 // SimpleExpressionNode
13171 const codegenNode = child.codegenNode;
13172 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
13173 makeBlock(codegenNode, context);
13174 }
13175 root.codegenNode = codegenNode;
13176 }
13177 else {
13178 // - single <slot/>, IfNode, ForNode: already blocks.
13179 // - single text node: always patched.
13180 // root codegen falls through via genNode()
13181 root.codegenNode = child;
13182 }
13183 }
13184 else if (children.length > 1) {
13185 // root has multiple nodes - return a fragment block.
13186 let patchFlag = 64 /* PatchFlags.STABLE_FRAGMENT */;
13187 let patchFlagText = PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */];
13188 // check if the fragment actually contains a single valid child with
13189 // the rest being comments
13190 if (children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */).length === 1) {
13191 patchFlag |= 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */;
13192 patchFlagText += `, ${PatchFlagNames[2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]}`;
13193 }
13194 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);
13195 }
13196 else ;
13197}
13198function traverseChildren(parent, context) {
13199 let i = 0;
13200 const nodeRemoved = () => {
13201 i--;
13202 };
13203 for (; i < parent.children.length; i++) {
13204 const child = parent.children[i];
13205 if (isString(child))
13206 continue;
13207 context.parent = parent;
13208 context.childIndex = i;
13209 context.onNodeRemoved = nodeRemoved;
13210 traverseNode(child, context);
13211 }
13212}
13213function traverseNode(node, context) {
13214 context.currentNode = node;
13215 // apply transform plugins
13216 const { nodeTransforms } = context;
13217 const exitFns = [];
13218 for (let i = 0; i < nodeTransforms.length; i++) {
13219 const onExit = nodeTransforms[i](node, context);
13220 if (onExit) {
13221 if (isArray(onExit)) {
13222 exitFns.push(...onExit);
13223 }
13224 else {
13225 exitFns.push(onExit);
13226 }
13227 }
13228 if (!context.currentNode) {
13229 // node was removed
13230 return;
13231 }
13232 else {
13233 // node may have been replaced
13234 node = context.currentNode;
13235 }
13236 }
13237 switch (node.type) {
13238 case 3 /* NodeTypes.COMMENT */:
13239 if (!context.ssr) {
13240 // inject import for the Comment symbol, which is needed for creating
13241 // comment nodes with `createVNode`
13242 context.helper(CREATE_COMMENT);
13243 }
13244 break;
13245 case 5 /* NodeTypes.INTERPOLATION */:
13246 // no need to traverse, but we need to inject toString helper
13247 if (!context.ssr) {
13248 context.helper(TO_DISPLAY_STRING);
13249 }
13250 break;
13251 // for container types, further traverse downwards
13252 case 9 /* NodeTypes.IF */:
13253 for (let i = 0; i < node.branches.length; i++) {
13254 traverseNode(node.branches[i], context);
13255 }
13256 break;
13257 case 10 /* NodeTypes.IF_BRANCH */:
13258 case 11 /* NodeTypes.FOR */:
13259 case 1 /* NodeTypes.ELEMENT */:
13260 case 0 /* NodeTypes.ROOT */:
13261 traverseChildren(node, context);
13262 break;
13263 }
13264 // exit transforms
13265 context.currentNode = node;
13266 let i = exitFns.length;
13267 while (i--) {
13268 exitFns[i]();
13269 }
13270}
13271function createStructuralDirectiveTransform(name, fn) {
13272 const matches = isString(name)
13273 ? (n) => n === name
13274 : (n) => name.test(n);
13275 return (node, context) => {
13276 if (node.type === 1 /* NodeTypes.ELEMENT */) {
13277 const { props } = node;
13278 // structural directive transforms are not concerned with slots
13279 // as they are handled separately in vSlot.ts
13280 if (node.tagType === 3 /* ElementTypes.TEMPLATE */ && props.some(isVSlot)) {
13281 return;
13282 }
13283 const exitFns = [];
13284 for (let i = 0; i < props.length; i++) {
13285 const prop = props[i];
13286 if (prop.type === 7 /* NodeTypes.DIRECTIVE */ && matches(prop.name)) {
13287 // structural directives are removed to avoid infinite recursion
13288 // also we remove them *before* applying so that it can further
13289 // traverse itself in case it moves the node around
13290 props.splice(i, 1);
13291 i--;
13292 const onExit = fn(node, prop, context);
13293 if (onExit)
13294 exitFns.push(onExit);
13295 }
13296 }
13297 return exitFns;
13298 }
13299 };
13300}
13301
13302const PURE_ANNOTATION = `/*#__PURE__*/`;
13303const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
13304function 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 }) {
13305 const context = {
13306 mode,
13307 prefixIdentifiers,
13308 sourceMap,
13309 filename,
13310 scopeId,
13311 optimizeImports,
13312 runtimeGlobalName,
13313 runtimeModuleName,
13314 ssrRuntimeModuleName,
13315 ssr,
13316 isTS,
13317 inSSR,
13318 source: ast.loc.source,
13319 code: ``,
13320 column: 1,
13321 line: 1,
13322 offset: 0,
13323 indentLevel: 0,
13324 pure: false,
13325 map: undefined,
13326 helper(key) {
13327 return `_${helperNameMap[key]}`;
13328 },
13329 push(code, node) {
13330 context.code += code;
13331 },
13332 indent() {
13333 newline(++context.indentLevel);
13334 },
13335 deindent(withoutNewLine = false) {
13336 if (withoutNewLine) {
13337 --context.indentLevel;
13338 }
13339 else {
13340 newline(--context.indentLevel);
13341 }
13342 },
13343 newline() {
13344 newline(context.indentLevel);
13345 }
13346 };
13347 function newline(n) {
13348 context.push('\n' + ` `.repeat(n));
13349 }
13350 return context;
13351}
13352function generate(ast, options = {}) {
13353 const context = createCodegenContext(ast, options);
13354 if (options.onContextCreated)
13355 options.onContextCreated(context);
13356 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
13357 const helpers = Array.from(ast.helpers);
13358 const hasHelpers = helpers.length > 0;
13359 const useWithBlock = !prefixIdentifiers && mode !== 'module';
13360 const isSetupInlined = !true ;
13361 // preambles
13362 // in setup() inline mode, the preamble is generated in a sub context
13363 // and returned separately.
13364 const preambleContext = isSetupInlined
13365 ? createCodegenContext(ast, options)
13366 : context;
13367 {
13368 genFunctionPreamble(ast, preambleContext);
13369 }
13370 // enter render function
13371 const functionName = ssr ? `ssrRender` : `render`;
13372 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
13373 const signature = args.join(', ');
13374 {
13375 push(`function ${functionName}(${signature}) {`);
13376 }
13377 indent();
13378 if (useWithBlock) {
13379 push(`with (_ctx) {`);
13380 indent();
13381 // function mode const declarations should be inside with block
13382 // also they should be renamed to avoid collision with user properties
13383 if (hasHelpers) {
13384 push(`const { ${helpers.map(aliasHelper).join(', ')} } = _Vue`);
13385 push(`\n`);
13386 newline();
13387 }
13388 }
13389 // generate asset resolution statements
13390 if (ast.components.length) {
13391 genAssets(ast.components, 'component', context);
13392 if (ast.directives.length || ast.temps > 0) {
13393 newline();
13394 }
13395 }
13396 if (ast.directives.length) {
13397 genAssets(ast.directives, 'directive', context);
13398 if (ast.temps > 0) {
13399 newline();
13400 }
13401 }
13402 if (ast.temps > 0) {
13403 push(`let `);
13404 for (let i = 0; i < ast.temps; i++) {
13405 push(`${i > 0 ? `, ` : ``}_temp${i}`);
13406 }
13407 }
13408 if (ast.components.length || ast.directives.length || ast.temps) {
13409 push(`\n`);
13410 newline();
13411 }
13412 // generate the VNode tree expression
13413 if (!ssr) {
13414 push(`return `);
13415 }
13416 if (ast.codegenNode) {
13417 genNode(ast.codegenNode, context);
13418 }
13419 else {
13420 push(`null`);
13421 }
13422 if (useWithBlock) {
13423 deindent();
13424 push(`}`);
13425 }
13426 deindent();
13427 push(`}`);
13428 return {
13429 ast,
13430 code: context.code,
13431 preamble: isSetupInlined ? preambleContext.code : ``,
13432 // SourceMapGenerator does have toJSON() method but it's not in the types
13433 map: context.map ? context.map.toJSON() : undefined
13434 };
13435}
13436function genFunctionPreamble(ast, context) {
13437 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
13438 const VueBinding = runtimeGlobalName;
13439 // Generate const declaration for helpers
13440 // In prefix mode, we place the const declaration at top so it's done
13441 // only once; But if we not prefixing, we place the declaration inside the
13442 // with block so it doesn't incur the `in` check cost for every helper access.
13443 const helpers = Array.from(ast.helpers);
13444 if (helpers.length > 0) {
13445 {
13446 // "with" mode.
13447 // save Vue in a separate variable to avoid collision
13448 push(`const _Vue = ${VueBinding}\n`);
13449 // in "with" mode, helpers are declared inside the with block to avoid
13450 // has check cost, but hoists are lifted out of the function - we need
13451 // to provide the helper here.
13452 if (ast.hoists.length) {
13453 const staticHelpers = [
13454 CREATE_VNODE,
13455 CREATE_ELEMENT_VNODE,
13456 CREATE_COMMENT,
13457 CREATE_TEXT,
13458 CREATE_STATIC
13459 ]
13460 .filter(helper => helpers.includes(helper))
13461 .map(aliasHelper)
13462 .join(', ');
13463 push(`const { ${staticHelpers} } = _Vue\n`);
13464 }
13465 }
13466 }
13467 genHoists(ast.hoists, context);
13468 newline();
13469 push(`return `);
13470}
13471function genAssets(assets, type, { helper, push, newline, isTS }) {
13472 const resolver = helper(type === 'component'
13473 ? RESOLVE_COMPONENT
13474 : RESOLVE_DIRECTIVE);
13475 for (let i = 0; i < assets.length; i++) {
13476 let id = assets[i];
13477 // potential component implicit self-reference inferred from SFC filename
13478 const maybeSelfReference = id.endsWith('__self');
13479 if (maybeSelfReference) {
13480 id = id.slice(0, -6);
13481 }
13482 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
13483 if (i < assets.length - 1) {
13484 newline();
13485 }
13486 }
13487}
13488function genHoists(hoists, context) {
13489 if (!hoists.length) {
13490 return;
13491 }
13492 context.pure = true;
13493 const { push, newline, helper, scopeId, mode } = context;
13494 newline();
13495 for (let i = 0; i < hoists.length; i++) {
13496 const exp = hoists[i];
13497 if (exp) {
13498 push(`const _hoisted_${i + 1} = ${``}`);
13499 genNode(exp, context);
13500 newline();
13501 }
13502 }
13503 context.pure = false;
13504}
13505function isText(n) {
13506 return (isString(n) ||
13507 n.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
13508 n.type === 2 /* NodeTypes.TEXT */ ||
13509 n.type === 5 /* NodeTypes.INTERPOLATION */ ||
13510 n.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */);
13511}
13512function genNodeListAsArray(nodes, context) {
13513 const multilines = nodes.length > 3 ||
13514 (nodes.some(n => isArray(n) || !isText(n)));
13515 context.push(`[`);
13516 multilines && context.indent();
13517 genNodeList(nodes, context, multilines);
13518 multilines && context.deindent();
13519 context.push(`]`);
13520}
13521function genNodeList(nodes, context, multilines = false, comma = true) {
13522 const { push, newline } = context;
13523 for (let i = 0; i < nodes.length; i++) {
13524 const node = nodes[i];
13525 if (isString(node)) {
13526 push(node);
13527 }
13528 else if (isArray(node)) {
13529 genNodeListAsArray(node, context);
13530 }
13531 else {
13532 genNode(node, context);
13533 }
13534 if (i < nodes.length - 1) {
13535 if (multilines) {
13536 comma && push(',');
13537 newline();
13538 }
13539 else {
13540 comma && push(', ');
13541 }
13542 }
13543 }
13544}
13545function genNode(node, context) {
13546 if (isString(node)) {
13547 context.push(node);
13548 return;
13549 }
13550 if (isSymbol(node)) {
13551 context.push(context.helper(node));
13552 return;
13553 }
13554 switch (node.type) {
13555 case 1 /* NodeTypes.ELEMENT */:
13556 case 9 /* NodeTypes.IF */:
13557 case 11 /* NodeTypes.FOR */:
13558 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
13559 `Apply appropriate transforms first.`);
13560 genNode(node.codegenNode, context);
13561 break;
13562 case 2 /* NodeTypes.TEXT */:
13563 genText(node, context);
13564 break;
13565 case 4 /* NodeTypes.SIMPLE_EXPRESSION */:
13566 genExpression(node, context);
13567 break;
13568 case 5 /* NodeTypes.INTERPOLATION */:
13569 genInterpolation(node, context);
13570 break;
13571 case 12 /* NodeTypes.TEXT_CALL */:
13572 genNode(node.codegenNode, context);
13573 break;
13574 case 8 /* NodeTypes.COMPOUND_EXPRESSION */:
13575 genCompoundExpression(node, context);
13576 break;
13577 case 3 /* NodeTypes.COMMENT */:
13578 genComment(node, context);
13579 break;
13580 case 13 /* NodeTypes.VNODE_CALL */:
13581 genVNodeCall(node, context);
13582 break;
13583 case 14 /* NodeTypes.JS_CALL_EXPRESSION */:
13584 genCallExpression(node, context);
13585 break;
13586 case 15 /* NodeTypes.JS_OBJECT_EXPRESSION */:
13587 genObjectExpression(node, context);
13588 break;
13589 case 17 /* NodeTypes.JS_ARRAY_EXPRESSION */:
13590 genArrayExpression(node, context);
13591 break;
13592 case 18 /* NodeTypes.JS_FUNCTION_EXPRESSION */:
13593 genFunctionExpression(node, context);
13594 break;
13595 case 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */:
13596 genConditionalExpression(node, context);
13597 break;
13598 case 20 /* NodeTypes.JS_CACHE_EXPRESSION */:
13599 genCacheExpression(node, context);
13600 break;
13601 case 21 /* NodeTypes.JS_BLOCK_STATEMENT */:
13602 genNodeList(node.body, context, true, false);
13603 break;
13604 // SSR only types
13605 case 22 /* NodeTypes.JS_TEMPLATE_LITERAL */:
13606 break;
13607 case 23 /* NodeTypes.JS_IF_STATEMENT */:
13608 break;
13609 case 24 /* NodeTypes.JS_ASSIGNMENT_EXPRESSION */:
13610 break;
13611 case 25 /* NodeTypes.JS_SEQUENCE_EXPRESSION */:
13612 break;
13613 case 26 /* NodeTypes.JS_RETURN_STATEMENT */:
13614 break;
13615 /* istanbul ignore next */
13616 case 10 /* NodeTypes.IF_BRANCH */:
13617 // noop
13618 break;
13619 default:
13620 {
13621 assert(false, `unhandled codegen node type: ${node.type}`);
13622 // make sure we exhaust all possible types
13623 const exhaustiveCheck = node;
13624 return exhaustiveCheck;
13625 }
13626 }
13627}
13628function genText(node, context) {
13629 context.push(JSON.stringify(node.content), node);
13630}
13631function genExpression(node, context) {
13632 const { content, isStatic } = node;
13633 context.push(isStatic ? JSON.stringify(content) : content, node);
13634}
13635function genInterpolation(node, context) {
13636 const { push, helper, pure } = context;
13637 if (pure)
13638 push(PURE_ANNOTATION);
13639 push(`${helper(TO_DISPLAY_STRING)}(`);
13640 genNode(node.content, context);
13641 push(`)`);
13642}
13643function genCompoundExpression(node, context) {
13644 for (let i = 0; i < node.children.length; i++) {
13645 const child = node.children[i];
13646 if (isString(child)) {
13647 context.push(child);
13648 }
13649 else {
13650 genNode(child, context);
13651 }
13652 }
13653}
13654function genExpressionAsPropertyKey(node, context) {
13655 const { push } = context;
13656 if (node.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
13657 push(`[`);
13658 genCompoundExpression(node, context);
13659 push(`]`);
13660 }
13661 else if (node.isStatic) {
13662 // only quote keys if necessary
13663 const text = isSimpleIdentifier(node.content)
13664 ? node.content
13665 : JSON.stringify(node.content);
13666 push(text, node);
13667 }
13668 else {
13669 push(`[${node.content}]`, node);
13670 }
13671}
13672function genComment(node, context) {
13673 const { push, helper, pure } = context;
13674 if (pure) {
13675 push(PURE_ANNOTATION);
13676 }
13677 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
13678}
13679function genVNodeCall(node, context) {
13680 const { push, helper, pure } = context;
13681 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
13682 if (directives) {
13683 push(helper(WITH_DIRECTIVES) + `(`);
13684 }
13685 if (isBlock) {
13686 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
13687 }
13688 if (pure) {
13689 push(PURE_ANNOTATION);
13690 }
13691 const callHelper = isBlock
13692 ? getVNodeBlockHelper(context.inSSR, isComponent)
13693 : getVNodeHelper(context.inSSR, isComponent);
13694 push(helper(callHelper) + `(`, node);
13695 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
13696 push(`)`);
13697 if (isBlock) {
13698 push(`)`);
13699 }
13700 if (directives) {
13701 push(`, `);
13702 genNode(directives, context);
13703 push(`)`);
13704 }
13705}
13706function genNullableArgs(args) {
13707 let i = args.length;
13708 while (i--) {
13709 if (args[i] != null)
13710 break;
13711 }
13712 return args.slice(0, i + 1).map(arg => arg || `null`);
13713}
13714// JavaScript
13715function genCallExpression(node, context) {
13716 const { push, helper, pure } = context;
13717 const callee = isString(node.callee) ? node.callee : helper(node.callee);
13718 if (pure) {
13719 push(PURE_ANNOTATION);
13720 }
13721 push(callee + `(`, node);
13722 genNodeList(node.arguments, context);
13723 push(`)`);
13724}
13725function genObjectExpression(node, context) {
13726 const { push, indent, deindent, newline } = context;
13727 const { properties } = node;
13728 if (!properties.length) {
13729 push(`{}`, node);
13730 return;
13731 }
13732 const multilines = properties.length > 1 ||
13733 (properties.some(p => p.value.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */));
13734 push(multilines ? `{` : `{ `);
13735 multilines && indent();
13736 for (let i = 0; i < properties.length; i++) {
13737 const { key, value } = properties[i];
13738 // key
13739 genExpressionAsPropertyKey(key, context);
13740 push(`: `);
13741 // value
13742 genNode(value, context);
13743 if (i < properties.length - 1) {
13744 // will only reach this if it's multilines
13745 push(`,`);
13746 newline();
13747 }
13748 }
13749 multilines && deindent();
13750 push(multilines ? `}` : ` }`);
13751}
13752function genArrayExpression(node, context) {
13753 genNodeListAsArray(node.elements, context);
13754}
13755function genFunctionExpression(node, context) {
13756 const { push, indent, deindent } = context;
13757 const { params, returns, body, newline, isSlot } = node;
13758 if (isSlot) {
13759 // wrap slot functions with owner context
13760 push(`_${helperNameMap[WITH_CTX]}(`);
13761 }
13762 push(`(`, node);
13763 if (isArray(params)) {
13764 genNodeList(params, context);
13765 }
13766 else if (params) {
13767 genNode(params, context);
13768 }
13769 push(`) => `);
13770 if (newline || body) {
13771 push(`{`);
13772 indent();
13773 }
13774 if (returns) {
13775 if (newline) {
13776 push(`return `);
13777 }
13778 if (isArray(returns)) {
13779 genNodeListAsArray(returns, context);
13780 }
13781 else {
13782 genNode(returns, context);
13783 }
13784 }
13785 else if (body) {
13786 genNode(body, context);
13787 }
13788 if (newline || body) {
13789 deindent();
13790 push(`}`);
13791 }
13792 if (isSlot) {
13793 push(`)`);
13794 }
13795}
13796function genConditionalExpression(node, context) {
13797 const { test, consequent, alternate, newline: needNewline } = node;
13798 const { push, indent, deindent, newline } = context;
13799 if (test.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
13800 const needsParens = !isSimpleIdentifier(test.content);
13801 needsParens && push(`(`);
13802 genExpression(test, context);
13803 needsParens && push(`)`);
13804 }
13805 else {
13806 push(`(`);
13807 genNode(test, context);
13808 push(`)`);
13809 }
13810 needNewline && indent();
13811 context.indentLevel++;
13812 needNewline || push(` `);
13813 push(`? `);
13814 genNode(consequent, context);
13815 context.indentLevel--;
13816 needNewline && newline();
13817 needNewline || push(` `);
13818 push(`: `);
13819 const isNested = alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */;
13820 if (!isNested) {
13821 context.indentLevel++;
13822 }
13823 genNode(alternate, context);
13824 if (!isNested) {
13825 context.indentLevel--;
13826 }
13827 needNewline && deindent(true /* without newline */);
13828}
13829function genCacheExpression(node, context) {
13830 const { push, helper, indent, deindent, newline } = context;
13831 push(`_cache[${node.index}] || (`);
13832 if (node.isVNode) {
13833 indent();
13834 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
13835 newline();
13836 }
13837 push(`_cache[${node.index}] = `);
13838 genNode(node.value, context);
13839 if (node.isVNode) {
13840 push(`,`);
13841 newline();
13842 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
13843 newline();
13844 push(`_cache[${node.index}]`);
13845 deindent();
13846 }
13847 push(`)`);
13848}
13849
13850// these keywords should not appear inside expressions, but operators like
13851// 'typeof', 'instanceof', and 'in' are allowed
13852const prohibitedKeywordRE = new RegExp('\\b' +
13853 ('arguments,await,break,case,catch,class,const,continue,debugger,default,' +
13854 'delete,do,else,export,extends,finally,for,function,if,import,let,new,' +
13855 'return,super,switch,throw,try,var,void,while,with,yield')
13856 .split(',')
13857 .join('\\b|\\b') +
13858 '\\b');
13859// strip strings in expressions
13860const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
13861/**
13862 * Validate a non-prefixed expression.
13863 * This is only called when using the in-browser runtime compiler since it
13864 * doesn't prefix expressions.
13865 */
13866function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
13867 const exp = node.content;
13868 // empty expressions are validated per-directive since some directives
13869 // do allow empty expressions.
13870 if (!exp.trim()) {
13871 return;
13872 }
13873 try {
13874 new Function(asRawStatements
13875 ? ` ${exp} `
13876 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
13877 }
13878 catch (e) {
13879 let message = e.message;
13880 const keywordMatch = exp
13881 .replace(stripStringRE, '')
13882 .match(prohibitedKeywordRE);
13883 if (keywordMatch) {
13884 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
13885 }
13886 context.onError(createCompilerError(45 /* ErrorCodes.X_INVALID_EXPRESSION */, node.loc, undefined, message));
13887 }
13888}
13889
13890const transformExpression = (node, context) => {
13891 if (node.type === 5 /* NodeTypes.INTERPOLATION */) {
13892 node.content = processExpression(node.content, context);
13893 }
13894 else if (node.type === 1 /* NodeTypes.ELEMENT */) {
13895 // handle directives on element
13896 for (let i = 0; i < node.props.length; i++) {
13897 const dir = node.props[i];
13898 // do not process for v-on & v-for since they are special handled
13899 if (dir.type === 7 /* NodeTypes.DIRECTIVE */ && dir.name !== 'for') {
13900 const exp = dir.exp;
13901 const arg = dir.arg;
13902 // do not process exp if this is v-on:arg - we need special handling
13903 // for wrapping inline statements.
13904 if (exp &&
13905 exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
13906 !(dir.name === 'on' && arg)) {
13907 dir.exp = processExpression(exp, context,
13908 // slot args must be processed as function params
13909 dir.name === 'slot');
13910 }
13911 if (arg && arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && !arg.isStatic) {
13912 dir.arg = processExpression(arg, context);
13913 }
13914 }
13915 }
13916 }
13917};
13918// Important: since this function uses Node.js only dependencies, it should
13919// always be used with a leading !true check so that it can be
13920// tree-shaken from the browser build.
13921function processExpression(node, context,
13922// some expressions like v-slot props & v-for aliases should be parsed as
13923// function params
13924asParams = false,
13925// v-on handler values may contain multiple statements
13926asRawStatements = false, localVars = Object.create(context.identifiers)) {
13927 {
13928 {
13929 // simple in-browser validation (same logic in 2.x)
13930 validateBrowserExpression(node, context, asParams, asRawStatements);
13931 }
13932 return node;
13933 }
13934}
13935
13936const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
13937 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
13938 // #1587: We need to dynamically increment the key based on the current
13939 // node's sibling nodes, since chained v-if/else branches are
13940 // rendered at the same depth
13941 const siblings = context.parent.children;
13942 let i = siblings.indexOf(ifNode);
13943 let key = 0;
13944 while (i-- >= 0) {
13945 const sibling = siblings[i];
13946 if (sibling && sibling.type === 9 /* NodeTypes.IF */) {
13947 key += sibling.branches.length;
13948 }
13949 }
13950 // Exit callback. Complete the codegenNode when all children have been
13951 // transformed.
13952 return () => {
13953 if (isRoot) {
13954 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
13955 }
13956 else {
13957 // attach this branch's codegen node to the v-if root.
13958 const parentCondition = getParentCondition(ifNode.codegenNode);
13959 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
13960 }
13961 };
13962 });
13963});
13964// target-agnostic transform used for both Client and SSR
13965function processIf(node, dir, context, processCodegen) {
13966 if (dir.name !== 'else' &&
13967 (!dir.exp || !dir.exp.content.trim())) {
13968 const loc = dir.exp ? dir.exp.loc : node.loc;
13969 context.onError(createCompilerError(28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */, dir.loc));
13970 dir.exp = createSimpleExpression(`true`, false, loc);
13971 }
13972 if (dir.exp) {
13973 validateBrowserExpression(dir.exp, context);
13974 }
13975 if (dir.name === 'if') {
13976 const branch = createIfBranch(node, dir);
13977 const ifNode = {
13978 type: 9 /* NodeTypes.IF */,
13979 loc: node.loc,
13980 branches: [branch]
13981 };
13982 context.replaceNode(ifNode);
13983 if (processCodegen) {
13984 return processCodegen(ifNode, branch, true);
13985 }
13986 }
13987 else {
13988 // locate the adjacent v-if
13989 const siblings = context.parent.children;
13990 const comments = [];
13991 let i = siblings.indexOf(node);
13992 while (i-- >= -1) {
13993 const sibling = siblings[i];
13994 if (sibling && sibling.type === 3 /* NodeTypes.COMMENT */) {
13995 context.removeNode(sibling);
13996 comments.unshift(sibling);
13997 continue;
13998 }
13999 if (sibling &&
14000 sibling.type === 2 /* NodeTypes.TEXT */ &&
14001 !sibling.content.trim().length) {
14002 context.removeNode(sibling);
14003 continue;
14004 }
14005 if (sibling && sibling.type === 9 /* NodeTypes.IF */) {
14006 // Check if v-else was followed by v-else-if
14007 if (dir.name === 'else-if' &&
14008 sibling.branches[sibling.branches.length - 1].condition === undefined) {
14009 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
14010 }
14011 // move the node to the if node's branches
14012 context.removeNode();
14013 const branch = createIfBranch(node, dir);
14014 if (comments.length &&
14015 // #3619 ignore comments if the v-if is direct child of <transition>
14016 !(context.parent &&
14017 context.parent.type === 1 /* NodeTypes.ELEMENT */ &&
14018 isBuiltInType(context.parent.tag, 'transition'))) {
14019 branch.children = [...comments, ...branch.children];
14020 }
14021 // check if user is forcing same key on different branches
14022 {
14023 const key = branch.userKey;
14024 if (key) {
14025 sibling.branches.forEach(({ userKey }) => {
14026 if (isSameKey(userKey, key)) {
14027 context.onError(createCompilerError(29 /* ErrorCodes.X_V_IF_SAME_KEY */, branch.userKey.loc));
14028 }
14029 });
14030 }
14031 }
14032 sibling.branches.push(branch);
14033 const onExit = processCodegen && processCodegen(sibling, branch, false);
14034 // since the branch was removed, it will not be traversed.
14035 // make sure to traverse here.
14036 traverseNode(branch, context);
14037 // call on exit
14038 if (onExit)
14039 onExit();
14040 // make sure to reset currentNode after traversal to indicate this
14041 // node has been removed.
14042 context.currentNode = null;
14043 }
14044 else {
14045 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
14046 }
14047 break;
14048 }
14049 }
14050}
14051function createIfBranch(node, dir) {
14052 const isTemplateIf = node.tagType === 3 /* ElementTypes.TEMPLATE */;
14053 return {
14054 type: 10 /* NodeTypes.IF_BRANCH */,
14055 loc: node.loc,
14056 condition: dir.name === 'else' ? undefined : dir.exp,
14057 children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
14058 userKey: findProp(node, `key`),
14059 isTemplateIf
14060 };
14061}
14062function createCodegenNodeForBranch(branch, keyIndex, context) {
14063 if (branch.condition) {
14064 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
14065 // make sure to pass in asBlock: true so that the comment node call
14066 // closes the current block.
14067 createCallExpression(context.helper(CREATE_COMMENT), [
14068 '"v-if"' ,
14069 'true'
14070 ]));
14071 }
14072 else {
14073 return createChildrenCodegenNode(branch, keyIndex, context);
14074 }
14075}
14076function createChildrenCodegenNode(branch, keyIndex, context) {
14077 const { helper } = context;
14078 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* ConstantTypes.CAN_HOIST */));
14079 const { children } = branch;
14080 const firstChild = children[0];
14081 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* NodeTypes.ELEMENT */;
14082 if (needFragmentWrapper) {
14083 if (children.length === 1 && firstChild.type === 11 /* NodeTypes.FOR */) {
14084 // optimize away nested fragments when child is a ForNode
14085 const vnodeCall = firstChild.codegenNode;
14086 injectProp(vnodeCall, keyProperty, context);
14087 return vnodeCall;
14088 }
14089 else {
14090 let patchFlag = 64 /* PatchFlags.STABLE_FRAGMENT */;
14091 let patchFlagText = PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */];
14092 // check if the fragment actually contains a single valid child with
14093 // the rest being comments
14094 if (!branch.isTemplateIf &&
14095 children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */).length === 1) {
14096 patchFlag |= 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */;
14097 patchFlagText += `, ${PatchFlagNames[2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]}`;
14098 }
14099 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);
14100 }
14101 }
14102 else {
14103 const ret = firstChild.codegenNode;
14104 const vnodeCall = getMemoedVNodeCall(ret);
14105 // Change createVNode to createBlock.
14106 if (vnodeCall.type === 13 /* NodeTypes.VNODE_CALL */) {
14107 makeBlock(vnodeCall, context);
14108 }
14109 // inject branch key
14110 injectProp(vnodeCall, keyProperty, context);
14111 return ret;
14112 }
14113}
14114function isSameKey(a, b) {
14115 if (!a || a.type !== b.type) {
14116 return false;
14117 }
14118 if (a.type === 6 /* NodeTypes.ATTRIBUTE */) {
14119 if (a.value.content !== b.value.content) {
14120 return false;
14121 }
14122 }
14123 else {
14124 // directive
14125 const exp = a.exp;
14126 const branchExp = b.exp;
14127 if (exp.type !== branchExp.type) {
14128 return false;
14129 }
14130 if (exp.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
14131 exp.isStatic !== branchExp.isStatic ||
14132 exp.content !== branchExp.content) {
14133 return false;
14134 }
14135 }
14136 return true;
14137}
14138function getParentCondition(node) {
14139 while (true) {
14140 if (node.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) {
14141 if (node.alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) {
14142 node = node.alternate;
14143 }
14144 else {
14145 return node;
14146 }
14147 }
14148 else if (node.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */) {
14149 node = node.value;
14150 }
14151 }
14152}
14153
14154const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
14155 const { helper, removeHelper } = context;
14156 return processFor(node, dir, context, forNode => {
14157 // create the loop render function expression now, and add the
14158 // iterator on exit after all children have been traversed
14159 const renderExp = createCallExpression(helper(RENDER_LIST), [
14160 forNode.source
14161 ]);
14162 const isTemplate = isTemplateNode(node);
14163 const memo = findDir(node, 'memo');
14164 const keyProp = findProp(node, `key`);
14165 const keyExp = keyProp &&
14166 (keyProp.type === 6 /* NodeTypes.ATTRIBUTE */
14167 ? createSimpleExpression(keyProp.value.content, true)
14168 : keyProp.exp);
14169 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
14170 const isStableFragment = forNode.source.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
14171 forNode.source.constType > 0 /* ConstantTypes.NOT_CONSTANT */;
14172 const fragmentFlag = isStableFragment
14173 ? 64 /* PatchFlags.STABLE_FRAGMENT */
14174 : keyProp
14175 ? 128 /* PatchFlags.KEYED_FRAGMENT */
14176 : 256 /* PatchFlags.UNKEYED_FRAGMENT */;
14177 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
14178 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
14179 return () => {
14180 // finish the codegen now that all children have been traversed
14181 let childBlock;
14182 const { children } = forNode;
14183 // check <template v-for> key placement
14184 if (isTemplate) {
14185 node.children.some(c => {
14186 if (c.type === 1 /* NodeTypes.ELEMENT */) {
14187 const key = findProp(c, 'key');
14188 if (key) {
14189 context.onError(createCompilerError(33 /* ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
14190 return true;
14191 }
14192 }
14193 });
14194 }
14195 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* NodeTypes.ELEMENT */;
14196 const slotOutlet = isSlotOutlet(node)
14197 ? node
14198 : isTemplate &&
14199 node.children.length === 1 &&
14200 isSlotOutlet(node.children[0])
14201 ? node.children[0] // api-extractor somehow fails to infer this
14202 : null;
14203 if (slotOutlet) {
14204 // <slot v-for="..."> or <template v-for="..."><slot/></template>
14205 childBlock = slotOutlet.codegenNode;
14206 if (isTemplate && keyProperty) {
14207 // <template v-for="..." :key="..."><slot/></template>
14208 // we need to inject the key to the renderSlot() call.
14209 // the props for renderSlot is passed as the 3rd argument.
14210 injectProp(childBlock, keyProperty, context);
14211 }
14212 }
14213 else if (needFragmentWrapper) {
14214 // <template v-for="..."> with text or multi-elements
14215 // should generate a fragment block for each loop
14216 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* PatchFlags.STABLE_FRAGMENT */ +
14217 (` /* ${PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */]} */`
14218 ), undefined, undefined, true, undefined, false /* isComponent */);
14219 }
14220 else {
14221 // Normal element v-for. Directly use the child's codegenNode
14222 // but mark it as a block.
14223 childBlock = children[0]
14224 .codegenNode;
14225 if (isTemplate && keyProperty) {
14226 injectProp(childBlock, keyProperty, context);
14227 }
14228 if (childBlock.isBlock !== !isStableFragment) {
14229 if (childBlock.isBlock) {
14230 // switch from block to vnode
14231 removeHelper(OPEN_BLOCK);
14232 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14233 }
14234 else {
14235 // switch from vnode to block
14236 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14237 }
14238 }
14239 childBlock.isBlock = !isStableFragment;
14240 if (childBlock.isBlock) {
14241 helper(OPEN_BLOCK);
14242 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14243 }
14244 else {
14245 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14246 }
14247 }
14248 if (memo) {
14249 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
14250 createSimpleExpression(`_cached`)
14251 ]));
14252 loop.body = createBlockStatement([
14253 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
14254 createCompoundExpression([
14255 `if (_cached`,
14256 ...(keyExp ? [` && _cached.key === `, keyExp] : []),
14257 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
14258 ]),
14259 createCompoundExpression([`const _item = `, childBlock]),
14260 createSimpleExpression(`_item.memo = _memo`),
14261 createSimpleExpression(`return _item`)
14262 ]);
14263 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
14264 }
14265 else {
14266 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
14267 }
14268 };
14269 });
14270});
14271// target-agnostic transform used for both Client and SSR
14272function processFor(node, dir, context, processCodegen) {
14273 if (!dir.exp) {
14274 context.onError(createCompilerError(31 /* ErrorCodes.X_V_FOR_NO_EXPRESSION */, dir.loc));
14275 return;
14276 }
14277 const parseResult = parseForExpression(
14278 // can only be simple expression because vFor transform is applied
14279 // before expression transform.
14280 dir.exp, context);
14281 if (!parseResult) {
14282 context.onError(createCompilerError(32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
14283 return;
14284 }
14285 const { addIdentifiers, removeIdentifiers, scopes } = context;
14286 const { source, value, key, index } = parseResult;
14287 const forNode = {
14288 type: 11 /* NodeTypes.FOR */,
14289 loc: dir.loc,
14290 source,
14291 valueAlias: value,
14292 keyAlias: key,
14293 objectIndexAlias: index,
14294 parseResult,
14295 children: isTemplateNode(node) ? node.children : [node]
14296 };
14297 context.replaceNode(forNode);
14298 // bookkeeping
14299 scopes.vFor++;
14300 const onExit = processCodegen && processCodegen(forNode);
14301 return () => {
14302 scopes.vFor--;
14303 if (onExit)
14304 onExit();
14305 };
14306}
14307const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
14308// This regex doesn't cover the case if key or index aliases have destructuring,
14309// but those do not make sense in the first place, so this works in practice.
14310const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
14311const stripParensRE = /^\(|\)$/g;
14312function parseForExpression(input, context) {
14313 const loc = input.loc;
14314 const exp = input.content;
14315 const inMatch = exp.match(forAliasRE);
14316 if (!inMatch)
14317 return;
14318 const [, LHS, RHS] = inMatch;
14319 const result = {
14320 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
14321 value: undefined,
14322 key: undefined,
14323 index: undefined
14324 };
14325 {
14326 validateBrowserExpression(result.source, context);
14327 }
14328 let valueContent = LHS.trim().replace(stripParensRE, '').trim();
14329 const trimmedOffset = LHS.indexOf(valueContent);
14330 const iteratorMatch = valueContent.match(forIteratorRE);
14331 if (iteratorMatch) {
14332 valueContent = valueContent.replace(forIteratorRE, '').trim();
14333 const keyContent = iteratorMatch[1].trim();
14334 let keyOffset;
14335 if (keyContent) {
14336 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
14337 result.key = createAliasExpression(loc, keyContent, keyOffset);
14338 {
14339 validateBrowserExpression(result.key, context, true);
14340 }
14341 }
14342 if (iteratorMatch[2]) {
14343 const indexContent = iteratorMatch[2].trim();
14344 if (indexContent) {
14345 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
14346 ? keyOffset + keyContent.length
14347 : trimmedOffset + valueContent.length));
14348 {
14349 validateBrowserExpression(result.index, context, true);
14350 }
14351 }
14352 }
14353 }
14354 if (valueContent) {
14355 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
14356 {
14357 validateBrowserExpression(result.value, context, true);
14358 }
14359 }
14360 return result;
14361}
14362function createAliasExpression(range, content, offset) {
14363 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
14364}
14365function createForLoopParams({ value, key, index }, memoArgs = []) {
14366 return createParamsList([value, key, index, ...memoArgs]);
14367}
14368function createParamsList(args) {
14369 let i = args.length;
14370 while (i--) {
14371 if (args[i])
14372 break;
14373 }
14374 return args
14375 .slice(0, i + 1)
14376 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
14377}
14378
14379const defaultFallback = createSimpleExpression(`undefined`, false);
14380// A NodeTransform that:
14381// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
14382// by transformExpression. This is only applied in non-browser builds with
14383// { prefixIdentifiers: true }.
14384// 2. Track v-slot depths so that we know a slot is inside another slot.
14385// Note the exit callback is executed before buildSlots() on the same node,
14386// so only nested slots see positive numbers.
14387const trackSlotScopes = (node, context) => {
14388 if (node.type === 1 /* NodeTypes.ELEMENT */ &&
14389 (node.tagType === 1 /* ElementTypes.COMPONENT */ ||
14390 node.tagType === 3 /* ElementTypes.TEMPLATE */)) {
14391 // We are only checking non-empty v-slot here
14392 // since we only care about slots that introduce scope variables.
14393 const vSlot = findDir(node, 'slot');
14394 if (vSlot) {
14395 vSlot.exp;
14396 context.scopes.vSlot++;
14397 return () => {
14398 context.scopes.vSlot--;
14399 };
14400 }
14401 }
14402};
14403const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
14404// Instead of being a DirectiveTransform, v-slot processing is called during
14405// transformElement to build the slots object for a component.
14406function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
14407 context.helper(WITH_CTX);
14408 const { children, loc } = node;
14409 const slotsProperties = [];
14410 const dynamicSlots = [];
14411 // If the slot is inside a v-for or another v-slot, force it to be dynamic
14412 // since it likely uses a scope variable.
14413 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
14414 // 1. Check for slot with slotProps on component itself.
14415 // <Comp v-slot="{ prop }"/>
14416 const onComponentSlot = findDir(node, 'slot', true);
14417 if (onComponentSlot) {
14418 const { arg, exp } = onComponentSlot;
14419 if (arg && !isStaticExp(arg)) {
14420 hasDynamicSlots = true;
14421 }
14422 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
14423 }
14424 // 2. Iterate through children and check for template slots
14425 // <template v-slot:foo="{ prop }">
14426 let hasTemplateSlots = false;
14427 let hasNamedDefaultSlot = false;
14428 const implicitDefaultChildren = [];
14429 const seenSlotNames = new Set();
14430 let conditionalBranchIndex = 0;
14431 for (let i = 0; i < children.length; i++) {
14432 const slotElement = children[i];
14433 let slotDir;
14434 if (!isTemplateNode(slotElement) ||
14435 !(slotDir = findDir(slotElement, 'slot', true))) {
14436 // not a <template v-slot>, skip.
14437 if (slotElement.type !== 3 /* NodeTypes.COMMENT */) {
14438 implicitDefaultChildren.push(slotElement);
14439 }
14440 continue;
14441 }
14442 if (onComponentSlot) {
14443 // already has on-component slot - this is incorrect usage.
14444 context.onError(createCompilerError(37 /* ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
14445 break;
14446 }
14447 hasTemplateSlots = true;
14448 const { children: slotChildren, loc: slotLoc } = slotElement;
14449 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
14450 // check if name is dynamic.
14451 let staticSlotName;
14452 if (isStaticExp(slotName)) {
14453 staticSlotName = slotName ? slotName.content : `default`;
14454 }
14455 else {
14456 hasDynamicSlots = true;
14457 }
14458 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
14459 // check if this slot is conditional (v-if/v-for)
14460 let vIf;
14461 let vElse;
14462 let vFor;
14463 if ((vIf = findDir(slotElement, 'if'))) {
14464 hasDynamicSlots = true;
14465 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++), defaultFallback));
14466 }
14467 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
14468 // find adjacent v-if
14469 let j = i;
14470 let prev;
14471 while (j--) {
14472 prev = children[j];
14473 if (prev.type !== 3 /* NodeTypes.COMMENT */) {
14474 break;
14475 }
14476 }
14477 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
14478 // remove node
14479 children.splice(i, 1);
14480 i--;
14481 // attach this slot to previous conditional
14482 let conditional = dynamicSlots[dynamicSlots.length - 1];
14483 while (conditional.alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) {
14484 conditional = conditional.alternate;
14485 }
14486 conditional.alternate = vElse.exp
14487 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++), defaultFallback)
14488 : buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++);
14489 }
14490 else {
14491 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
14492 }
14493 }
14494 else if ((vFor = findDir(slotElement, 'for'))) {
14495 hasDynamicSlots = true;
14496 const parseResult = vFor.parseResult ||
14497 parseForExpression(vFor.exp, context);
14498 if (parseResult) {
14499 // Render the dynamic slots as an array and add it to the createSlot()
14500 // args. The runtime knows how to handle it appropriately.
14501 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
14502 parseResult.source,
14503 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
14504 ]));
14505 }
14506 else {
14507 context.onError(createCompilerError(32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
14508 }
14509 }
14510 else {
14511 // check duplicate static names
14512 if (staticSlotName) {
14513 if (seenSlotNames.has(staticSlotName)) {
14514 context.onError(createCompilerError(38 /* ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
14515 continue;
14516 }
14517 seenSlotNames.add(staticSlotName);
14518 if (staticSlotName === 'default') {
14519 hasNamedDefaultSlot = true;
14520 }
14521 }
14522 slotsProperties.push(createObjectProperty(slotName, slotFunction));
14523 }
14524 }
14525 if (!onComponentSlot) {
14526 const buildDefaultSlotProperty = (props, children) => {
14527 const fn = buildSlotFn(props, children, loc);
14528 return createObjectProperty(`default`, fn);
14529 };
14530 if (!hasTemplateSlots) {
14531 // implicit default slot (on component)
14532 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
14533 }
14534 else if (implicitDefaultChildren.length &&
14535 // #3766
14536 // with whitespace: 'preserve', whitespaces between slots will end up in
14537 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
14538 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
14539 // implicit default slot (mixed with named slots)
14540 if (hasNamedDefaultSlot) {
14541 context.onError(createCompilerError(39 /* ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
14542 }
14543 else {
14544 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
14545 }
14546 }
14547 }
14548 const slotFlag = hasDynamicSlots
14549 ? 2 /* SlotFlags.DYNAMIC */
14550 : hasForwardedSlots(node.children)
14551 ? 3 /* SlotFlags.FORWARDED */
14552 : 1 /* SlotFlags.STABLE */;
14553 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
14554 // 2 = compiled but dynamic = can skip normalization, but must run diff
14555 // 1 = compiled and static = can skip normalization AND diff as optimized
14556 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
14557 if (dynamicSlots.length) {
14558 slots = createCallExpression(context.helper(CREATE_SLOTS), [
14559 slots,
14560 createArrayExpression(dynamicSlots)
14561 ]);
14562 }
14563 return {
14564 slots,
14565 hasDynamicSlots
14566 };
14567}
14568function buildDynamicSlot(name, fn, index) {
14569 const props = [
14570 createObjectProperty(`name`, name),
14571 createObjectProperty(`fn`, fn)
14572 ];
14573 if (index != null) {
14574 props.push(createObjectProperty(`key`, createSimpleExpression(String(index), true)));
14575 }
14576 return createObjectExpression(props);
14577}
14578function hasForwardedSlots(children) {
14579 for (let i = 0; i < children.length; i++) {
14580 const child = children[i];
14581 switch (child.type) {
14582 case 1 /* NodeTypes.ELEMENT */:
14583 if (child.tagType === 2 /* ElementTypes.SLOT */ ||
14584 hasForwardedSlots(child.children)) {
14585 return true;
14586 }
14587 break;
14588 case 9 /* NodeTypes.IF */:
14589 if (hasForwardedSlots(child.branches))
14590 return true;
14591 break;
14592 case 10 /* NodeTypes.IF_BRANCH */:
14593 case 11 /* NodeTypes.FOR */:
14594 if (hasForwardedSlots(child.children))
14595 return true;
14596 break;
14597 }
14598 }
14599 return false;
14600}
14601function isNonWhitespaceContent(node) {
14602 if (node.type !== 2 /* NodeTypes.TEXT */ && node.type !== 12 /* NodeTypes.TEXT_CALL */)
14603 return true;
14604 return node.type === 2 /* NodeTypes.TEXT */
14605 ? !!node.content.trim()
14606 : isNonWhitespaceContent(node.content);
14607}
14608
14609// some directive transforms (e.g. v-model) may return a symbol for runtime
14610// import, which should be used instead of a resolveDirective call.
14611const directiveImportMap = new WeakMap();
14612// generate a JavaScript AST for this element's codegen
14613const transformElement = (node, context) => {
14614 // perform the work on exit, after all child expressions have been
14615 // processed and merged.
14616 return function postTransformElement() {
14617 node = context.currentNode;
14618 if (!(node.type === 1 /* NodeTypes.ELEMENT */ &&
14619 (node.tagType === 0 /* ElementTypes.ELEMENT */ ||
14620 node.tagType === 1 /* ElementTypes.COMPONENT */))) {
14621 return;
14622 }
14623 const { tag, props } = node;
14624 const isComponent = node.tagType === 1 /* ElementTypes.COMPONENT */;
14625 // The goal of the transform is to create a codegenNode implementing the
14626 // VNodeCall interface.
14627 let vnodeTag = isComponent
14628 ? resolveComponentType(node, context)
14629 : `"${tag}"`;
14630 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
14631 let vnodeProps;
14632 let vnodeChildren;
14633 let vnodePatchFlag;
14634 let patchFlag = 0;
14635 let vnodeDynamicProps;
14636 let dynamicPropNames;
14637 let vnodeDirectives;
14638 let shouldUseBlock =
14639 // dynamic component may resolve to plain elements
14640 isDynamicComponent ||
14641 vnodeTag === TELEPORT ||
14642 vnodeTag === SUSPENSE ||
14643 (!isComponent &&
14644 // <svg> and <foreignObject> must be forced into blocks so that block
14645 // updates inside get proper isSVG flag at runtime. (#639, #643)
14646 // This is technically web-specific, but splitting the logic out of core
14647 // leads to too much unnecessary complexity.
14648 (tag === 'svg' || tag === 'foreignObject'));
14649 // props
14650 if (props.length > 0) {
14651 const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
14652 vnodeProps = propsBuildResult.props;
14653 patchFlag = propsBuildResult.patchFlag;
14654 dynamicPropNames = propsBuildResult.dynamicPropNames;
14655 const directives = propsBuildResult.directives;
14656 vnodeDirectives =
14657 directives && directives.length
14658 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14659 : undefined;
14660 if (propsBuildResult.shouldUseBlock) {
14661 shouldUseBlock = true;
14662 }
14663 }
14664 // children
14665 if (node.children.length > 0) {
14666 if (vnodeTag === KEEP_ALIVE) {
14667 // Although a built-in component, we compile KeepAlive with raw children
14668 // instead of slot functions so that it can be used inside Transition
14669 // or other Transition-wrapping HOCs.
14670 // To ensure correct updates with block optimizations, we need to:
14671 // 1. Force keep-alive into a block. This avoids its children being
14672 // collected by a parent block.
14673 shouldUseBlock = true;
14674 // 2. Force keep-alive to always be updated, since it uses raw children.
14675 patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */;
14676 if (node.children.length > 1) {
14677 context.onError(createCompilerError(46 /* ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN */, {
14678 start: node.children[0].loc.start,
14679 end: node.children[node.children.length - 1].loc.end,
14680 source: ''
14681 }));
14682 }
14683 }
14684 const shouldBuildAsSlots = isComponent &&
14685 // Teleport is not a real component and has dedicated runtime handling
14686 vnodeTag !== TELEPORT &&
14687 // explained above.
14688 vnodeTag !== KEEP_ALIVE;
14689 if (shouldBuildAsSlots) {
14690 const { slots, hasDynamicSlots } = buildSlots(node, context);
14691 vnodeChildren = slots;
14692 if (hasDynamicSlots) {
14693 patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */;
14694 }
14695 }
14696 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
14697 const child = node.children[0];
14698 const type = child.type;
14699 // check for dynamic text children
14700 const hasDynamicTextChild = type === 5 /* NodeTypes.INTERPOLATION */ ||
14701 type === 8 /* NodeTypes.COMPOUND_EXPRESSION */;
14702 if (hasDynamicTextChild &&
14703 getConstantType(child, context) === 0 /* ConstantTypes.NOT_CONSTANT */) {
14704 patchFlag |= 1 /* PatchFlags.TEXT */;
14705 }
14706 // pass directly if the only child is a text node
14707 // (plain / interpolation / expression)
14708 if (hasDynamicTextChild || type === 2 /* NodeTypes.TEXT */) {
14709 vnodeChildren = child;
14710 }
14711 else {
14712 vnodeChildren = node.children;
14713 }
14714 }
14715 else {
14716 vnodeChildren = node.children;
14717 }
14718 }
14719 // patchFlag & dynamicPropNames
14720 if (patchFlag !== 0) {
14721 {
14722 if (patchFlag < 0) {
14723 // special flags (negative and mutually exclusive)
14724 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
14725 }
14726 else {
14727 // bitwise flags
14728 const flagNames = Object.keys(PatchFlagNames)
14729 .map(Number)
14730 .filter(n => n > 0 && patchFlag & n)
14731 .map(n => PatchFlagNames[n])
14732 .join(`, `);
14733 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
14734 }
14735 }
14736 if (dynamicPropNames && dynamicPropNames.length) {
14737 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
14738 }
14739 }
14740 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
14741 };
14742};
14743function resolveComponentType(node, context, ssr = false) {
14744 let { tag } = node;
14745 // 1. dynamic component
14746 const isExplicitDynamic = isComponentTag(tag);
14747 const isProp = findProp(node, 'is');
14748 if (isProp) {
14749 if (isExplicitDynamic ||
14750 (false )) {
14751 const exp = isProp.type === 6 /* NodeTypes.ATTRIBUTE */
14752 ? isProp.value && createSimpleExpression(isProp.value.content, true)
14753 : isProp.exp;
14754 if (exp) {
14755 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14756 exp
14757 ]);
14758 }
14759 }
14760 else if (isProp.type === 6 /* NodeTypes.ATTRIBUTE */ &&
14761 isProp.value.content.startsWith('vue:')) {
14762 // <button is="vue:xxx">
14763 // if not <component>, only is value that starts with "vue:" will be
14764 // treated as component by the parse phase and reach here, unless it's
14765 // compat mode where all is values are considered components
14766 tag = isProp.value.content.slice(4);
14767 }
14768 }
14769 // 1.5 v-is (TODO: Deprecate)
14770 const isDir = !isExplicitDynamic && findDir(node, 'is');
14771 if (isDir && isDir.exp) {
14772 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14773 isDir.exp
14774 ]);
14775 }
14776 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
14777 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
14778 if (builtIn) {
14779 // built-ins are simply fallthroughs / have special handling during ssr
14780 // so we don't need to import their runtime equivalents
14781 if (!ssr)
14782 context.helper(builtIn);
14783 return builtIn;
14784 }
14785 // 5. user component (resolve)
14786 context.helper(RESOLVE_COMPONENT);
14787 context.components.add(tag);
14788 return toValidAssetId(tag, `component`);
14789}
14790function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
14791 const { tag, loc: elementLoc, children } = node;
14792 let properties = [];
14793 const mergeArgs = [];
14794 const runtimeDirectives = [];
14795 const hasChildren = children.length > 0;
14796 let shouldUseBlock = false;
14797 // patchFlag analysis
14798 let patchFlag = 0;
14799 let hasRef = false;
14800 let hasClassBinding = false;
14801 let hasStyleBinding = false;
14802 let hasHydrationEventBinding = false;
14803 let hasDynamicKeys = false;
14804 let hasVnodeHook = false;
14805 const dynamicPropNames = [];
14806 const pushMergeArg = (arg) => {
14807 if (properties.length) {
14808 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14809 properties = [];
14810 }
14811 if (arg)
14812 mergeArgs.push(arg);
14813 };
14814 const analyzePatchFlag = ({ key, value }) => {
14815 if (isStaticExp(key)) {
14816 const name = key.content;
14817 const isEventHandler = isOn(name);
14818 if (isEventHandler &&
14819 (!isComponent || isDynamicComponent) &&
14820 // omit the flag for click handlers because hydration gives click
14821 // dedicated fast path.
14822 name.toLowerCase() !== 'onclick' &&
14823 // omit v-model handlers
14824 name !== 'onUpdate:modelValue' &&
14825 // omit onVnodeXXX hooks
14826 !isReservedProp(name)) {
14827 hasHydrationEventBinding = true;
14828 }
14829 if (isEventHandler && isReservedProp(name)) {
14830 hasVnodeHook = true;
14831 }
14832 if (value.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */ ||
14833 ((value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
14834 value.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) &&
14835 getConstantType(value, context) > 0)) {
14836 // skip if the prop is a cached handler or has constant value
14837 return;
14838 }
14839 if (name === 'ref') {
14840 hasRef = true;
14841 }
14842 else if (name === 'class') {
14843 hasClassBinding = true;
14844 }
14845 else if (name === 'style') {
14846 hasStyleBinding = true;
14847 }
14848 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
14849 dynamicPropNames.push(name);
14850 }
14851 // treat the dynamic class and style binding of the component as dynamic props
14852 if (isComponent &&
14853 (name === 'class' || name === 'style') &&
14854 !dynamicPropNames.includes(name)) {
14855 dynamicPropNames.push(name);
14856 }
14857 }
14858 else {
14859 hasDynamicKeys = true;
14860 }
14861 };
14862 for (let i = 0; i < props.length; i++) {
14863 // static attribute
14864 const prop = props[i];
14865 if (prop.type === 6 /* NodeTypes.ATTRIBUTE */) {
14866 const { loc, name, value } = prop;
14867 let isStatic = true;
14868 if (name === 'ref') {
14869 hasRef = true;
14870 if (context.scopes.vFor > 0) {
14871 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14872 }
14873 }
14874 // skip is on <component>, or is="vue:xxx"
14875 if (name === 'is' &&
14876 (isComponentTag(tag) ||
14877 (value && value.content.startsWith('vue:')) ||
14878 (false ))) {
14879 continue;
14880 }
14881 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14882 }
14883 else {
14884 // directives
14885 const { name, arg, exp, loc } = prop;
14886 const isVBind = name === 'bind';
14887 const isVOn = name === 'on';
14888 // skip v-slot - it is handled by its dedicated transform.
14889 if (name === 'slot') {
14890 if (!isComponent) {
14891 context.onError(createCompilerError(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, loc));
14892 }
14893 continue;
14894 }
14895 // skip v-once/v-memo - they are handled by dedicated transforms.
14896 if (name === 'once' || name === 'memo') {
14897 continue;
14898 }
14899 // skip v-is and :is on <component>
14900 if (name === 'is' ||
14901 (isVBind &&
14902 isStaticArgOf(arg, 'is') &&
14903 (isComponentTag(tag) ||
14904 (false )))) {
14905 continue;
14906 }
14907 // skip v-on in SSR compilation
14908 if (isVOn && ssr) {
14909 continue;
14910 }
14911 if (
14912 // #938: elements with dynamic keys should be forced into blocks
14913 (isVBind && isStaticArgOf(arg, 'key')) ||
14914 // inline before-update hooks need to force block so that it is invoked
14915 // before children
14916 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14917 shouldUseBlock = true;
14918 }
14919 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14920 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14921 }
14922 // special case for v-bind and v-on with no argument
14923 if (!arg && (isVBind || isVOn)) {
14924 hasDynamicKeys = true;
14925 if (exp) {
14926 if (isVBind) {
14927 // have to merge early for compat build check
14928 pushMergeArg();
14929 mergeArgs.push(exp);
14930 }
14931 else {
14932 // v-on="obj" -> toHandlers(obj)
14933 pushMergeArg({
14934 type: 14 /* NodeTypes.JS_CALL_EXPRESSION */,
14935 loc,
14936 callee: context.helper(TO_HANDLERS),
14937 arguments: isComponent ? [exp] : [exp, `true`]
14938 });
14939 }
14940 }
14941 else {
14942 context.onError(createCompilerError(isVBind
14943 ? 34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */
14944 : 35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */, loc));
14945 }
14946 continue;
14947 }
14948 const directiveTransform = context.directiveTransforms[name];
14949 if (directiveTransform) {
14950 // has built-in directive transform.
14951 const { props, needRuntime } = directiveTransform(prop, node, context);
14952 !ssr && props.forEach(analyzePatchFlag);
14953 if (isVOn && arg && !isStaticExp(arg)) {
14954 pushMergeArg(createObjectExpression(props, elementLoc));
14955 }
14956 else {
14957 properties.push(...props);
14958 }
14959 if (needRuntime) {
14960 runtimeDirectives.push(prop);
14961 if (isSymbol(needRuntime)) {
14962 directiveImportMap.set(prop, needRuntime);
14963 }
14964 }
14965 }
14966 else if (!isBuiltInDirective(name)) {
14967 // no built-in transform, this is a user custom directive.
14968 runtimeDirectives.push(prop);
14969 // custom dirs may use beforeUpdate so they need to force blocks
14970 // to ensure before-update gets called before children update
14971 if (hasChildren) {
14972 shouldUseBlock = true;
14973 }
14974 }
14975 }
14976 }
14977 let propsExpression = undefined;
14978 // has v-bind="object" or v-on="object", wrap with mergeProps
14979 if (mergeArgs.length) {
14980 // close up any not-yet-merged props
14981 pushMergeArg();
14982 if (mergeArgs.length > 1) {
14983 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
14984 }
14985 else {
14986 // single v-bind with nothing else - no need for a mergeProps call
14987 propsExpression = mergeArgs[0];
14988 }
14989 }
14990 else if (properties.length) {
14991 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
14992 }
14993 // patchFlag analysis
14994 if (hasDynamicKeys) {
14995 patchFlag |= 16 /* PatchFlags.FULL_PROPS */;
14996 }
14997 else {
14998 if (hasClassBinding && !isComponent) {
14999 patchFlag |= 2 /* PatchFlags.CLASS */;
15000 }
15001 if (hasStyleBinding && !isComponent) {
15002 patchFlag |= 4 /* PatchFlags.STYLE */;
15003 }
15004 if (dynamicPropNames.length) {
15005 patchFlag |= 8 /* PatchFlags.PROPS */;
15006 }
15007 if (hasHydrationEventBinding) {
15008 patchFlag |= 32 /* PatchFlags.HYDRATE_EVENTS */;
15009 }
15010 }
15011 if (!shouldUseBlock &&
15012 (patchFlag === 0 || patchFlag === 32 /* PatchFlags.HYDRATE_EVENTS */) &&
15013 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
15014 patchFlag |= 512 /* PatchFlags.NEED_PATCH */;
15015 }
15016 // pre-normalize props, SSR is skipped for now
15017 if (!context.inSSR && propsExpression) {
15018 switch (propsExpression.type) {
15019 case 15 /* NodeTypes.JS_OBJECT_EXPRESSION */:
15020 // means that there is no v-bind,
15021 // but still need to deal with dynamic key binding
15022 let classKeyIndex = -1;
15023 let styleKeyIndex = -1;
15024 let hasDynamicKey = false;
15025 for (let i = 0; i < propsExpression.properties.length; i++) {
15026 const key = propsExpression.properties[i].key;
15027 if (isStaticExp(key)) {
15028 if (key.content === 'class') {
15029 classKeyIndex = i;
15030 }
15031 else if (key.content === 'style') {
15032 styleKeyIndex = i;
15033 }
15034 }
15035 else if (!key.isHandlerKey) {
15036 hasDynamicKey = true;
15037 }
15038 }
15039 const classProp = propsExpression.properties[classKeyIndex];
15040 const styleProp = propsExpression.properties[styleKeyIndex];
15041 // no dynamic key
15042 if (!hasDynamicKey) {
15043 if (classProp && !isStaticExp(classProp.value)) {
15044 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
15045 }
15046 if (styleProp &&
15047 // the static style is compiled into an object,
15048 // so use `hasStyleBinding` to ensure that it is a dynamic style binding
15049 (hasStyleBinding ||
15050 (styleProp.value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
15051 styleProp.value.content.trim()[0] === `[`) ||
15052 // v-bind:style and style both exist,
15053 // v-bind:style with static literal object
15054 styleProp.value.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */)) {
15055 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
15056 }
15057 }
15058 else {
15059 // dynamic key binding, wrap with `normalizeProps`
15060 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
15061 }
15062 break;
15063 case 14 /* NodeTypes.JS_CALL_EXPRESSION */:
15064 // mergeProps call, do nothing
15065 break;
15066 default:
15067 // single v-bind
15068 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
15069 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
15070 propsExpression
15071 ])
15072 ]);
15073 break;
15074 }
15075 }
15076 return {
15077 props: propsExpression,
15078 directives: runtimeDirectives,
15079 patchFlag,
15080 dynamicPropNames,
15081 shouldUseBlock
15082 };
15083}
15084// Dedupe props in an object literal.
15085// Literal duplicated attributes would have been warned during the parse phase,
15086// however, it's possible to encounter duplicated `onXXX` handlers with different
15087// modifiers. We also need to merge static and dynamic class / style attributes.
15088// - onXXX handlers / style: merge into array
15089// - class: merge into single expression with concatenation
15090function dedupeProperties(properties) {
15091 const knownProps = new Map();
15092 const deduped = [];
15093 for (let i = 0; i < properties.length; i++) {
15094 const prop = properties[i];
15095 // dynamic keys are always allowed
15096 if (prop.key.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
15097 deduped.push(prop);
15098 continue;
15099 }
15100 const name = prop.key.content;
15101 const existing = knownProps.get(name);
15102 if (existing) {
15103 if (name === 'style' || name === 'class' || isOn(name)) {
15104 mergeAsArray(existing, prop);
15105 }
15106 // unexpected duplicate, should have emitted error during parse
15107 }
15108 else {
15109 knownProps.set(name, prop);
15110 deduped.push(prop);
15111 }
15112 }
15113 return deduped;
15114}
15115function mergeAsArray(existing, incoming) {
15116 if (existing.value.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */) {
15117 existing.value.elements.push(incoming.value);
15118 }
15119 else {
15120 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
15121 }
15122}
15123function buildDirectiveArgs(dir, context) {
15124 const dirArgs = [];
15125 const runtime = directiveImportMap.get(dir);
15126 if (runtime) {
15127 // built-in directive with runtime
15128 dirArgs.push(context.helperString(runtime));
15129 }
15130 else {
15131 {
15132 // inject statement for resolving directive
15133 context.helper(RESOLVE_DIRECTIVE);
15134 context.directives.add(dir.name);
15135 dirArgs.push(toValidAssetId(dir.name, `directive`));
15136 }
15137 }
15138 const { loc } = dir;
15139 if (dir.exp)
15140 dirArgs.push(dir.exp);
15141 if (dir.arg) {
15142 if (!dir.exp) {
15143 dirArgs.push(`void 0`);
15144 }
15145 dirArgs.push(dir.arg);
15146 }
15147 if (Object.keys(dir.modifiers).length) {
15148 if (!dir.arg) {
15149 if (!dir.exp) {
15150 dirArgs.push(`void 0`);
15151 }
15152 dirArgs.push(`void 0`);
15153 }
15154 const trueExpression = createSimpleExpression(`true`, false, loc);
15155 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
15156 }
15157 return createArrayExpression(dirArgs, dir.loc);
15158}
15159function stringifyDynamicPropNames(props) {
15160 let propsNamesString = `[`;
15161 for (let i = 0, l = props.length; i < l; i++) {
15162 propsNamesString += JSON.stringify(props[i]);
15163 if (i < l - 1)
15164 propsNamesString += ', ';
15165 }
15166 return propsNamesString + `]`;
15167}
15168function isComponentTag(tag) {
15169 return tag === 'component' || tag === 'Component';
15170}
15171
15172const transformSlotOutlet = (node, context) => {
15173 if (isSlotOutlet(node)) {
15174 const { children, loc } = node;
15175 const { slotName, slotProps } = processSlotOutlet(node, context);
15176 const slotArgs = [
15177 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
15178 slotName,
15179 '{}',
15180 'undefined',
15181 'true'
15182 ];
15183 let expectedLen = 2;
15184 if (slotProps) {
15185 slotArgs[2] = slotProps;
15186 expectedLen = 3;
15187 }
15188 if (children.length) {
15189 slotArgs[3] = createFunctionExpression([], children, false, false, loc);
15190 expectedLen = 4;
15191 }
15192 if (context.scopeId && !context.slotted) {
15193 expectedLen = 5;
15194 }
15195 slotArgs.splice(expectedLen); // remove unused arguments
15196 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
15197 }
15198};
15199function processSlotOutlet(node, context) {
15200 let slotName = `"default"`;
15201 let slotProps = undefined;
15202 const nonNameProps = [];
15203 for (let i = 0; i < node.props.length; i++) {
15204 const p = node.props[i];
15205 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
15206 if (p.value) {
15207 if (p.name === 'name') {
15208 slotName = JSON.stringify(p.value.content);
15209 }
15210 else {
15211 p.name = camelize(p.name);
15212 nonNameProps.push(p);
15213 }
15214 }
15215 }
15216 else {
15217 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
15218 if (p.exp)
15219 slotName = p.exp;
15220 }
15221 else {
15222 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
15223 p.arg.content = camelize(p.arg.content);
15224 }
15225 nonNameProps.push(p);
15226 }
15227 }
15228 }
15229 if (nonNameProps.length > 0) {
15230 const { props, directives } = buildProps(node, context, nonNameProps, false, false);
15231 slotProps = props;
15232 if (directives.length) {
15233 context.onError(createCompilerError(36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
15234 }
15235 }
15236 return {
15237 slotName,
15238 slotProps
15239 };
15240}
15241
15242const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
15243const transformOn$1 = (dir, node, context, augmentor) => {
15244 const { loc, modifiers, arg } = dir;
15245 if (!dir.exp && !modifiers.length) {
15246 context.onError(createCompilerError(35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */, loc));
15247 }
15248 let eventName;
15249 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15250 if (arg.isStatic) {
15251 let rawName = arg.content;
15252 // TODO deprecate @vnodeXXX usage
15253 if (rawName.startsWith('vue:')) {
15254 rawName = `vnode-${rawName.slice(4)}`;
15255 }
15256 const eventString = node.tagType !== 0 /* ElementTypes.ELEMENT */ ||
15257 rawName.startsWith('vnode') ||
15258 !/[A-Z]/.test(rawName)
15259 ? // for non-element and vnode lifecycle event listeners, auto convert
15260 // it to camelCase. See issue #2249
15261 toHandlerKey(camelize(rawName))
15262 : // preserve case for plain element listeners that have uppercase
15263 // letters, as these may be custom elements' custom events
15264 `on:${rawName}`;
15265 eventName = createSimpleExpression(eventString, true, arg.loc);
15266 }
15267 else {
15268 // #2388
15269 eventName = createCompoundExpression([
15270 `${context.helperString(TO_HANDLER_KEY)}(`,
15271 arg,
15272 `)`
15273 ]);
15274 }
15275 }
15276 else {
15277 // already a compound expression.
15278 eventName = arg;
15279 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
15280 eventName.children.push(`)`);
15281 }
15282 // handler processing
15283 let exp = dir.exp;
15284 if (exp && !exp.content.trim()) {
15285 exp = undefined;
15286 }
15287 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
15288 if (exp) {
15289 const isMemberExp = isMemberExpression(exp.content);
15290 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
15291 const hasMultipleStatements = exp.content.includes(`;`);
15292 {
15293 validateBrowserExpression(exp, context, false, hasMultipleStatements);
15294 }
15295 if (isInlineStatement || (shouldCache && isMemberExp)) {
15296 // wrap inline statement in a function expression
15297 exp = createCompoundExpression([
15298 `${isInlineStatement
15299 ? `$event`
15300 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
15301 exp,
15302 hasMultipleStatements ? `}` : `)`
15303 ]);
15304 }
15305 }
15306 let ret = {
15307 props: [
15308 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
15309 ]
15310 };
15311 // apply extended compiler augmentor
15312 if (augmentor) {
15313 ret = augmentor(ret);
15314 }
15315 if (shouldCache) {
15316 // cache handlers so that it's always the same handler being passed down.
15317 // this avoids unnecessary re-renders when users use inline handlers on
15318 // components.
15319 ret.props[0].value = context.cache(ret.props[0].value);
15320 }
15321 // mark the key as handler for props normalization check
15322 ret.props.forEach(p => (p.key.isHandlerKey = true));
15323 return ret;
15324};
15325
15326// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
15327// codegen for the entire props object. This transform here is only for v-bind
15328// *with* args.
15329const transformBind = (dir, _node, context) => {
15330 const { exp, modifiers, loc } = dir;
15331 const arg = dir.arg;
15332 if (arg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15333 arg.children.unshift(`(`);
15334 arg.children.push(`) || ""`);
15335 }
15336 else if (!arg.isStatic) {
15337 arg.content = `${arg.content} || ""`;
15338 }
15339 // .sync is replaced by v-model:arg
15340 if (modifiers.includes('camel')) {
15341 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15342 if (arg.isStatic) {
15343 arg.content = camelize(arg.content);
15344 }
15345 else {
15346 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
15347 }
15348 }
15349 else {
15350 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
15351 arg.children.push(`)`);
15352 }
15353 }
15354 if (!context.inSSR) {
15355 if (modifiers.includes('prop')) {
15356 injectPrefix(arg, '.');
15357 }
15358 if (modifiers.includes('attr')) {
15359 injectPrefix(arg, '^');
15360 }
15361 }
15362 if (!exp ||
15363 (exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && !exp.content.trim())) {
15364 context.onError(createCompilerError(34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */, loc));
15365 return {
15366 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
15367 };
15368 }
15369 return {
15370 props: [createObjectProperty(arg, exp)]
15371 };
15372};
15373const injectPrefix = (arg, prefix) => {
15374 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15375 if (arg.isStatic) {
15376 arg.content = prefix + arg.content;
15377 }
15378 else {
15379 arg.content = `\`${prefix}\${${arg.content}}\``;
15380 }
15381 }
15382 else {
15383 arg.children.unshift(`'${prefix}' + (`);
15384 arg.children.push(`)`);
15385 }
15386};
15387
15388// Merge adjacent text nodes and expressions into a single expression
15389// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
15390const transformText = (node, context) => {
15391 if (node.type === 0 /* NodeTypes.ROOT */ ||
15392 node.type === 1 /* NodeTypes.ELEMENT */ ||
15393 node.type === 11 /* NodeTypes.FOR */ ||
15394 node.type === 10 /* NodeTypes.IF_BRANCH */) {
15395 // perform the transform on node exit so that all expressions have already
15396 // been processed.
15397 return () => {
15398 const children = node.children;
15399 let currentContainer = undefined;
15400 let hasText = false;
15401 for (let i = 0; i < children.length; i++) {
15402 const child = children[i];
15403 if (isText$1(child)) {
15404 hasText = true;
15405 for (let j = i + 1; j < children.length; j++) {
15406 const next = children[j];
15407 if (isText$1(next)) {
15408 if (!currentContainer) {
15409 currentContainer = children[i] = createCompoundExpression([child], child.loc);
15410 }
15411 // merge adjacent text node into current
15412 currentContainer.children.push(` + `, next);
15413 children.splice(j, 1);
15414 j--;
15415 }
15416 else {
15417 currentContainer = undefined;
15418 break;
15419 }
15420 }
15421 }
15422 }
15423 if (!hasText ||
15424 // if this is a plain element with a single text child, leave it
15425 // as-is since the runtime has dedicated fast path for this by directly
15426 // setting textContent of the element.
15427 // for component root it's always normalized anyway.
15428 (children.length === 1 &&
15429 (node.type === 0 /* NodeTypes.ROOT */ ||
15430 (node.type === 1 /* NodeTypes.ELEMENT */ &&
15431 node.tagType === 0 /* ElementTypes.ELEMENT */ &&
15432 // #3756
15433 // custom directives can potentially add DOM elements arbitrarily,
15434 // we need to avoid setting textContent of the element at runtime
15435 // to avoid accidentally overwriting the DOM elements added
15436 // by the user through custom directives.
15437 !node.props.find(p => p.type === 7 /* NodeTypes.DIRECTIVE */ &&
15438 !context.directiveTransforms[p.name]) &&
15439 // in compat mode, <template> tags with no special directives
15440 // will be rendered as a fragment so its children must be
15441 // converted into vnodes.
15442 !(false ))))) {
15443 return;
15444 }
15445 // pre-convert text nodes into createTextVNode(text) calls to avoid
15446 // runtime normalization.
15447 for (let i = 0; i < children.length; i++) {
15448 const child = children[i];
15449 if (isText$1(child) || child.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
15450 const callArgs = [];
15451 // createTextVNode defaults to single whitespace, so if it is a
15452 // single space the code could be an empty call to save bytes.
15453 if (child.type !== 2 /* NodeTypes.TEXT */ || child.content !== ' ') {
15454 callArgs.push(child);
15455 }
15456 // mark dynamic text with flag so it gets patched inside a block
15457 if (!context.ssr &&
15458 getConstantType(child, context) === 0 /* ConstantTypes.NOT_CONSTANT */) {
15459 callArgs.push(1 /* PatchFlags.TEXT */ +
15460 (` /* ${PatchFlagNames[1 /* PatchFlags.TEXT */]} */` ));
15461 }
15462 children[i] = {
15463 type: 12 /* NodeTypes.TEXT_CALL */,
15464 content: child,
15465 loc: child.loc,
15466 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
15467 };
15468 }
15469 }
15470 };
15471 }
15472};
15473
15474const seen$1 = new WeakSet();
15475const transformOnce = (node, context) => {
15476 if (node.type === 1 /* NodeTypes.ELEMENT */ && findDir(node, 'once', true)) {
15477 if (seen$1.has(node) || context.inVOnce) {
15478 return;
15479 }
15480 seen$1.add(node);
15481 context.inVOnce = true;
15482 context.helper(SET_BLOCK_TRACKING);
15483 return () => {
15484 context.inVOnce = false;
15485 const cur = context.currentNode;
15486 if (cur.codegenNode) {
15487 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
15488 }
15489 };
15490 }
15491};
15492
15493const transformModel$1 = (dir, node, context) => {
15494 const { exp, arg } = dir;
15495 if (!exp) {
15496 context.onError(createCompilerError(41 /* ErrorCodes.X_V_MODEL_NO_EXPRESSION */, dir.loc));
15497 return createTransformProps();
15498 }
15499 const rawExp = exp.loc.source;
15500 const expString = exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ? exp.content : rawExp;
15501 // im SFC <script setup> inline mode, the exp may have been transformed into
15502 // _unref(exp)
15503 const bindingType = context.bindingMetadata[rawExp];
15504 // check props
15505 if (bindingType === "props" /* BindingTypes.PROPS */ ||
15506 bindingType === "props-aliased" /* BindingTypes.PROPS_ALIASED */) {
15507 context.onError(createCompilerError(44 /* ErrorCodes.X_V_MODEL_ON_PROPS */, exp.loc));
15508 return createTransformProps();
15509 }
15510 const maybeRef = !true ;
15511 if (!expString.trim() ||
15512 (!isMemberExpression(expString) && !maybeRef)) {
15513 context.onError(createCompilerError(42 /* ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
15514 return createTransformProps();
15515 }
15516 const propName = arg ? arg : createSimpleExpression('modelValue', true);
15517 const eventName = arg
15518 ? isStaticExp(arg)
15519 ? `onUpdate:${camelize(arg.content)}`
15520 : createCompoundExpression(['"onUpdate:" + ', arg])
15521 : `onUpdate:modelValue`;
15522 let assignmentExp;
15523 const eventArg = context.isTS ? `($event: any)` : `$event`;
15524 {
15525 assignmentExp = createCompoundExpression([
15526 `${eventArg} => ((`,
15527 exp,
15528 `) = $event)`
15529 ]);
15530 }
15531 const props = [
15532 // modelValue: foo
15533 createObjectProperty(propName, dir.exp),
15534 // "onUpdate:modelValue": $event => (foo = $event)
15535 createObjectProperty(eventName, assignmentExp)
15536 ];
15537 // modelModifiers: { foo: true, "bar-baz": true }
15538 if (dir.modifiers.length && node.tagType === 1 /* ElementTypes.COMPONENT */) {
15539 const modifiers = dir.modifiers
15540 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
15541 .join(`, `);
15542 const modifiersKey = arg
15543 ? isStaticExp(arg)
15544 ? `${arg.content}Modifiers`
15545 : createCompoundExpression([arg, ' + "Modifiers"'])
15546 : `modelModifiers`;
15547 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* ConstantTypes.CAN_HOIST */)));
15548 }
15549 return createTransformProps(props);
15550};
15551function createTransformProps(props = []) {
15552 return { props };
15553}
15554
15555const seen = new WeakSet();
15556const transformMemo = (node, context) => {
15557 if (node.type === 1 /* NodeTypes.ELEMENT */) {
15558 const dir = findDir(node, 'memo');
15559 if (!dir || seen.has(node)) {
15560 return;
15561 }
15562 seen.add(node);
15563 return () => {
15564 const codegenNode = node.codegenNode ||
15565 context.currentNode.codegenNode;
15566 if (codegenNode && codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
15567 // non-component sub tree should be turned into a block
15568 if (node.tagType !== 1 /* ElementTypes.COMPONENT */) {
15569 makeBlock(codegenNode, context);
15570 }
15571 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
15572 dir.exp,
15573 createFunctionExpression(undefined, codegenNode),
15574 `_cache`,
15575 String(context.cached++)
15576 ]);
15577 }
15578 };
15579 }
15580};
15581
15582function getBaseTransformPreset(prefixIdentifiers) {
15583 return [
15584 [
15585 transformOnce,
15586 transformIf,
15587 transformMemo,
15588 transformFor,
15589 ...([]),
15590 ...([transformExpression]
15591 ),
15592 transformSlotOutlet,
15593 transformElement,
15594 trackSlotScopes,
15595 transformText
15596 ],
15597 {
15598 on: transformOn$1,
15599 bind: transformBind,
15600 model: transformModel$1
15601 }
15602 ];
15603}
15604// we name it `baseCompile` so that higher order compilers like
15605// @vue/compiler-dom can export `compile` while re-exporting everything else.
15606function baseCompile(template, options = {}) {
15607 const onError = options.onError || defaultOnError;
15608 const isModuleMode = options.mode === 'module';
15609 /* istanbul ignore if */
15610 {
15611 if (options.prefixIdentifiers === true) {
15612 onError(createCompilerError(47 /* ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED */));
15613 }
15614 else if (isModuleMode) {
15615 onError(createCompilerError(48 /* ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED */));
15616 }
15617 }
15618 const prefixIdentifiers = !true ;
15619 if (options.cacheHandlers) {
15620 onError(createCompilerError(49 /* ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED */));
15621 }
15622 if (options.scopeId && !isModuleMode) {
15623 onError(createCompilerError(50 /* ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED */));
15624 }
15625 const ast = isString(template) ? baseParse(template, options) : template;
15626 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
15627 transform(ast, extend({}, options, {
15628 prefixIdentifiers,
15629 nodeTransforms: [
15630 ...nodeTransforms,
15631 ...(options.nodeTransforms || []) // user transforms
15632 ],
15633 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
15634 )
15635 }));
15636 return generate(ast, extend({}, options, {
15637 prefixIdentifiers
15638 }));
15639}
15640
15641const noopDirectiveTransform = () => ({ props: [] });
15642
15643const V_MODEL_RADIO = Symbol(`vModelRadio` );
15644const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
15645const V_MODEL_TEXT = Symbol(`vModelText` );
15646const V_MODEL_SELECT = Symbol(`vModelSelect` );
15647const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
15648const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
15649const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
15650const V_SHOW = Symbol(`vShow` );
15651const TRANSITION = Symbol(`Transition` );
15652const TRANSITION_GROUP = Symbol(`TransitionGroup` );
15653registerRuntimeHelpers({
15654 [V_MODEL_RADIO]: `vModelRadio`,
15655 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
15656 [V_MODEL_TEXT]: `vModelText`,
15657 [V_MODEL_SELECT]: `vModelSelect`,
15658 [V_MODEL_DYNAMIC]: `vModelDynamic`,
15659 [V_ON_WITH_MODIFIERS]: `withModifiers`,
15660 [V_ON_WITH_KEYS]: `withKeys`,
15661 [V_SHOW]: `vShow`,
15662 [TRANSITION]: `Transition`,
15663 [TRANSITION_GROUP]: `TransitionGroup`
15664});
15665
15666/* eslint-disable no-restricted-globals */
15667let decoder;
15668function decodeHtmlBrowser(raw, asAttr = false) {
15669 if (!decoder) {
15670 decoder = document.createElement('div');
15671 }
15672 if (asAttr) {
15673 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
15674 return decoder.children[0].getAttribute('foo');
15675 }
15676 else {
15677 decoder.innerHTML = raw;
15678 return decoder.textContent;
15679 }
15680}
15681
15682const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
15683const parserOptions = {
15684 isVoidTag,
15685 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
15686 isPreTag: tag => tag === 'pre',
15687 decodeEntities: decodeHtmlBrowser ,
15688 isBuiltInComponent: (tag) => {
15689 if (isBuiltInType(tag, `Transition`)) {
15690 return TRANSITION;
15691 }
15692 else if (isBuiltInType(tag, `TransitionGroup`)) {
15693 return TRANSITION_GROUP;
15694 }
15695 },
15696 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
15697 getNamespace(tag, parent) {
15698 let ns = parent ? parent.ns : 0 /* DOMNamespaces.HTML */;
15699 if (parent && ns === 2 /* DOMNamespaces.MATH_ML */) {
15700 if (parent.tag === 'annotation-xml') {
15701 if (tag === 'svg') {
15702 return 1 /* DOMNamespaces.SVG */;
15703 }
15704 if (parent.props.some(a => a.type === 6 /* NodeTypes.ATTRIBUTE */ &&
15705 a.name === 'encoding' &&
15706 a.value != null &&
15707 (a.value.content === 'text/html' ||
15708 a.value.content === 'application/xhtml+xml'))) {
15709 ns = 0 /* DOMNamespaces.HTML */;
15710 }
15711 }
15712 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
15713 tag !== 'mglyph' &&
15714 tag !== 'malignmark') {
15715 ns = 0 /* DOMNamespaces.HTML */;
15716 }
15717 }
15718 else if (parent && ns === 1 /* DOMNamespaces.SVG */) {
15719 if (parent.tag === 'foreignObject' ||
15720 parent.tag === 'desc' ||
15721 parent.tag === 'title') {
15722 ns = 0 /* DOMNamespaces.HTML */;
15723 }
15724 }
15725 if (ns === 0 /* DOMNamespaces.HTML */) {
15726 if (tag === 'svg') {
15727 return 1 /* DOMNamespaces.SVG */;
15728 }
15729 if (tag === 'math') {
15730 return 2 /* DOMNamespaces.MATH_ML */;
15731 }
15732 }
15733 return ns;
15734 },
15735 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
15736 getTextMode({ tag, ns }) {
15737 if (ns === 0 /* DOMNamespaces.HTML */) {
15738 if (tag === 'textarea' || tag === 'title') {
15739 return 1 /* TextModes.RCDATA */;
15740 }
15741 if (isRawTextContainer(tag)) {
15742 return 2 /* TextModes.RAWTEXT */;
15743 }
15744 }
15745 return 0 /* TextModes.DATA */;
15746 }
15747};
15748
15749// Parse inline CSS strings for static style attributes into an object.
15750// This is a NodeTransform since it works on the static `style` attribute and
15751// converts it into a dynamic equivalent:
15752// style="color: red" -> :style='{ "color": "red" }'
15753// It is then processed by `transformElement` and included in the generated
15754// props.
15755const transformStyle = node => {
15756 if (node.type === 1 /* NodeTypes.ELEMENT */) {
15757 node.props.forEach((p, i) => {
15758 if (p.type === 6 /* NodeTypes.ATTRIBUTE */ && p.name === 'style' && p.value) {
15759 // replace p with an expression node
15760 node.props[i] = {
15761 type: 7 /* NodeTypes.DIRECTIVE */,
15762 name: `bind`,
15763 arg: createSimpleExpression(`style`, true, p.loc),
15764 exp: parseInlineCSS(p.value.content, p.loc),
15765 modifiers: [],
15766 loc: p.loc
15767 };
15768 }
15769 });
15770 }
15771};
15772const parseInlineCSS = (cssText, loc) => {
15773 const normalized = parseStringStyle(cssText);
15774 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* ConstantTypes.CAN_STRINGIFY */);
15775};
15776
15777function createDOMCompilerError(code, loc) {
15778 return createCompilerError(code, loc, DOMErrorMessages );
15779}
15780const DOMErrorMessages = {
15781 [51 /* DOMErrorCodes.X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
15782 [52 /* DOMErrorCodes.X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
15783 [53 /* DOMErrorCodes.X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
15784 [54 /* DOMErrorCodes.X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
15785 [55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
15786 [56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
15787 [57 /* DOMErrorCodes.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.`,
15788 [58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
15789 [59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
15790 [60 /* DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
15791 [61 /* DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
15792};
15793
15794const transformVHtml = (dir, node, context) => {
15795 const { exp, loc } = dir;
15796 if (!exp) {
15797 context.onError(createDOMCompilerError(51 /* DOMErrorCodes.X_V_HTML_NO_EXPRESSION */, loc));
15798 }
15799 if (node.children.length) {
15800 context.onError(createDOMCompilerError(52 /* DOMErrorCodes.X_V_HTML_WITH_CHILDREN */, loc));
15801 node.children.length = 0;
15802 }
15803 return {
15804 props: [
15805 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
15806 ]
15807 };
15808};
15809
15810const transformVText = (dir, node, context) => {
15811 const { exp, loc } = dir;
15812 if (!exp) {
15813 context.onError(createDOMCompilerError(53 /* DOMErrorCodes.X_V_TEXT_NO_EXPRESSION */, loc));
15814 }
15815 if (node.children.length) {
15816 context.onError(createDOMCompilerError(54 /* DOMErrorCodes.X_V_TEXT_WITH_CHILDREN */, loc));
15817 node.children.length = 0;
15818 }
15819 return {
15820 props: [
15821 createObjectProperty(createSimpleExpression(`textContent`, true), exp
15822 ? getConstantType(exp, context) > 0
15823 ? exp
15824 : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
15825 : createSimpleExpression('', true))
15826 ]
15827 };
15828};
15829
15830const transformModel = (dir, node, context) => {
15831 const baseResult = transformModel$1(dir, node, context);
15832 // base transform has errors OR component v-model (only need props)
15833 if (!baseResult.props.length || node.tagType === 1 /* ElementTypes.COMPONENT */) {
15834 return baseResult;
15835 }
15836 if (dir.arg) {
15837 context.onError(createDOMCompilerError(56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
15838 }
15839 function checkDuplicatedValue() {
15840 const value = findProp(node, 'value');
15841 if (value) {
15842 context.onError(createDOMCompilerError(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
15843 }
15844 }
15845 const { tag } = node;
15846 const isCustomElement = context.isCustomElement(tag);
15847 if (tag === 'input' ||
15848 tag === 'textarea' ||
15849 tag === 'select' ||
15850 isCustomElement) {
15851 let directiveToUse = V_MODEL_TEXT;
15852 let isInvalidType = false;
15853 if (tag === 'input' || isCustomElement) {
15854 const type = findProp(node, `type`);
15855 if (type) {
15856 if (type.type === 7 /* NodeTypes.DIRECTIVE */) {
15857 // :type="foo"
15858 directiveToUse = V_MODEL_DYNAMIC;
15859 }
15860 else if (type.value) {
15861 switch (type.value.content) {
15862 case 'radio':
15863 directiveToUse = V_MODEL_RADIO;
15864 break;
15865 case 'checkbox':
15866 directiveToUse = V_MODEL_CHECKBOX;
15867 break;
15868 case 'file':
15869 isInvalidType = true;
15870 context.onError(createDOMCompilerError(57 /* DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
15871 break;
15872 default:
15873 // text type
15874 checkDuplicatedValue();
15875 break;
15876 }
15877 }
15878 }
15879 else if (hasDynamicKeyVBind(node)) {
15880 // element has bindings with dynamic keys, which can possibly contain
15881 // "type".
15882 directiveToUse = V_MODEL_DYNAMIC;
15883 }
15884 else {
15885 // text type
15886 checkDuplicatedValue();
15887 }
15888 }
15889 else if (tag === 'select') {
15890 directiveToUse = V_MODEL_SELECT;
15891 }
15892 else {
15893 // textarea
15894 checkDuplicatedValue();
15895 }
15896 // inject runtime directive
15897 // by returning the helper symbol via needRuntime
15898 // the import will replaced a resolveDirective call.
15899 if (!isInvalidType) {
15900 baseResult.needRuntime = context.helper(directiveToUse);
15901 }
15902 }
15903 else {
15904 context.onError(createDOMCompilerError(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
15905 }
15906 // native vmodel doesn't need the `modelValue` props since they are also
15907 // passed to the runtime as `binding.value`. removing it reduces code size.
15908 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
15909 p.key.content === 'modelValue'));
15910 return baseResult;
15911};
15912
15913const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
15914const isNonKeyModifier = /*#__PURE__*/ makeMap(
15915// event propagation management
15916`stop,prevent,self,` +
15917 // system modifiers + exact
15918 `ctrl,shift,alt,meta,exact,` +
15919 // mouse
15920 `middle`);
15921// left & right could be mouse or key modifiers based on event type
15922const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
15923const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
15924const resolveModifiers = (key, modifiers, context, loc) => {
15925 const keyModifiers = [];
15926 const nonKeyModifiers = [];
15927 const eventOptionModifiers = [];
15928 for (let i = 0; i < modifiers.length; i++) {
15929 const modifier = modifiers[i];
15930 if (isEventOptionModifier(modifier)) {
15931 // eventOptionModifiers: modifiers for addEventListener() options,
15932 // e.g. .passive & .capture
15933 eventOptionModifiers.push(modifier);
15934 }
15935 else {
15936 // runtimeModifiers: modifiers that needs runtime guards
15937 if (maybeKeyModifier(modifier)) {
15938 if (isStaticExp(key)) {
15939 if (isKeyboardEvent(key.content)) {
15940 keyModifiers.push(modifier);
15941 }
15942 else {
15943 nonKeyModifiers.push(modifier);
15944 }
15945 }
15946 else {
15947 keyModifiers.push(modifier);
15948 nonKeyModifiers.push(modifier);
15949 }
15950 }
15951 else {
15952 if (isNonKeyModifier(modifier)) {
15953 nonKeyModifiers.push(modifier);
15954 }
15955 else {
15956 keyModifiers.push(modifier);
15957 }
15958 }
15959 }
15960 }
15961 return {
15962 keyModifiers,
15963 nonKeyModifiers,
15964 eventOptionModifiers
15965 };
15966};
15967const transformClick = (key, event) => {
15968 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
15969 return isStaticClick
15970 ? createSimpleExpression(event, true)
15971 : key.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */
15972 ? createCompoundExpression([
15973 `(`,
15974 key,
15975 `) === "onClick" ? "${event}" : (`,
15976 key,
15977 `)`
15978 ])
15979 : key;
15980};
15981const transformOn = (dir, node, context) => {
15982 return transformOn$1(dir, node, context, baseResult => {
15983 const { modifiers } = dir;
15984 if (!modifiers.length)
15985 return baseResult;
15986 let { key, value: handlerExp } = baseResult.props[0];
15987 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
15988 // normalize click.right and click.middle since they don't actually fire
15989 if (nonKeyModifiers.includes('right')) {
15990 key = transformClick(key, `onContextmenu`);
15991 }
15992 if (nonKeyModifiers.includes('middle')) {
15993 key = transformClick(key, `onMouseup`);
15994 }
15995 if (nonKeyModifiers.length) {
15996 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
15997 handlerExp,
15998 JSON.stringify(nonKeyModifiers)
15999 ]);
16000 }
16001 if (keyModifiers.length &&
16002 // if event name is dynamic, always wrap with keys guard
16003 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
16004 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
16005 handlerExp,
16006 JSON.stringify(keyModifiers)
16007 ]);
16008 }
16009 if (eventOptionModifiers.length) {
16010 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
16011 key = isStaticExp(key)
16012 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
16013 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
16014 }
16015 return {
16016 props: [createObjectProperty(key, handlerExp)]
16017 };
16018 });
16019};
16020
16021const transformShow = (dir, node, context) => {
16022 const { exp, loc } = dir;
16023 if (!exp) {
16024 context.onError(createDOMCompilerError(59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */, loc));
16025 }
16026 return {
16027 props: [],
16028 needRuntime: context.helper(V_SHOW)
16029 };
16030};
16031
16032const transformTransition = (node, context) => {
16033 if (node.type === 1 /* NodeTypes.ELEMENT */ &&
16034 node.tagType === 1 /* ElementTypes.COMPONENT */) {
16035 const component = context.isBuiltInComponent(node.tag);
16036 if (component === TRANSITION) {
16037 return () => {
16038 if (!node.children.length) {
16039 return;
16040 }
16041 // warn multiple transition children
16042 if (hasMultipleChildren(node)) {
16043 context.onError(createDOMCompilerError(60 /* DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN */, {
16044 start: node.children[0].loc.start,
16045 end: node.children[node.children.length - 1].loc.end,
16046 source: ''
16047 }));
16048 }
16049 // check if it's s single child w/ v-show
16050 // if yes, inject "persisted: true" to the transition props
16051 const child = node.children[0];
16052 if (child.type === 1 /* NodeTypes.ELEMENT */) {
16053 for (const p of child.props) {
16054 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'show') {
16055 node.props.push({
16056 type: 6 /* NodeTypes.ATTRIBUTE */,
16057 name: 'persisted',
16058 value: undefined,
16059 loc: node.loc
16060 });
16061 }
16062 }
16063 }
16064 };
16065 }
16066 }
16067};
16068function hasMultipleChildren(node) {
16069 // #1352 filter out potential comment nodes.
16070 const children = (node.children = node.children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */ &&
16071 !(c.type === 2 /* NodeTypes.TEXT */ && !c.content.trim())));
16072 const child = children[0];
16073 return (children.length !== 1 ||
16074 child.type === 11 /* NodeTypes.FOR */ ||
16075 (child.type === 9 /* NodeTypes.IF */ && child.branches.some(hasMultipleChildren)));
16076}
16077
16078const ignoreSideEffectTags = (node, context) => {
16079 if (node.type === 1 /* NodeTypes.ELEMENT */ &&
16080 node.tagType === 0 /* ElementTypes.ELEMENT */ &&
16081 (node.tag === 'script' || node.tag === 'style')) {
16082 context.onError(createDOMCompilerError(61 /* DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
16083 context.removeNode();
16084 }
16085};
16086
16087const DOMNodeTransforms = [
16088 transformStyle,
16089 ...([transformTransition] )
16090];
16091const DOMDirectiveTransforms = {
16092 cloak: noopDirectiveTransform,
16093 html: transformVHtml,
16094 text: transformVText,
16095 model: transformModel,
16096 on: transformOn,
16097 show: transformShow
16098};
16099function compile(template, options = {}) {
16100 return baseCompile(template, extend({}, parserOptions, options, {
16101 nodeTransforms: [
16102 // ignore <script> and <tag>
16103 // this is not put inside DOMNodeTransforms because that list is used
16104 // by compiler-ssr to generate vnode fallback branches
16105 ignoreSideEffectTags,
16106 ...DOMNodeTransforms,
16107 ...(options.nodeTransforms || [])
16108 ],
16109 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
16110 transformHoist: null
16111 }));
16112}
16113
16114// This entry is the "full-build" that includes both the runtime
16115{
16116 initDev();
16117}
16118const compileCache = Object.create(null);
16119function compileToFunction(template, options) {
16120 if (!isString(template)) {
16121 if (template.nodeType) {
16122 template = template.innerHTML;
16123 }
16124 else {
16125 warn(`invalid template option: `, template);
16126 return NOOP;
16127 }
16128 }
16129 const key = template;
16130 const cached = compileCache[key];
16131 if (cached) {
16132 return cached;
16133 }
16134 if (template[0] === '#') {
16135 const el = document.querySelector(template);
16136 if (!el) {
16137 warn(`Template element not found or is empty: ${template}`);
16138 }
16139 // __UNSAFE__
16140 // Reason: potential execution of JS expressions in in-DOM template.
16141 // The user must make sure the in-DOM template is trusted. If it's rendered
16142 // by the server, the template should not contain any user data.
16143 template = el ? el.innerHTML : ``;
16144 }
16145 const opts = extend({
16146 hoistStatic: true,
16147 onError: onError ,
16148 onWarn: e => onError(e, true)
16149 }, options);
16150 if (!opts.isCustomElement && typeof customElements !== 'undefined') {
16151 opts.isCustomElement = tag => !!customElements.get(tag);
16152 }
16153 const { code } = compile(template, opts);
16154 function onError(err, asWarning = false) {
16155 const message = asWarning
16156 ? err.message
16157 : `Template compilation error: ${err.message}`;
16158 const codeFrame = err.loc &&
16159 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
16160 warn(codeFrame ? `${message}\n${codeFrame}` : message);
16161 }
16162 // The wildcard import results in a huge object with every export
16163 // with keys that cannot be mangled, and can be quite heavy size-wise.
16164 // In the global build we know `Vue` is available globally so we can avoid
16165 // the wildcard object.
16166 const render = (new Function('Vue', code)(runtimeDom));
16167 render._rc = true;
16168 return (compileCache[key] = render);
16169}
16170registerRuntimeCompiler(compileToFunction);
16171
16172export { BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, assertNumber, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compileToFunction as compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createBaseVNode as createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isShallow, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId };