UNPKG

643 kBJavaScriptView Raw
1var Vue = (function (exports) {
2 'use strict';
3
4 /**
5 * Make a map and return a function for checking if a key
6 * is in that map.
7 * IMPORTANT: all calls of this function must be prefixed with
8 * \/\*#\_\_PURE\_\_\*\/
9 * So that rollup can tree-shake them if necessary.
10 */
11 function makeMap(str, expectsLowerCase) {
12 const map = Object.create(null);
13 const list = str.split(',');
14 for (let i = 0; i < list.length; i++) {
15 map[list[i]] = true;
16 }
17 return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
18 }
19
20 /**
21 * dev only flag -> name mapping
22 */
23 const PatchFlagNames = {
24 [1 /* PatchFlags.TEXT */]: `TEXT`,
25 [2 /* PatchFlags.CLASS */]: `CLASS`,
26 [4 /* PatchFlags.STYLE */]: `STYLE`,
27 [8 /* PatchFlags.PROPS */]: `PROPS`,
28 [16 /* PatchFlags.FULL_PROPS */]: `FULL_PROPS`,
29 [32 /* PatchFlags.HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
30 [64 /* PatchFlags.STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
31 [128 /* PatchFlags.KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
32 [256 /* PatchFlags.UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
33 [512 /* PatchFlags.NEED_PATCH */]: `NEED_PATCH`,
34 [1024 /* PatchFlags.DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
35 [2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
36 [-1 /* PatchFlags.HOISTED */]: `HOISTED`,
37 [-2 /* PatchFlags.BAIL */]: `BAIL`
38 };
39
40 /**
41 * Dev only
42 */
43 const slotFlagsText = {
44 [1 /* SlotFlags.STABLE */]: 'STABLE',
45 [2 /* SlotFlags.DYNAMIC */]: 'DYNAMIC',
46 [3 /* SlotFlags.FORWARDED */]: 'FORWARDED'
47 };
48
49 const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
50 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
51 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
52 const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
53
54 const range = 2;
55 function generateCodeFrame(source, start = 0, end = source.length) {
56 // Split the content into individual lines but capture the newline sequence
57 // that separated each line. This is important because the actual sequence is
58 // needed to properly take into account the full line length for offset
59 // comparison
60 let lines = source.split(/(\r?\n)/);
61 // Separate the lines and newline sequences into separate arrays for easier referencing
62 const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
63 lines = lines.filter((_, idx) => idx % 2 === 0);
64 let count = 0;
65 const res = [];
66 for (let i = 0; i < lines.length; i++) {
67 count +=
68 lines[i].length +
69 ((newlineSequences[i] && newlineSequences[i].length) || 0);
70 if (count >= start) {
71 for (let j = i - range; j <= i + range || end > count; j++) {
72 if (j < 0 || j >= lines.length)
73 continue;
74 const line = j + 1;
75 res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
76 const lineLength = lines[j].length;
77 const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
78 if (j === i) {
79 // push underline
80 const pad = start - (count - (lineLength + newLineSeqLength));
81 const length = Math.max(1, end > count ? lineLength - pad : end - start);
82 res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
83 }
84 else if (j > i) {
85 if (end > count) {
86 const length = Math.max(Math.min(end - count, lineLength), 1);
87 res.push(` | ` + '^'.repeat(length));
88 }
89 count += lineLength + newLineSeqLength;
90 }
91 }
92 break;
93 }
94 }
95 return res.join('\n');
96 }
97
98 function normalizeStyle(value) {
99 if (isArray(value)) {
100 const res = {};
101 for (let i = 0; i < value.length; i++) {
102 const item = value[i];
103 const normalized = isString(item)
104 ? parseStringStyle(item)
105 : normalizeStyle(item);
106 if (normalized) {
107 for (const key in normalized) {
108 res[key] = normalized[key];
109 }
110 }
111 }
112 return res;
113 }
114 else if (isString(value)) {
115 return value;
116 }
117 else if (isObject(value)) {
118 return value;
119 }
120 }
121 const listDelimiterRE = /;(?![^(]*\))/g;
122 const propertyDelimiterRE = /:([^]+)/;
123 const styleCommentRE = /\/\*.*?\*\//gs;
124 function parseStringStyle(cssText) {
125 const ret = {};
126 cssText
127 .replace(styleCommentRE, '')
128 .split(listDelimiterRE)
129 .forEach(item => {
130 if (item) {
131 const tmp = item.split(propertyDelimiterRE);
132 tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
133 }
134 });
135 return ret;
136 }
137 function normalizeClass(value) {
138 let res = '';
139 if (isString(value)) {
140 res = value;
141 }
142 else if (isArray(value)) {
143 for (let i = 0; i < value.length; i++) {
144 const normalized = normalizeClass(value[i]);
145 if (normalized) {
146 res += normalized + ' ';
147 }
148 }
149 }
150 else if (isObject(value)) {
151 for (const name in value) {
152 if (value[name]) {
153 res += name + ' ';
154 }
155 }
156 }
157 return res.trim();
158 }
159 function normalizeProps(props) {
160 if (!props)
161 return null;
162 let { class: klass, style } = props;
163 if (klass && !isString(klass)) {
164 props.class = normalizeClass(klass);
165 }
166 if (style) {
167 props.style = normalizeStyle(style);
168 }
169 return props;
170 }
171
172 // These tag configs are shared between compiler-dom and runtime-dom, so they
173 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
174 const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
175 'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
176 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
177 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
178 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
179 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
180 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
181 'option,output,progress,select,textarea,details,dialog,menu,' +
182 'summary,template,blockquote,iframe,tfoot';
183 // https://developer.mozilla.org/en-US/docs/Web/SVG/Element
184 const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
185 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
186 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
187 'feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
188 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
189 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
190 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
191 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
192 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
193 'text,textPath,title,tspan,unknown,use,view';
194 const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
195 /**
196 * Compiler only.
197 * Do NOT use in runtime code paths unless behind `true` flag.
198 */
199 const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
200 /**
201 * Compiler only.
202 * Do NOT use in runtime code paths unless behind `true` flag.
203 */
204 const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
205 /**
206 * Compiler only.
207 * Do NOT use in runtime code paths unless behind `true` flag.
208 */
209 const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
210
211 /**
212 * On the client we only need to offer special cases for boolean attributes that
213 * have different names from their corresponding dom properties:
214 * - itemscope -> N/A
215 * - allowfullscreen -> allowFullscreen
216 * - formnovalidate -> formNoValidate
217 * - ismap -> isMap
218 * - nomodule -> noModule
219 * - novalidate -> noValidate
220 * - readonly -> readOnly
221 */
222 const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
223 const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
224 /**
225 * Boolean attributes should be included if the value is truthy or ''.
226 * e.g. `<select multiple>` compiles to `{ multiple: '' }`
227 */
228 function includeBooleanAttr(value) {
229 return !!value || value === '';
230 }
231
232 function looseCompareArrays(a, b) {
233 if (a.length !== b.length)
234 return false;
235 let equal = true;
236 for (let i = 0; equal && i < a.length; i++) {
237 equal = looseEqual(a[i], b[i]);
238 }
239 return equal;
240 }
241 function looseEqual(a, b) {
242 if (a === b)
243 return true;
244 let aValidType = isDate(a);
245 let bValidType = isDate(b);
246 if (aValidType || bValidType) {
247 return aValidType && bValidType ? a.getTime() === b.getTime() : false;
248 }
249 aValidType = isSymbol(a);
250 bValidType = isSymbol(b);
251 if (aValidType || bValidType) {
252 return a === b;
253 }
254 aValidType = isArray(a);
255 bValidType = isArray(b);
256 if (aValidType || bValidType) {
257 return aValidType && bValidType ? looseCompareArrays(a, b) : false;
258 }
259 aValidType = isObject(a);
260 bValidType = isObject(b);
261 if (aValidType || bValidType) {
262 /* istanbul ignore if: this if will probably never be called */
263 if (!aValidType || !bValidType) {
264 return false;
265 }
266 const aKeysCount = Object.keys(a).length;
267 const bKeysCount = Object.keys(b).length;
268 if (aKeysCount !== bKeysCount) {
269 return false;
270 }
271 for (const key in a) {
272 const aHasKey = a.hasOwnProperty(key);
273 const bHasKey = b.hasOwnProperty(key);
274 if ((aHasKey && !bHasKey) ||
275 (!aHasKey && bHasKey) ||
276 !looseEqual(a[key], b[key])) {
277 return false;
278 }
279 }
280 }
281 return String(a) === String(b);
282 }
283 function looseIndexOf(arr, val) {
284 return arr.findIndex(item => looseEqual(item, val));
285 }
286
287 /**
288 * For converting {{ interpolation }} values to displayed strings.
289 * @private
290 */
291 const toDisplayString = (val) => {
292 return isString(val)
293 ? val
294 : val == null
295 ? ''
296 : isArray(val) ||
297 (isObject(val) &&
298 (val.toString === objectToString || !isFunction(val.toString)))
299 ? JSON.stringify(val, replacer, 2)
300 : String(val);
301 };
302 const replacer = (_key, val) => {
303 // can't use isRef here since @vue/shared has no deps
304 if (val && val.__v_isRef) {
305 return replacer(_key, val.value);
306 }
307 else if (isMap(val)) {
308 return {
309 [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
310 entries[`${key} =>`] = val;
311 return entries;
312 }, {})
313 };
314 }
315 else if (isSet(val)) {
316 return {
317 [`Set(${val.size})`]: [...val.values()]
318 };
319 }
320 else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
321 return String(val);
322 }
323 return val;
324 };
325
326 const EMPTY_OBJ = Object.freeze({})
327 ;
328 const EMPTY_ARR = Object.freeze([]) ;
329 const NOOP = () => { };
330 /**
331 * Always return false.
332 */
333 const NO = () => false;
334 const onRE = /^on[^a-z]/;
335 const isOn = (key) => onRE.test(key);
336 const isModelListener = (key) => key.startsWith('onUpdate:');
337 const extend = Object.assign;
338 const remove = (arr, el) => {
339 const i = arr.indexOf(el);
340 if (i > -1) {
341 arr.splice(i, 1);
342 }
343 };
344 const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
345 const hasOwn = (val, key) => hasOwnProperty$1.call(val, key);
346 const isArray = Array.isArray;
347 const isMap = (val) => toTypeString(val) === '[object Map]';
348 const isSet = (val) => toTypeString(val) === '[object Set]';
349 const isDate = (val) => toTypeString(val) === '[object Date]';
350 const isRegExp = (val) => toTypeString(val) === '[object RegExp]';
351 const isFunction = (val) => typeof val === 'function';
352 const isString = (val) => typeof val === 'string';
353 const isSymbol = (val) => typeof val === 'symbol';
354 const isObject = (val) => val !== null && typeof val === 'object';
355 const isPromise = (val) => {
356 return isObject(val) && isFunction(val.then) && isFunction(val.catch);
357 };
358 const objectToString = Object.prototype.toString;
359 const toTypeString = (value) => objectToString.call(value);
360 const toRawType = (value) => {
361 // extract "RawType" from strings like "[object RawType]"
362 return toTypeString(value).slice(8, -1);
363 };
364 const isPlainObject = (val) => toTypeString(val) === '[object Object]';
365 const isIntegerKey = (key) => isString(key) &&
366 key !== 'NaN' &&
367 key[0] !== '-' &&
368 '' + parseInt(key, 10) === key;
369 const isReservedProp = /*#__PURE__*/ makeMap(
370 // the leading comma is intentional so empty string "" is also included
371 ',key,ref,ref_for,ref_key,' +
372 'onVnodeBeforeMount,onVnodeMounted,' +
373 'onVnodeBeforeUpdate,onVnodeUpdated,' +
374 'onVnodeBeforeUnmount,onVnodeUnmounted');
375 const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
376 const cacheStringFunction = (fn) => {
377 const cache = Object.create(null);
378 return ((str) => {
379 const hit = cache[str];
380 return hit || (cache[str] = fn(str));
381 });
382 };
383 const camelizeRE = /-(\w)/g;
384 /**
385 * @private
386 */
387 const camelize = cacheStringFunction((str) => {
388 return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
389 });
390 const hyphenateRE = /\B([A-Z])/g;
391 /**
392 * @private
393 */
394 const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
395 /**
396 * @private
397 */
398 const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
399 /**
400 * @private
401 */
402 const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
403 // compare whether a value has changed, accounting for NaN.
404 const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
405 const invokeArrayFns = (fns, arg) => {
406 for (let i = 0; i < fns.length; i++) {
407 fns[i](arg);
408 }
409 };
410 const def = (obj, key, value) => {
411 Object.defineProperty(obj, key, {
412 configurable: true,
413 enumerable: false,
414 value
415 });
416 };
417 /**
418 * "123-foo" will be parsed to 123
419 * This is used for the .number modifier in v-model
420 */
421 const looseToNumber = (val) => {
422 const n = parseFloat(val);
423 return isNaN(n) ? val : n;
424 };
425 /**
426 * Only conerces number-like strings
427 * "123-foo" will be returned as-is
428 */
429 const toNumber = (val) => {
430 const n = isString(val) ? Number(val) : NaN;
431 return isNaN(n) ? val : n;
432 };
433 let _globalThis;
434 const getGlobalThis = () => {
435 return (_globalThis ||
436 (_globalThis =
437 typeof globalThis !== 'undefined'
438 ? globalThis
439 : typeof self !== 'undefined'
440 ? self
441 : typeof window !== 'undefined'
442 ? window
443 : typeof global !== 'undefined'
444 ? global
445 : {}));
446 };
447
448 function warn$1(msg, ...args) {
449 console.warn(`[Vue warn] ${msg}`, ...args);
450 }
451
452 let activeEffectScope;
453 class EffectScope {
454 constructor(detached = false) {
455 this.detached = detached;
456 /**
457 * @internal
458 */
459 this._active = true;
460 /**
461 * @internal
462 */
463 this.effects = [];
464 /**
465 * @internal
466 */
467 this.cleanups = [];
468 this.parent = activeEffectScope;
469 if (!detached && activeEffectScope) {
470 this.index =
471 (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
472 }
473 }
474 get active() {
475 return this._active;
476 }
477 run(fn) {
478 if (this._active) {
479 const currentEffectScope = activeEffectScope;
480 try {
481 activeEffectScope = this;
482 return fn();
483 }
484 finally {
485 activeEffectScope = currentEffectScope;
486 }
487 }
488 else {
489 warn$1(`cannot run an inactive effect scope.`);
490 }
491 }
492 /**
493 * This should only be called on non-detached scopes
494 * @internal
495 */
496 on() {
497 activeEffectScope = this;
498 }
499 /**
500 * This should only be called on non-detached scopes
501 * @internal
502 */
503 off() {
504 activeEffectScope = this.parent;
505 }
506 stop(fromParent) {
507 if (this._active) {
508 let i, l;
509 for (i = 0, l = this.effects.length; i < l; i++) {
510 this.effects[i].stop();
511 }
512 for (i = 0, l = this.cleanups.length; i < l; i++) {
513 this.cleanups[i]();
514 }
515 if (this.scopes) {
516 for (i = 0, l = this.scopes.length; i < l; i++) {
517 this.scopes[i].stop(true);
518 }
519 }
520 // nested scope, dereference from parent to avoid memory leaks
521 if (!this.detached && this.parent && !fromParent) {
522 // optimized O(1) removal
523 const last = this.parent.scopes.pop();
524 if (last && last !== this) {
525 this.parent.scopes[this.index] = last;
526 last.index = this.index;
527 }
528 }
529 this.parent = undefined;
530 this._active = false;
531 }
532 }
533 }
534 function effectScope(detached) {
535 return new EffectScope(detached);
536 }
537 function recordEffectScope(effect, scope = activeEffectScope) {
538 if (scope && scope.active) {
539 scope.effects.push(effect);
540 }
541 }
542 function getCurrentScope() {
543 return activeEffectScope;
544 }
545 function onScopeDispose(fn) {
546 if (activeEffectScope) {
547 activeEffectScope.cleanups.push(fn);
548 }
549 else {
550 warn$1(`onScopeDispose() is called when there is no active effect scope` +
551 ` to be associated with.`);
552 }
553 }
554
555 const createDep = (effects) => {
556 const dep = new Set(effects);
557 dep.w = 0;
558 dep.n = 0;
559 return dep;
560 };
561 const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
562 const newTracked = (dep) => (dep.n & trackOpBit) > 0;
563 const initDepMarkers = ({ deps }) => {
564 if (deps.length) {
565 for (let i = 0; i < deps.length; i++) {
566 deps[i].w |= trackOpBit; // set was tracked
567 }
568 }
569 };
570 const finalizeDepMarkers = (effect) => {
571 const { deps } = effect;
572 if (deps.length) {
573 let ptr = 0;
574 for (let i = 0; i < deps.length; i++) {
575 const dep = deps[i];
576 if (wasTracked(dep) && !newTracked(dep)) {
577 dep.delete(effect);
578 }
579 else {
580 deps[ptr++] = dep;
581 }
582 // clear bits
583 dep.w &= ~trackOpBit;
584 dep.n &= ~trackOpBit;
585 }
586 deps.length = ptr;
587 }
588 };
589
590 const targetMap = new WeakMap();
591 // The number of effects currently being tracked recursively.
592 let effectTrackDepth = 0;
593 let trackOpBit = 1;
594 /**
595 * The bitwise track markers support at most 30 levels of recursion.
596 * This value is chosen to enable modern JS engines to use a SMI on all platforms.
597 * When recursion depth is greater, fall back to using a full cleanup.
598 */
599 const maxMarkerBits = 30;
600 let activeEffect;
601 const ITERATE_KEY = Symbol('iterate' );
602 const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
603 class ReactiveEffect {
604 constructor(fn, scheduler = null, scope) {
605 this.fn = fn;
606 this.scheduler = scheduler;
607 this.active = true;
608 this.deps = [];
609 this.parent = undefined;
610 recordEffectScope(this, scope);
611 }
612 run() {
613 if (!this.active) {
614 return this.fn();
615 }
616 let parent = activeEffect;
617 let lastShouldTrack = shouldTrack;
618 while (parent) {
619 if (parent === this) {
620 return;
621 }
622 parent = parent.parent;
623 }
624 try {
625 this.parent = activeEffect;
626 activeEffect = this;
627 shouldTrack = true;
628 trackOpBit = 1 << ++effectTrackDepth;
629 if (effectTrackDepth <= maxMarkerBits) {
630 initDepMarkers(this);
631 }
632 else {
633 cleanupEffect(this);
634 }
635 return this.fn();
636 }
637 finally {
638 if (effectTrackDepth <= maxMarkerBits) {
639 finalizeDepMarkers(this);
640 }
641 trackOpBit = 1 << --effectTrackDepth;
642 activeEffect = this.parent;
643 shouldTrack = lastShouldTrack;
644 this.parent = undefined;
645 if (this.deferStop) {
646 this.stop();
647 }
648 }
649 }
650 stop() {
651 // stopped while running itself - defer the cleanup
652 if (activeEffect === this) {
653 this.deferStop = true;
654 }
655 else if (this.active) {
656 cleanupEffect(this);
657 if (this.onStop) {
658 this.onStop();
659 }
660 this.active = false;
661 }
662 }
663 }
664 function cleanupEffect(effect) {
665 const { deps } = effect;
666 if (deps.length) {
667 for (let i = 0; i < deps.length; i++) {
668 deps[i].delete(effect);
669 }
670 deps.length = 0;
671 }
672 }
673 function effect(fn, options) {
674 if (fn.effect) {
675 fn = fn.effect.fn;
676 }
677 const _effect = new ReactiveEffect(fn);
678 if (options) {
679 extend(_effect, options);
680 if (options.scope)
681 recordEffectScope(_effect, options.scope);
682 }
683 if (!options || !options.lazy) {
684 _effect.run();
685 }
686 const runner = _effect.run.bind(_effect);
687 runner.effect = _effect;
688 return runner;
689 }
690 function stop(runner) {
691 runner.effect.stop();
692 }
693 let shouldTrack = true;
694 const trackStack = [];
695 function pauseTracking() {
696 trackStack.push(shouldTrack);
697 shouldTrack = false;
698 }
699 function resetTracking() {
700 const last = trackStack.pop();
701 shouldTrack = last === undefined ? true : last;
702 }
703 function track(target, type, key) {
704 if (shouldTrack && activeEffect) {
705 let depsMap = targetMap.get(target);
706 if (!depsMap) {
707 targetMap.set(target, (depsMap = new Map()));
708 }
709 let dep = depsMap.get(key);
710 if (!dep) {
711 depsMap.set(key, (dep = createDep()));
712 }
713 const eventInfo = { effect: activeEffect, target, type, key }
714 ;
715 trackEffects(dep, eventInfo);
716 }
717 }
718 function trackEffects(dep, debuggerEventExtraInfo) {
719 let shouldTrack = false;
720 if (effectTrackDepth <= maxMarkerBits) {
721 if (!newTracked(dep)) {
722 dep.n |= trackOpBit; // set newly tracked
723 shouldTrack = !wasTracked(dep);
724 }
725 }
726 else {
727 // Full cleanup mode.
728 shouldTrack = !dep.has(activeEffect);
729 }
730 if (shouldTrack) {
731 dep.add(activeEffect);
732 activeEffect.deps.push(dep);
733 if (activeEffect.onTrack) {
734 activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo));
735 }
736 }
737 }
738 function trigger(target, type, key, newValue, oldValue, oldTarget) {
739 const depsMap = targetMap.get(target);
740 if (!depsMap) {
741 // never been tracked
742 return;
743 }
744 let deps = [];
745 if (type === "clear" /* TriggerOpTypes.CLEAR */) {
746 // collection being cleared
747 // trigger all effects for target
748 deps = [...depsMap.values()];
749 }
750 else if (key === 'length' && isArray(target)) {
751 const newLength = Number(newValue);
752 depsMap.forEach((dep, key) => {
753 if (key === 'length' || key >= newLength) {
754 deps.push(dep);
755 }
756 });
757 }
758 else {
759 // schedule runs for SET | ADD | DELETE
760 if (key !== void 0) {
761 deps.push(depsMap.get(key));
762 }
763 // also run for iteration key on ADD | DELETE | Map.SET
764 switch (type) {
765 case "add" /* TriggerOpTypes.ADD */:
766 if (!isArray(target)) {
767 deps.push(depsMap.get(ITERATE_KEY));
768 if (isMap(target)) {
769 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
770 }
771 }
772 else if (isIntegerKey(key)) {
773 // new index added to array -> length changes
774 deps.push(depsMap.get('length'));
775 }
776 break;
777 case "delete" /* TriggerOpTypes.DELETE */:
778 if (!isArray(target)) {
779 deps.push(depsMap.get(ITERATE_KEY));
780 if (isMap(target)) {
781 deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
782 }
783 }
784 break;
785 case "set" /* TriggerOpTypes.SET */:
786 if (isMap(target)) {
787 deps.push(depsMap.get(ITERATE_KEY));
788 }
789 break;
790 }
791 }
792 const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
793 ;
794 if (deps.length === 1) {
795 if (deps[0]) {
796 {
797 triggerEffects(deps[0], eventInfo);
798 }
799 }
800 }
801 else {
802 const effects = [];
803 for (const dep of deps) {
804 if (dep) {
805 effects.push(...dep);
806 }
807 }
808 {
809 triggerEffects(createDep(effects), eventInfo);
810 }
811 }
812 }
813 function triggerEffects(dep, debuggerEventExtraInfo) {
814 // spread into array for stabilization
815 const effects = isArray(dep) ? dep : [...dep];
816 for (const effect of effects) {
817 if (effect.computed) {
818 triggerEffect(effect, debuggerEventExtraInfo);
819 }
820 }
821 for (const effect of effects) {
822 if (!effect.computed) {
823 triggerEffect(effect, debuggerEventExtraInfo);
824 }
825 }
826 }
827 function triggerEffect(effect, debuggerEventExtraInfo) {
828 if (effect !== activeEffect || effect.allowRecurse) {
829 if (effect.onTrigger) {
830 effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
831 }
832 if (effect.scheduler) {
833 effect.scheduler();
834 }
835 else {
836 effect.run();
837 }
838 }
839 }
840 function getDepFromReactive(object, key) {
841 var _a;
842 return (_a = targetMap.get(object)) === null || _a === void 0 ? void 0 : _a.get(key);
843 }
844
845 const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
846 const builtInSymbols = new Set(
847 /*#__PURE__*/
848 Object.getOwnPropertyNames(Symbol)
849 // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
850 // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
851 // function
852 .filter(key => key !== 'arguments' && key !== 'caller')
853 .map(key => Symbol[key])
854 .filter(isSymbol));
855 const get$1 = /*#__PURE__*/ createGetter();
856 const shallowGet = /*#__PURE__*/ createGetter(false, true);
857 const readonlyGet = /*#__PURE__*/ createGetter(true);
858 const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
859 const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
860 function createArrayInstrumentations() {
861 const instrumentations = {};
862 ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
863 instrumentations[key] = function (...args) {
864 const arr = toRaw(this);
865 for (let i = 0, l = this.length; i < l; i++) {
866 track(arr, "get" /* TrackOpTypes.GET */, i + '');
867 }
868 // we run the method using the original args first (which may be reactive)
869 const res = arr[key](...args);
870 if (res === -1 || res === false) {
871 // if that didn't work, run it again using raw values.
872 return arr[key](...args.map(toRaw));
873 }
874 else {
875 return res;
876 }
877 };
878 });
879 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
880 instrumentations[key] = function (...args) {
881 pauseTracking();
882 const res = toRaw(this)[key].apply(this, args);
883 resetTracking();
884 return res;
885 };
886 });
887 return instrumentations;
888 }
889 function hasOwnProperty(key) {
890 const obj = toRaw(this);
891 track(obj, "has" /* TrackOpTypes.HAS */, key);
892 return obj.hasOwnProperty(key);
893 }
894 function createGetter(isReadonly = false, shallow = false) {
895 return function get(target, key, receiver) {
896 if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) {
897 return !isReadonly;
898 }
899 else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) {
900 return isReadonly;
901 }
902 else if (key === "__v_isShallow" /* ReactiveFlags.IS_SHALLOW */) {
903 return shallow;
904 }
905 else if (key === "__v_raw" /* ReactiveFlags.RAW */ &&
906 receiver ===
907 (isReadonly
908 ? shallow
909 ? shallowReadonlyMap
910 : readonlyMap
911 : shallow
912 ? shallowReactiveMap
913 : reactiveMap).get(target)) {
914 return target;
915 }
916 const targetIsArray = isArray(target);
917 if (!isReadonly) {
918 if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
919 return Reflect.get(arrayInstrumentations, key, receiver);
920 }
921 if (key === 'hasOwnProperty') {
922 return hasOwnProperty;
923 }
924 }
925 const res = Reflect.get(target, key, receiver);
926 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
927 return res;
928 }
929 if (!isReadonly) {
930 track(target, "get" /* TrackOpTypes.GET */, key);
931 }
932 if (shallow) {
933 return res;
934 }
935 if (isRef(res)) {
936 // ref unwrapping - skip unwrap for Array + integer key.
937 return targetIsArray && isIntegerKey(key) ? res : res.value;
938 }
939 if (isObject(res)) {
940 // Convert returned value into a proxy as well. we do the isObject check
941 // here to avoid invalid value warning. Also need to lazy access readonly
942 // and reactive here to avoid circular dependency.
943 return isReadonly ? readonly(res) : reactive(res);
944 }
945 return res;
946 };
947 }
948 const set$1 = /*#__PURE__*/ createSetter();
949 const shallowSet = /*#__PURE__*/ createSetter(true);
950 function createSetter(shallow = false) {
951 return function set(target, key, value, receiver) {
952 let oldValue = target[key];
953 if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
954 return false;
955 }
956 if (!shallow) {
957 if (!isShallow(value) && !isReadonly(value)) {
958 oldValue = toRaw(oldValue);
959 value = toRaw(value);
960 }
961 if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
962 oldValue.value = value;
963 return true;
964 }
965 }
966 const hadKey = isArray(target) && isIntegerKey(key)
967 ? Number(key) < target.length
968 : hasOwn(target, key);
969 const result = Reflect.set(target, key, value, receiver);
970 // don't trigger if target is something up in the prototype chain of original
971 if (target === toRaw(receiver)) {
972 if (!hadKey) {
973 trigger(target, "add" /* TriggerOpTypes.ADD */, key, value);
974 }
975 else if (hasChanged(value, oldValue)) {
976 trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue);
977 }
978 }
979 return result;
980 };
981 }
982 function deleteProperty(target, key) {
983 const hadKey = hasOwn(target, key);
984 const oldValue = target[key];
985 const result = Reflect.deleteProperty(target, key);
986 if (result && hadKey) {
987 trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue);
988 }
989 return result;
990 }
991 function has$1(target, key) {
992 const result = Reflect.has(target, key);
993 if (!isSymbol(key) || !builtInSymbols.has(key)) {
994 track(target, "has" /* TrackOpTypes.HAS */, key);
995 }
996 return result;
997 }
998 function ownKeys(target) {
999 track(target, "iterate" /* TrackOpTypes.ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
1000 return Reflect.ownKeys(target);
1001 }
1002 const mutableHandlers = {
1003 get: get$1,
1004 set: set$1,
1005 deleteProperty,
1006 has: has$1,
1007 ownKeys
1008 };
1009 const readonlyHandlers = {
1010 get: readonlyGet,
1011 set(target, key) {
1012 {
1013 warn$1(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
1014 }
1015 return true;
1016 },
1017 deleteProperty(target, key) {
1018 {
1019 warn$1(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
1020 }
1021 return true;
1022 }
1023 };
1024 const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
1025 get: shallowGet,
1026 set: shallowSet
1027 });
1028 // Props handlers are special in the sense that it should not unwrap top-level
1029 // refs (in order to allow refs to be explicitly passed down), but should
1030 // retain the reactivity of the normal readonly object.
1031 const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
1032 get: shallowReadonlyGet
1033 });
1034
1035 const toShallow = (value) => value;
1036 const getProto = (v) => Reflect.getPrototypeOf(v);
1037 function get(target, key, isReadonly = false, isShallow = false) {
1038 // #1772: readonly(reactive(Map)) should return readonly + reactive version
1039 // of the value
1040 target = target["__v_raw" /* ReactiveFlags.RAW */];
1041 const rawTarget = toRaw(target);
1042 const rawKey = toRaw(key);
1043 if (!isReadonly) {
1044 if (key !== rawKey) {
1045 track(rawTarget, "get" /* TrackOpTypes.GET */, key);
1046 }
1047 track(rawTarget, "get" /* TrackOpTypes.GET */, rawKey);
1048 }
1049 const { has } = getProto(rawTarget);
1050 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1051 if (has.call(rawTarget, key)) {
1052 return wrap(target.get(key));
1053 }
1054 else if (has.call(rawTarget, rawKey)) {
1055 return wrap(target.get(rawKey));
1056 }
1057 else if (target !== rawTarget) {
1058 // #3602 readonly(reactive(Map))
1059 // ensure that the nested reactive `Map` can do tracking for itself
1060 target.get(key);
1061 }
1062 }
1063 function has(key, isReadonly = false) {
1064 const target = this["__v_raw" /* ReactiveFlags.RAW */];
1065 const rawTarget = toRaw(target);
1066 const rawKey = toRaw(key);
1067 if (!isReadonly) {
1068 if (key !== rawKey) {
1069 track(rawTarget, "has" /* TrackOpTypes.HAS */, key);
1070 }
1071 track(rawTarget, "has" /* TrackOpTypes.HAS */, rawKey);
1072 }
1073 return key === rawKey
1074 ? target.has(key)
1075 : target.has(key) || target.has(rawKey);
1076 }
1077 function size(target, isReadonly = false) {
1078 target = target["__v_raw" /* ReactiveFlags.RAW */];
1079 !isReadonly && track(toRaw(target), "iterate" /* TrackOpTypes.ITERATE */, ITERATE_KEY);
1080 return Reflect.get(target, 'size', target);
1081 }
1082 function add(value) {
1083 value = toRaw(value);
1084 const target = toRaw(this);
1085 const proto = getProto(target);
1086 const hadKey = proto.has.call(target, value);
1087 if (!hadKey) {
1088 target.add(value);
1089 trigger(target, "add" /* TriggerOpTypes.ADD */, value, value);
1090 }
1091 return this;
1092 }
1093 function set(key, value) {
1094 value = toRaw(value);
1095 const target = toRaw(this);
1096 const { has, get } = getProto(target);
1097 let hadKey = has.call(target, key);
1098 if (!hadKey) {
1099 key = toRaw(key);
1100 hadKey = has.call(target, key);
1101 }
1102 else {
1103 checkIdentityKeys(target, has, key);
1104 }
1105 const oldValue = get.call(target, key);
1106 target.set(key, value);
1107 if (!hadKey) {
1108 trigger(target, "add" /* TriggerOpTypes.ADD */, key, value);
1109 }
1110 else if (hasChanged(value, oldValue)) {
1111 trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue);
1112 }
1113 return this;
1114 }
1115 function deleteEntry(key) {
1116 const target = toRaw(this);
1117 const { has, get } = getProto(target);
1118 let hadKey = has.call(target, key);
1119 if (!hadKey) {
1120 key = toRaw(key);
1121 hadKey = has.call(target, key);
1122 }
1123 else {
1124 checkIdentityKeys(target, has, key);
1125 }
1126 const oldValue = get ? get.call(target, key) : undefined;
1127 // forward the operation before queueing reactions
1128 const result = target.delete(key);
1129 if (hadKey) {
1130 trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue);
1131 }
1132 return result;
1133 }
1134 function clear() {
1135 const target = toRaw(this);
1136 const hadItems = target.size !== 0;
1137 const oldTarget = isMap(target)
1138 ? new Map(target)
1139 : new Set(target)
1140 ;
1141 // forward the operation before queueing reactions
1142 const result = target.clear();
1143 if (hadItems) {
1144 trigger(target, "clear" /* TriggerOpTypes.CLEAR */, undefined, undefined, oldTarget);
1145 }
1146 return result;
1147 }
1148 function createForEach(isReadonly, isShallow) {
1149 return function forEach(callback, thisArg) {
1150 const observed = this;
1151 const target = observed["__v_raw" /* ReactiveFlags.RAW */];
1152 const rawTarget = toRaw(target);
1153 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1154 !isReadonly && track(rawTarget, "iterate" /* TrackOpTypes.ITERATE */, ITERATE_KEY);
1155 return target.forEach((value, key) => {
1156 // important: make sure the callback is
1157 // 1. invoked with the reactive map as `this` and 3rd arg
1158 // 2. the value received should be a corresponding reactive/readonly.
1159 return callback.call(thisArg, wrap(value), wrap(key), observed);
1160 });
1161 };
1162 }
1163 function createIterableMethod(method, isReadonly, isShallow) {
1164 return function (...args) {
1165 const target = this["__v_raw" /* ReactiveFlags.RAW */];
1166 const rawTarget = toRaw(target);
1167 const targetIsMap = isMap(rawTarget);
1168 const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
1169 const isKeyOnly = method === 'keys' && targetIsMap;
1170 const innerIterator = target[method](...args);
1171 const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
1172 !isReadonly &&
1173 track(rawTarget, "iterate" /* TrackOpTypes.ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
1174 // return a wrapped iterator which returns observed versions of the
1175 // values emitted from the real iterator
1176 return {
1177 // iterator protocol
1178 next() {
1179 const { value, done } = innerIterator.next();
1180 return done
1181 ? { value, done }
1182 : {
1183 value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
1184 done
1185 };
1186 },
1187 // iterable protocol
1188 [Symbol.iterator]() {
1189 return this;
1190 }
1191 };
1192 };
1193 }
1194 function createReadonlyMethod(type) {
1195 return function (...args) {
1196 {
1197 const key = args[0] ? `on key "${args[0]}" ` : ``;
1198 console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
1199 }
1200 return type === "delete" /* TriggerOpTypes.DELETE */ ? false : this;
1201 };
1202 }
1203 function createInstrumentations() {
1204 const mutableInstrumentations = {
1205 get(key) {
1206 return get(this, key);
1207 },
1208 get size() {
1209 return size(this);
1210 },
1211 has,
1212 add,
1213 set,
1214 delete: deleteEntry,
1215 clear,
1216 forEach: createForEach(false, false)
1217 };
1218 const shallowInstrumentations = {
1219 get(key) {
1220 return get(this, key, false, true);
1221 },
1222 get size() {
1223 return size(this);
1224 },
1225 has,
1226 add,
1227 set,
1228 delete: deleteEntry,
1229 clear,
1230 forEach: createForEach(false, true)
1231 };
1232 const readonlyInstrumentations = {
1233 get(key) {
1234 return get(this, key, true);
1235 },
1236 get size() {
1237 return size(this, true);
1238 },
1239 has(key) {
1240 return has.call(this, key, true);
1241 },
1242 add: createReadonlyMethod("add" /* TriggerOpTypes.ADD */),
1243 set: createReadonlyMethod("set" /* TriggerOpTypes.SET */),
1244 delete: createReadonlyMethod("delete" /* TriggerOpTypes.DELETE */),
1245 clear: createReadonlyMethod("clear" /* TriggerOpTypes.CLEAR */),
1246 forEach: createForEach(true, false)
1247 };
1248 const shallowReadonlyInstrumentations = {
1249 get(key) {
1250 return get(this, key, true, true);
1251 },
1252 get size() {
1253 return size(this, true);
1254 },
1255 has(key) {
1256 return has.call(this, key, true);
1257 },
1258 add: createReadonlyMethod("add" /* TriggerOpTypes.ADD */),
1259 set: createReadonlyMethod("set" /* TriggerOpTypes.SET */),
1260 delete: createReadonlyMethod("delete" /* TriggerOpTypes.DELETE */),
1261 clear: createReadonlyMethod("clear" /* TriggerOpTypes.CLEAR */),
1262 forEach: createForEach(true, true)
1263 };
1264 const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
1265 iteratorMethods.forEach(method => {
1266 mutableInstrumentations[method] = createIterableMethod(method, false, false);
1267 readonlyInstrumentations[method] = createIterableMethod(method, true, false);
1268 shallowInstrumentations[method] = createIterableMethod(method, false, true);
1269 shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
1270 });
1271 return [
1272 mutableInstrumentations,
1273 readonlyInstrumentations,
1274 shallowInstrumentations,
1275 shallowReadonlyInstrumentations
1276 ];
1277 }
1278 const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
1279 function createInstrumentationGetter(isReadonly, shallow) {
1280 const instrumentations = shallow
1281 ? isReadonly
1282 ? shallowReadonlyInstrumentations
1283 : shallowInstrumentations
1284 : isReadonly
1285 ? readonlyInstrumentations
1286 : mutableInstrumentations;
1287 return (target, key, receiver) => {
1288 if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) {
1289 return !isReadonly;
1290 }
1291 else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) {
1292 return isReadonly;
1293 }
1294 else if (key === "__v_raw" /* ReactiveFlags.RAW */) {
1295 return target;
1296 }
1297 return Reflect.get(hasOwn(instrumentations, key) && key in target
1298 ? instrumentations
1299 : target, key, receiver);
1300 };
1301 }
1302 const mutableCollectionHandlers = {
1303 get: /*#__PURE__*/ createInstrumentationGetter(false, false)
1304 };
1305 const shallowCollectionHandlers = {
1306 get: /*#__PURE__*/ createInstrumentationGetter(false, true)
1307 };
1308 const readonlyCollectionHandlers = {
1309 get: /*#__PURE__*/ createInstrumentationGetter(true, false)
1310 };
1311 const shallowReadonlyCollectionHandlers = {
1312 get: /*#__PURE__*/ createInstrumentationGetter(true, true)
1313 };
1314 function checkIdentityKeys(target, has, key) {
1315 const rawKey = toRaw(key);
1316 if (rawKey !== key && has.call(target, rawKey)) {
1317 const type = toRawType(target);
1318 console.warn(`Reactive ${type} contains both the raw and reactive ` +
1319 `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
1320 `which can lead to inconsistencies. ` +
1321 `Avoid differentiating between the raw and reactive versions ` +
1322 `of an object and only use the reactive version if possible.`);
1323 }
1324 }
1325
1326 const reactiveMap = new WeakMap();
1327 const shallowReactiveMap = new WeakMap();
1328 const readonlyMap = new WeakMap();
1329 const shallowReadonlyMap = new WeakMap();
1330 function targetTypeMap(rawType) {
1331 switch (rawType) {
1332 case 'Object':
1333 case 'Array':
1334 return 1 /* TargetType.COMMON */;
1335 case 'Map':
1336 case 'Set':
1337 case 'WeakMap':
1338 case 'WeakSet':
1339 return 2 /* TargetType.COLLECTION */;
1340 default:
1341 return 0 /* TargetType.INVALID */;
1342 }
1343 }
1344 function getTargetType(value) {
1345 return value["__v_skip" /* ReactiveFlags.SKIP */] || !Object.isExtensible(value)
1346 ? 0 /* TargetType.INVALID */
1347 : targetTypeMap(toRawType(value));
1348 }
1349 function reactive(target) {
1350 // if trying to observe a readonly proxy, return the readonly version.
1351 if (isReadonly(target)) {
1352 return target;
1353 }
1354 return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
1355 }
1356 /**
1357 * Return a shallowly-reactive copy of the original object, where only the root
1358 * level properties are reactive. It also does not auto-unwrap refs (even at the
1359 * root level).
1360 */
1361 function shallowReactive(target) {
1362 return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
1363 }
1364 /**
1365 * Creates a readonly copy of the original object. Note the returned copy is not
1366 * made reactive, but `readonly` can be called on an already reactive object.
1367 */
1368 function readonly(target) {
1369 return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
1370 }
1371 /**
1372 * Returns a reactive-copy of the original object, where only the root level
1373 * properties are readonly, and does NOT unwrap refs nor recursively convert
1374 * returned properties.
1375 * This is used for creating the props proxy object for stateful components.
1376 */
1377 function shallowReadonly(target) {
1378 return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
1379 }
1380 function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
1381 if (!isObject(target)) {
1382 {
1383 console.warn(`value cannot be made reactive: ${String(target)}`);
1384 }
1385 return target;
1386 }
1387 // target is already a Proxy, return it.
1388 // exception: calling readonly() on a reactive object
1389 if (target["__v_raw" /* ReactiveFlags.RAW */] &&
1390 !(isReadonly && target["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */])) {
1391 return target;
1392 }
1393 // target already has corresponding Proxy
1394 const existingProxy = proxyMap.get(target);
1395 if (existingProxy) {
1396 return existingProxy;
1397 }
1398 // only specific value types can be observed.
1399 const targetType = getTargetType(target);
1400 if (targetType === 0 /* TargetType.INVALID */) {
1401 return target;
1402 }
1403 const proxy = new Proxy(target, targetType === 2 /* TargetType.COLLECTION */ ? collectionHandlers : baseHandlers);
1404 proxyMap.set(target, proxy);
1405 return proxy;
1406 }
1407 function isReactive(value) {
1408 if (isReadonly(value)) {
1409 return isReactive(value["__v_raw" /* ReactiveFlags.RAW */]);
1410 }
1411 return !!(value && value["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */]);
1412 }
1413 function isReadonly(value) {
1414 return !!(value && value["__v_isReadonly" /* ReactiveFlags.IS_READONLY */]);
1415 }
1416 function isShallow(value) {
1417 return !!(value && value["__v_isShallow" /* ReactiveFlags.IS_SHALLOW */]);
1418 }
1419 function isProxy(value) {
1420 return isReactive(value) || isReadonly(value);
1421 }
1422 function toRaw(observed) {
1423 const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */];
1424 return raw ? toRaw(raw) : observed;
1425 }
1426 function markRaw(value) {
1427 def(value, "__v_skip" /* ReactiveFlags.SKIP */, true);
1428 return value;
1429 }
1430 const toReactive = (value) => isObject(value) ? reactive(value) : value;
1431 const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1432
1433 function trackRefValue(ref) {
1434 if (shouldTrack && activeEffect) {
1435 ref = toRaw(ref);
1436 {
1437 trackEffects(ref.dep || (ref.dep = createDep()), {
1438 target: ref,
1439 type: "get" /* TrackOpTypes.GET */,
1440 key: 'value'
1441 });
1442 }
1443 }
1444 }
1445 function triggerRefValue(ref, newVal) {
1446 ref = toRaw(ref);
1447 const dep = ref.dep;
1448 if (dep) {
1449 {
1450 triggerEffects(dep, {
1451 target: ref,
1452 type: "set" /* TriggerOpTypes.SET */,
1453 key: 'value',
1454 newValue: newVal
1455 });
1456 }
1457 }
1458 }
1459 function isRef(r) {
1460 return !!(r && r.__v_isRef === true);
1461 }
1462 function ref(value) {
1463 return createRef(value, false);
1464 }
1465 function shallowRef(value) {
1466 return createRef(value, true);
1467 }
1468 function createRef(rawValue, shallow) {
1469 if (isRef(rawValue)) {
1470 return rawValue;
1471 }
1472 return new RefImpl(rawValue, shallow);
1473 }
1474 class RefImpl {
1475 constructor(value, __v_isShallow) {
1476 this.__v_isShallow = __v_isShallow;
1477 this.dep = undefined;
1478 this.__v_isRef = true;
1479 this._rawValue = __v_isShallow ? value : toRaw(value);
1480 this._value = __v_isShallow ? value : toReactive(value);
1481 }
1482 get value() {
1483 trackRefValue(this);
1484 return this._value;
1485 }
1486 set value(newVal) {
1487 const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
1488 newVal = useDirectValue ? newVal : toRaw(newVal);
1489 if (hasChanged(newVal, this._rawValue)) {
1490 this._rawValue = newVal;
1491 this._value = useDirectValue ? newVal : toReactive(newVal);
1492 triggerRefValue(this, newVal);
1493 }
1494 }
1495 }
1496 function triggerRef(ref) {
1497 triggerRefValue(ref, ref.value );
1498 }
1499 function unref(ref) {
1500 return isRef(ref) ? ref.value : ref;
1501 }
1502 const shallowUnwrapHandlers = {
1503 get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
1504 set: (target, key, value, receiver) => {
1505 const oldValue = target[key];
1506 if (isRef(oldValue) && !isRef(value)) {
1507 oldValue.value = value;
1508 return true;
1509 }
1510 else {
1511 return Reflect.set(target, key, value, receiver);
1512 }
1513 }
1514 };
1515 function proxyRefs(objectWithRefs) {
1516 return isReactive(objectWithRefs)
1517 ? objectWithRefs
1518 : new Proxy(objectWithRefs, shallowUnwrapHandlers);
1519 }
1520 class CustomRefImpl {
1521 constructor(factory) {
1522 this.dep = undefined;
1523 this.__v_isRef = true;
1524 const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
1525 this._get = get;
1526 this._set = set;
1527 }
1528 get value() {
1529 return this._get();
1530 }
1531 set value(newVal) {
1532 this._set(newVal);
1533 }
1534 }
1535 function customRef(factory) {
1536 return new CustomRefImpl(factory);
1537 }
1538 function toRefs(object) {
1539 if (!isProxy(object)) {
1540 console.warn(`toRefs() expects a reactive object but received a plain one.`);
1541 }
1542 const ret = isArray(object) ? new Array(object.length) : {};
1543 for (const key in object) {
1544 ret[key] = toRef(object, key);
1545 }
1546 return ret;
1547 }
1548 class ObjectRefImpl {
1549 constructor(_object, _key, _defaultValue) {
1550 this._object = _object;
1551 this._key = _key;
1552 this._defaultValue = _defaultValue;
1553 this.__v_isRef = true;
1554 }
1555 get value() {
1556 const val = this._object[this._key];
1557 return val === undefined ? this._defaultValue : val;
1558 }
1559 set value(newVal) {
1560 this._object[this._key] = newVal;
1561 }
1562 get dep() {
1563 return getDepFromReactive(toRaw(this._object), this._key);
1564 }
1565 }
1566 function toRef(object, key, defaultValue) {
1567 const val = object[key];
1568 return isRef(val)
1569 ? val
1570 : new ObjectRefImpl(object, key, defaultValue);
1571 }
1572
1573 var _a;
1574 class ComputedRefImpl {
1575 constructor(getter, _setter, isReadonly, isSSR) {
1576 this._setter = _setter;
1577 this.dep = undefined;
1578 this.__v_isRef = true;
1579 this[_a] = false;
1580 this._dirty = true;
1581 this.effect = new ReactiveEffect(getter, () => {
1582 if (!this._dirty) {
1583 this._dirty = true;
1584 triggerRefValue(this);
1585 }
1586 });
1587 this.effect.computed = this;
1588 this.effect.active = this._cacheable = !isSSR;
1589 this["__v_isReadonly" /* ReactiveFlags.IS_READONLY */] = isReadonly;
1590 }
1591 get value() {
1592 // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1593 const self = toRaw(this);
1594 trackRefValue(self);
1595 if (self._dirty || !self._cacheable) {
1596 self._dirty = false;
1597 self._value = self.effect.run();
1598 }
1599 return self._value;
1600 }
1601 set value(newValue) {
1602 this._setter(newValue);
1603 }
1604 }
1605 _a = "__v_isReadonly" /* ReactiveFlags.IS_READONLY */;
1606 function computed$1(getterOrOptions, debugOptions, isSSR = false) {
1607 let getter;
1608 let setter;
1609 const onlyGetter = isFunction(getterOrOptions);
1610 if (onlyGetter) {
1611 getter = getterOrOptions;
1612 setter = () => {
1613 console.warn('Write operation failed: computed value is readonly');
1614 }
1615 ;
1616 }
1617 else {
1618 getter = getterOrOptions.get;
1619 setter = getterOrOptions.set;
1620 }
1621 const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1622 if (debugOptions && !isSSR) {
1623 cRef.effect.onTrack = debugOptions.onTrack;
1624 cRef.effect.onTrigger = debugOptions.onTrigger;
1625 }
1626 return cRef;
1627 }
1628
1629 const stack = [];
1630 function pushWarningContext(vnode) {
1631 stack.push(vnode);
1632 }
1633 function popWarningContext() {
1634 stack.pop();
1635 }
1636 function warn(msg, ...args) {
1637 // avoid props formatting or warn handler tracking deps that might be mutated
1638 // during patch, leading to infinite recursion.
1639 pauseTracking();
1640 const instance = stack.length ? stack[stack.length - 1].component : null;
1641 const appWarnHandler = instance && instance.appContext.config.warnHandler;
1642 const trace = getComponentTrace();
1643 if (appWarnHandler) {
1644 callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [
1645 msg + args.join(''),
1646 instance && instance.proxy,
1647 trace
1648 .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
1649 .join('\n'),
1650 trace
1651 ]);
1652 }
1653 else {
1654 const warnArgs = [`[Vue warn]: ${msg}`, ...args];
1655 /* istanbul ignore if */
1656 if (trace.length &&
1657 // avoid spamming console during tests
1658 !false) {
1659 warnArgs.push(`\n`, ...formatTrace(trace));
1660 }
1661 console.warn(...warnArgs);
1662 }
1663 resetTracking();
1664 }
1665 function getComponentTrace() {
1666 let currentVNode = stack[stack.length - 1];
1667 if (!currentVNode) {
1668 return [];
1669 }
1670 // we can't just use the stack because it will be incomplete during updates
1671 // that did not start from the root. Re-construct the parent chain using
1672 // instance parent pointers.
1673 const normalizedStack = [];
1674 while (currentVNode) {
1675 const last = normalizedStack[0];
1676 if (last && last.vnode === currentVNode) {
1677 last.recurseCount++;
1678 }
1679 else {
1680 normalizedStack.push({
1681 vnode: currentVNode,
1682 recurseCount: 0
1683 });
1684 }
1685 const parentInstance = currentVNode.component && currentVNode.component.parent;
1686 currentVNode = parentInstance && parentInstance.vnode;
1687 }
1688 return normalizedStack;
1689 }
1690 /* istanbul ignore next */
1691 function formatTrace(trace) {
1692 const logs = [];
1693 trace.forEach((entry, i) => {
1694 logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
1695 });
1696 return logs;
1697 }
1698 function formatTraceEntry({ vnode, recurseCount }) {
1699 const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
1700 const isRoot = vnode.component ? vnode.component.parent == null : false;
1701 const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
1702 const close = `>` + postfix;
1703 return vnode.props
1704 ? [open, ...formatProps(vnode.props), close]
1705 : [open + close];
1706 }
1707 /* istanbul ignore next */
1708 function formatProps(props) {
1709 const res = [];
1710 const keys = Object.keys(props);
1711 keys.slice(0, 3).forEach(key => {
1712 res.push(...formatProp(key, props[key]));
1713 });
1714 if (keys.length > 3) {
1715 res.push(` ...`);
1716 }
1717 return res;
1718 }
1719 /* istanbul ignore next */
1720 function formatProp(key, value, raw) {
1721 if (isString(value)) {
1722 value = JSON.stringify(value);
1723 return raw ? value : [`${key}=${value}`];
1724 }
1725 else if (typeof value === 'number' ||
1726 typeof value === 'boolean' ||
1727 value == null) {
1728 return raw ? value : [`${key}=${value}`];
1729 }
1730 else if (isRef(value)) {
1731 value = formatProp(key, toRaw(value.value), true);
1732 return raw ? value : [`${key}=Ref<`, value, `>`];
1733 }
1734 else if (isFunction(value)) {
1735 return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
1736 }
1737 else {
1738 value = toRaw(value);
1739 return raw ? value : [`${key}=`, value];
1740 }
1741 }
1742 /**
1743 * @internal
1744 */
1745 function assertNumber(val, type) {
1746 if (val === undefined) {
1747 return;
1748 }
1749 else if (typeof val !== 'number') {
1750 warn(`${type} is not a valid number - ` + `got ${JSON.stringify(val)}.`);
1751 }
1752 else if (isNaN(val)) {
1753 warn(`${type} is NaN - ` + 'the duration expression might be incorrect.');
1754 }
1755 }
1756
1757 const ErrorTypeStrings = {
1758 ["sp" /* LifecycleHooks.SERVER_PREFETCH */]: 'serverPrefetch hook',
1759 ["bc" /* LifecycleHooks.BEFORE_CREATE */]: 'beforeCreate hook',
1760 ["c" /* LifecycleHooks.CREATED */]: 'created hook',
1761 ["bm" /* LifecycleHooks.BEFORE_MOUNT */]: 'beforeMount hook',
1762 ["m" /* LifecycleHooks.MOUNTED */]: 'mounted hook',
1763 ["bu" /* LifecycleHooks.BEFORE_UPDATE */]: 'beforeUpdate hook',
1764 ["u" /* LifecycleHooks.UPDATED */]: 'updated',
1765 ["bum" /* LifecycleHooks.BEFORE_UNMOUNT */]: 'beforeUnmount hook',
1766 ["um" /* LifecycleHooks.UNMOUNTED */]: 'unmounted hook',
1767 ["a" /* LifecycleHooks.ACTIVATED */]: 'activated hook',
1768 ["da" /* LifecycleHooks.DEACTIVATED */]: 'deactivated hook',
1769 ["ec" /* LifecycleHooks.ERROR_CAPTURED */]: 'errorCaptured hook',
1770 ["rtc" /* LifecycleHooks.RENDER_TRACKED */]: 'renderTracked hook',
1771 ["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook',
1772 [0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function',
1773 [1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function',
1774 [2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter',
1775 [3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback',
1776 [4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function',
1777 [5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler',
1778 [6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler',
1779 [7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook',
1780 [8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook',
1781 [9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook',
1782 [10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler',
1783 [11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler',
1784 [12 /* ErrorCodes.FUNCTION_REF */]: 'ref function',
1785 [13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader',
1786 [14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1787 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
1788 };
1789 function callWithErrorHandling(fn, instance, type, args) {
1790 let res;
1791 try {
1792 res = args ? fn(...args) : fn();
1793 }
1794 catch (err) {
1795 handleError(err, instance, type);
1796 }
1797 return res;
1798 }
1799 function callWithAsyncErrorHandling(fn, instance, type, args) {
1800 if (isFunction(fn)) {
1801 const res = callWithErrorHandling(fn, instance, type, args);
1802 if (res && isPromise(res)) {
1803 res.catch(err => {
1804 handleError(err, instance, type);
1805 });
1806 }
1807 return res;
1808 }
1809 const values = [];
1810 for (let i = 0; i < fn.length; i++) {
1811 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
1812 }
1813 return values;
1814 }
1815 function handleError(err, instance, type, throwInDev = true) {
1816 const contextVNode = instance ? instance.vnode : null;
1817 if (instance) {
1818 let cur = instance.parent;
1819 // the exposed instance is the render proxy to keep it consistent with 2.x
1820 const exposedInstance = instance.proxy;
1821 // in production the hook receives only the error code
1822 const errorInfo = ErrorTypeStrings[type] ;
1823 while (cur) {
1824 const errorCapturedHooks = cur.ec;
1825 if (errorCapturedHooks) {
1826 for (let i = 0; i < errorCapturedHooks.length; i++) {
1827 if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
1828 return;
1829 }
1830 }
1831 }
1832 cur = cur.parent;
1833 }
1834 // app-level handling
1835 const appErrorHandler = instance.appContext.config.errorHandler;
1836 if (appErrorHandler) {
1837 callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
1838 return;
1839 }
1840 }
1841 logError(err, type, contextVNode, throwInDev);
1842 }
1843 function logError(err, type, contextVNode, throwInDev = true) {
1844 {
1845 const info = ErrorTypeStrings[type];
1846 if (contextVNode) {
1847 pushWarningContext(contextVNode);
1848 }
1849 warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
1850 if (contextVNode) {
1851 popWarningContext();
1852 }
1853 // crash in dev by default so it's more noticeable
1854 if (throwInDev) {
1855 throw err;
1856 }
1857 else {
1858 console.error(err);
1859 }
1860 }
1861 }
1862
1863 let isFlushing = false;
1864 let isFlushPending = false;
1865 const queue = [];
1866 let flushIndex = 0;
1867 const pendingPostFlushCbs = [];
1868 let activePostFlushCbs = null;
1869 let postFlushIndex = 0;
1870 const resolvedPromise = /*#__PURE__*/ Promise.resolve();
1871 let currentFlushPromise = null;
1872 const RECURSION_LIMIT = 100;
1873 function nextTick(fn) {
1874 const p = currentFlushPromise || resolvedPromise;
1875 return fn ? p.then(this ? fn.bind(this) : fn) : p;
1876 }
1877 // #2768
1878 // Use binary-search to find a suitable position in the queue,
1879 // so that the queue maintains the increasing order of job's id,
1880 // which can prevent the job from being skipped and also can avoid repeated patching.
1881 function findInsertionIndex(id) {
1882 // the start index should be `flushIndex + 1`
1883 let start = flushIndex + 1;
1884 let end = queue.length;
1885 while (start < end) {
1886 const middle = (start + end) >>> 1;
1887 const middleJobId = getId(queue[middle]);
1888 middleJobId < id ? (start = middle + 1) : (end = middle);
1889 }
1890 return start;
1891 }
1892 function queueJob(job) {
1893 // the dedupe search uses the startIndex argument of Array.includes()
1894 // by default the search index includes the current job that is being run
1895 // so it cannot recursively trigger itself again.
1896 // if the job is a watch() callback, the search will start with a +1 index to
1897 // allow it recursively trigger itself - it is the user's responsibility to
1898 // ensure it doesn't end up in an infinite loop.
1899 if (!queue.length ||
1900 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) {
1901 if (job.id == null) {
1902 queue.push(job);
1903 }
1904 else {
1905 queue.splice(findInsertionIndex(job.id), 0, job);
1906 }
1907 queueFlush();
1908 }
1909 }
1910 function queueFlush() {
1911 if (!isFlushing && !isFlushPending) {
1912 isFlushPending = true;
1913 currentFlushPromise = resolvedPromise.then(flushJobs);
1914 }
1915 }
1916 function invalidateJob(job) {
1917 const i = queue.indexOf(job);
1918 if (i > flushIndex) {
1919 queue.splice(i, 1);
1920 }
1921 }
1922 function queuePostFlushCb(cb) {
1923 if (!isArray(cb)) {
1924 if (!activePostFlushCbs ||
1925 !activePostFlushCbs.includes(cb, cb.allowRecurse ? postFlushIndex + 1 : postFlushIndex)) {
1926 pendingPostFlushCbs.push(cb);
1927 }
1928 }
1929 else {
1930 // if cb is an array, it is a component lifecycle hook which can only be
1931 // triggered by a job, which is already deduped in the main queue, so
1932 // we can skip duplicate check here to improve perf
1933 pendingPostFlushCbs.push(...cb);
1934 }
1935 queueFlush();
1936 }
1937 function flushPreFlushCbs(seen,
1938 // if currently flushing, skip the current job itself
1939 i = isFlushing ? flushIndex + 1 : 0) {
1940 {
1941 seen = seen || new Map();
1942 }
1943 for (; i < queue.length; i++) {
1944 const cb = queue[i];
1945 if (cb && cb.pre) {
1946 if (checkRecursiveUpdates(seen, cb)) {
1947 continue;
1948 }
1949 queue.splice(i, 1);
1950 i--;
1951 cb();
1952 }
1953 }
1954 }
1955 function flushPostFlushCbs(seen) {
1956 if (pendingPostFlushCbs.length) {
1957 const deduped = [...new Set(pendingPostFlushCbs)];
1958 pendingPostFlushCbs.length = 0;
1959 // #1947 already has active queue, nested flushPostFlushCbs call
1960 if (activePostFlushCbs) {
1961 activePostFlushCbs.push(...deduped);
1962 return;
1963 }
1964 activePostFlushCbs = deduped;
1965 {
1966 seen = seen || new Map();
1967 }
1968 activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
1969 for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
1970 if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
1971 continue;
1972 }
1973 activePostFlushCbs[postFlushIndex]();
1974 }
1975 activePostFlushCbs = null;
1976 postFlushIndex = 0;
1977 }
1978 }
1979 const getId = (job) => job.id == null ? Infinity : job.id;
1980 const comparator = (a, b) => {
1981 const diff = getId(a) - getId(b);
1982 if (diff === 0) {
1983 if (a.pre && !b.pre)
1984 return -1;
1985 if (b.pre && !a.pre)
1986 return 1;
1987 }
1988 return diff;
1989 };
1990 function flushJobs(seen) {
1991 isFlushPending = false;
1992 isFlushing = true;
1993 {
1994 seen = seen || new Map();
1995 }
1996 // Sort queue before flush.
1997 // This ensures that:
1998 // 1. Components are updated from parent to child. (because parent is always
1999 // created before the child so its render effect will have smaller
2000 // priority number)
2001 // 2. If a component is unmounted during a parent component's update,
2002 // its update can be skipped.
2003 queue.sort(comparator);
2004 // conditional usage of checkRecursiveUpdate must be determined out of
2005 // try ... catch block since Rollup by default de-optimizes treeshaking
2006 // inside try-catch. This can leave all warning code unshaked. Although
2007 // they would get eventually shaken by a minifier like terser, some minifiers
2008 // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610)
2009 const check = (job) => checkRecursiveUpdates(seen, job)
2010 ;
2011 try {
2012 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
2013 const job = queue[flushIndex];
2014 if (job && job.active !== false) {
2015 if (true && check(job)) {
2016 continue;
2017 }
2018 // console.log(`running:`, job.id)
2019 callWithErrorHandling(job, null, 14 /* ErrorCodes.SCHEDULER */);
2020 }
2021 }
2022 }
2023 finally {
2024 flushIndex = 0;
2025 queue.length = 0;
2026 flushPostFlushCbs(seen);
2027 isFlushing = false;
2028 currentFlushPromise = null;
2029 // some postFlushCb queued jobs!
2030 // keep flushing until it drains.
2031 if (queue.length || pendingPostFlushCbs.length) {
2032 flushJobs(seen);
2033 }
2034 }
2035 }
2036 function checkRecursiveUpdates(seen, fn) {
2037 if (!seen.has(fn)) {
2038 seen.set(fn, 1);
2039 }
2040 else {
2041 const count = seen.get(fn);
2042 if (count > RECURSION_LIMIT) {
2043 const instance = fn.ownerInstance;
2044 const componentName = instance && getComponentName(instance.type);
2045 warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
2046 `This means you have a reactive effect that is mutating its own ` +
2047 `dependencies and thus recursively triggering itself. Possible sources ` +
2048 `include component template, render function, updated hook or ` +
2049 `watcher source function.`);
2050 return true;
2051 }
2052 else {
2053 seen.set(fn, count + 1);
2054 }
2055 }
2056 }
2057
2058 /* eslint-disable no-restricted-globals */
2059 let isHmrUpdating = false;
2060 const hmrDirtyComponents = new Set();
2061 // Expose the HMR runtime on the global object
2062 // This makes it entirely tree-shakable without polluting the exports and makes
2063 // it easier to be used in toolings like vue-loader
2064 // Note: for a component to be eligible for HMR it also needs the __hmrId option
2065 // to be set so that its instances can be registered / removed.
2066 {
2067 getGlobalThis().__VUE_HMR_RUNTIME__ = {
2068 createRecord: tryWrap(createRecord),
2069 rerender: tryWrap(rerender),
2070 reload: tryWrap(reload)
2071 };
2072 }
2073 const map = new Map();
2074 function registerHMR(instance) {
2075 const id = instance.type.__hmrId;
2076 let record = map.get(id);
2077 if (!record) {
2078 createRecord(id, instance.type);
2079 record = map.get(id);
2080 }
2081 record.instances.add(instance);
2082 }
2083 function unregisterHMR(instance) {
2084 map.get(instance.type.__hmrId).instances.delete(instance);
2085 }
2086 function createRecord(id, initialDef) {
2087 if (map.has(id)) {
2088 return false;
2089 }
2090 map.set(id, {
2091 initialDef: normalizeClassComponent(initialDef),
2092 instances: new Set()
2093 });
2094 return true;
2095 }
2096 function normalizeClassComponent(component) {
2097 return isClassComponent(component) ? component.__vccOpts : component;
2098 }
2099 function rerender(id, newRender) {
2100 const record = map.get(id);
2101 if (!record) {
2102 return;
2103 }
2104 // update initial record (for not-yet-rendered component)
2105 record.initialDef.render = newRender;
2106 [...record.instances].forEach(instance => {
2107 if (newRender) {
2108 instance.render = newRender;
2109 normalizeClassComponent(instance.type).render = newRender;
2110 }
2111 instance.renderCache = [];
2112 // this flag forces child components with slot content to update
2113 isHmrUpdating = true;
2114 instance.update();
2115 isHmrUpdating = false;
2116 });
2117 }
2118 function reload(id, newComp) {
2119 const record = map.get(id);
2120 if (!record)
2121 return;
2122 newComp = normalizeClassComponent(newComp);
2123 // update initial def (for not-yet-rendered components)
2124 updateComponentDef(record.initialDef, newComp);
2125 // create a snapshot which avoids the set being mutated during updates
2126 const instances = [...record.instances];
2127 for (const instance of instances) {
2128 const oldComp = normalizeClassComponent(instance.type);
2129 if (!hmrDirtyComponents.has(oldComp)) {
2130 // 1. Update existing comp definition to match new one
2131 if (oldComp !== record.initialDef) {
2132 updateComponentDef(oldComp, newComp);
2133 }
2134 // 2. mark definition dirty. This forces the renderer to replace the
2135 // component on patch.
2136 hmrDirtyComponents.add(oldComp);
2137 }
2138 // 3. invalidate options resolution cache
2139 instance.appContext.optionsCache.delete(instance.type);
2140 // 4. actually update
2141 if (instance.ceReload) {
2142 // custom element
2143 hmrDirtyComponents.add(oldComp);
2144 instance.ceReload(newComp.styles);
2145 hmrDirtyComponents.delete(oldComp);
2146 }
2147 else if (instance.parent) {
2148 // 4. Force the parent instance to re-render. This will cause all updated
2149 // components to be unmounted and re-mounted. Queue the update so that we
2150 // don't end up forcing the same parent to re-render multiple times.
2151 queueJob(instance.parent.update);
2152 }
2153 else if (instance.appContext.reload) {
2154 // root instance mounted via createApp() has a reload method
2155 instance.appContext.reload();
2156 }
2157 else if (typeof window !== 'undefined') {
2158 // root instance inside tree created via raw render(). Force reload.
2159 window.location.reload();
2160 }
2161 else {
2162 console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
2163 }
2164 }
2165 // 5. make sure to cleanup dirty hmr components after update
2166 queuePostFlushCb(() => {
2167 for (const instance of instances) {
2168 hmrDirtyComponents.delete(normalizeClassComponent(instance.type));
2169 }
2170 });
2171 }
2172 function updateComponentDef(oldComp, newComp) {
2173 extend(oldComp, newComp);
2174 for (const key in oldComp) {
2175 if (key !== '__file' && !(key in newComp)) {
2176 delete oldComp[key];
2177 }
2178 }
2179 }
2180 function tryWrap(fn) {
2181 return (id, arg) => {
2182 try {
2183 return fn(id, arg);
2184 }
2185 catch (e) {
2186 console.error(e);
2187 console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
2188 `Full reload required.`);
2189 }
2190 };
2191 }
2192
2193 exports.devtools = void 0;
2194 let buffer = [];
2195 let devtoolsNotInstalled = false;
2196 function emit$1(event, ...args) {
2197 if (exports.devtools) {
2198 exports.devtools.emit(event, ...args);
2199 }
2200 else if (!devtoolsNotInstalled) {
2201 buffer.push({ event, args });
2202 }
2203 }
2204 function setDevtoolsHook(hook, target) {
2205 var _a, _b;
2206 exports.devtools = hook;
2207 if (exports.devtools) {
2208 exports.devtools.enabled = true;
2209 buffer.forEach(({ event, args }) => exports.devtools.emit(event, ...args));
2210 buffer = [];
2211 }
2212 else if (
2213 // handle late devtools injection - only do this if we are in an actual
2214 // browser environment to avoid the timer handle stalling test runner exit
2215 // (#4815)
2216 typeof window !== 'undefined' &&
2217 // some envs mock window but not fully
2218 window.HTMLElement &&
2219 // also exclude jsdom
2220 !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
2221 const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
2222 target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
2223 replay.push((newHook) => {
2224 setDevtoolsHook(newHook, target);
2225 });
2226 // clear buffer after 3s - the user probably doesn't have devtools installed
2227 // at all, and keeping the buffer will cause memory leaks (#4738)
2228 setTimeout(() => {
2229 if (!exports.devtools) {
2230 target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
2231 devtoolsNotInstalled = true;
2232 buffer = [];
2233 }
2234 }, 3000);
2235 }
2236 else {
2237 // non-browser env, assume not installed
2238 devtoolsNotInstalled = true;
2239 buffer = [];
2240 }
2241 }
2242 function devtoolsInitApp(app, version) {
2243 emit$1("app:init" /* DevtoolsHooks.APP_INIT */, app, version, {
2244 Fragment,
2245 Text,
2246 Comment,
2247 Static
2248 });
2249 }
2250 function devtoolsUnmountApp(app) {
2251 emit$1("app:unmount" /* DevtoolsHooks.APP_UNMOUNT */, app);
2252 }
2253 const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* DevtoolsHooks.COMPONENT_ADDED */);
2254 const devtoolsComponentUpdated =
2255 /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* DevtoolsHooks.COMPONENT_UPDATED */);
2256 const _devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* DevtoolsHooks.COMPONENT_REMOVED */);
2257 const devtoolsComponentRemoved = (component) => {
2258 if (exports.devtools &&
2259 typeof exports.devtools.cleanupBuffer === 'function' &&
2260 // remove the component if it wasn't buffered
2261 !exports.devtools.cleanupBuffer(component)) {
2262 _devtoolsComponentRemoved(component);
2263 }
2264 };
2265 function createDevtoolsComponentHook(hook) {
2266 return (component) => {
2267 emit$1(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
2268 };
2269 }
2270 const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* DevtoolsHooks.PERFORMANCE_START */);
2271 const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* DevtoolsHooks.PERFORMANCE_END */);
2272 function createDevtoolsPerformanceHook(hook) {
2273 return (component, type, time) => {
2274 emit$1(hook, component.appContext.app, component.uid, component, type, time);
2275 };
2276 }
2277 function devtoolsComponentEmit(component, event, params) {
2278 emit$1("component:emit" /* DevtoolsHooks.COMPONENT_EMIT */, component.appContext.app, component, event, params);
2279 }
2280
2281 function emit(instance, event, ...rawArgs) {
2282 if (instance.isUnmounted)
2283 return;
2284 const props = instance.vnode.props || EMPTY_OBJ;
2285 {
2286 const { emitsOptions, propsOptions: [propsOptions] } = instance;
2287 if (emitsOptions) {
2288 if (!(event in emitsOptions) &&
2289 !(false )) {
2290 if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
2291 warn(`Component emitted event "${event}" but it is neither declared in ` +
2292 `the emits option nor as an "${toHandlerKey(event)}" prop.`);
2293 }
2294 }
2295 else {
2296 const validator = emitsOptions[event];
2297 if (isFunction(validator)) {
2298 const isValid = validator(...rawArgs);
2299 if (!isValid) {
2300 warn(`Invalid event arguments: event validation failed for event "${event}".`);
2301 }
2302 }
2303 }
2304 }
2305 }
2306 let args = rawArgs;
2307 const isModelListener = event.startsWith('update:');
2308 // for v-model update:xxx events, apply modifiers on args
2309 const modelArg = isModelListener && event.slice(7);
2310 if (modelArg && modelArg in props) {
2311 const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
2312 const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
2313 if (trim) {
2314 args = rawArgs.map(a => (isString(a) ? a.trim() : a));
2315 }
2316 if (number) {
2317 args = rawArgs.map(looseToNumber);
2318 }
2319 }
2320 {
2321 devtoolsComponentEmit(instance, event, args);
2322 }
2323 {
2324 const lowerCaseEvent = event.toLowerCase();
2325 if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
2326 warn(`Event "${lowerCaseEvent}" is emitted in component ` +
2327 `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
2328 `Note that HTML attributes are case-insensitive and you cannot use ` +
2329 `v-on to listen to camelCase events when using in-DOM templates. ` +
2330 `You should probably use "${hyphenate(event)}" instead of "${event}".`);
2331 }
2332 }
2333 let handlerName;
2334 let handler = props[(handlerName = toHandlerKey(event))] ||
2335 // also try camelCase event handler (#2249)
2336 props[(handlerName = toHandlerKey(camelize(event)))];
2337 // for v-model update:xxx events, also trigger kebab-case equivalent
2338 // for props passed via kebab-case
2339 if (!handler && isModelListener) {
2340 handler = props[(handlerName = toHandlerKey(hyphenate(event)))];
2341 }
2342 if (handler) {
2343 callWithAsyncErrorHandling(handler, instance, 6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */, args);
2344 }
2345 const onceHandler = props[handlerName + `Once`];
2346 if (onceHandler) {
2347 if (!instance.emitted) {
2348 instance.emitted = {};
2349 }
2350 else if (instance.emitted[handlerName]) {
2351 return;
2352 }
2353 instance.emitted[handlerName] = true;
2354 callWithAsyncErrorHandling(onceHandler, instance, 6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */, args);
2355 }
2356 }
2357 function normalizeEmitsOptions(comp, appContext, asMixin = false) {
2358 const cache = appContext.emitsCache;
2359 const cached = cache.get(comp);
2360 if (cached !== undefined) {
2361 return cached;
2362 }
2363 const raw = comp.emits;
2364 let normalized = {};
2365 // apply mixin/extends props
2366 let hasExtends = false;
2367 if (!isFunction(comp)) {
2368 const extendEmits = (raw) => {
2369 const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
2370 if (normalizedFromExtend) {
2371 hasExtends = true;
2372 extend(normalized, normalizedFromExtend);
2373 }
2374 };
2375 if (!asMixin && appContext.mixins.length) {
2376 appContext.mixins.forEach(extendEmits);
2377 }
2378 if (comp.extends) {
2379 extendEmits(comp.extends);
2380 }
2381 if (comp.mixins) {
2382 comp.mixins.forEach(extendEmits);
2383 }
2384 }
2385 if (!raw && !hasExtends) {
2386 if (isObject(comp)) {
2387 cache.set(comp, null);
2388 }
2389 return null;
2390 }
2391 if (isArray(raw)) {
2392 raw.forEach(key => (normalized[key] = null));
2393 }
2394 else {
2395 extend(normalized, raw);
2396 }
2397 if (isObject(comp)) {
2398 cache.set(comp, normalized);
2399 }
2400 return normalized;
2401 }
2402 // Check if an incoming prop key is a declared emit event listener.
2403 // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
2404 // both considered matched listeners.
2405 function isEmitListener(options, key) {
2406 if (!options || !isOn(key)) {
2407 return false;
2408 }
2409 key = key.slice(2).replace(/Once$/, '');
2410 return (hasOwn(options, key[0].toLowerCase() + key.slice(1)) ||
2411 hasOwn(options, hyphenate(key)) ||
2412 hasOwn(options, key));
2413 }
2414
2415 /**
2416 * mark the current rendering instance for asset resolution (e.g.
2417 * resolveComponent, resolveDirective) during render
2418 */
2419 let currentRenderingInstance = null;
2420 let currentScopeId = null;
2421 /**
2422 * Note: rendering calls maybe nested. The function returns the parent rendering
2423 * instance if present, which should be restored after the render is done:
2424 *
2425 * ```js
2426 * const prev = setCurrentRenderingInstance(i)
2427 * // ...render
2428 * setCurrentRenderingInstance(prev)
2429 * ```
2430 */
2431 function setCurrentRenderingInstance(instance) {
2432 const prev = currentRenderingInstance;
2433 currentRenderingInstance = instance;
2434 currentScopeId = (instance && instance.type.__scopeId) || null;
2435 return prev;
2436 }
2437 /**
2438 * Set scope id when creating hoisted vnodes.
2439 * @private compiler helper
2440 */
2441 function pushScopeId(id) {
2442 currentScopeId = id;
2443 }
2444 /**
2445 * Technically we no longer need this after 3.0.8 but we need to keep the same
2446 * API for backwards compat w/ code generated by compilers.
2447 * @private
2448 */
2449 function popScopeId() {
2450 currentScopeId = null;
2451 }
2452 /**
2453 * Only for backwards compat
2454 * @private
2455 */
2456 const withScopeId = (_id) => withCtx;
2457 /**
2458 * Wrap a slot function to memoize current rendering instance
2459 * @private compiler helper
2460 */
2461 function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
2462 ) {
2463 if (!ctx)
2464 return fn;
2465 // already normalized
2466 if (fn._n) {
2467 return fn;
2468 }
2469 const renderFnWithContext = (...args) => {
2470 // If a user calls a compiled slot inside a template expression (#1745), it
2471 // can mess up block tracking, so by default we disable block tracking and
2472 // force bail out when invoking a compiled slot (indicated by the ._d flag).
2473 // This isn't necessary if rendering a compiled `<slot>`, so we flip the
2474 // ._d flag off when invoking the wrapped fn inside `renderSlot`.
2475 if (renderFnWithContext._d) {
2476 setBlockTracking(-1);
2477 }
2478 const prevInstance = setCurrentRenderingInstance(ctx);
2479 let res;
2480 try {
2481 res = fn(...args);
2482 }
2483 finally {
2484 setCurrentRenderingInstance(prevInstance);
2485 if (renderFnWithContext._d) {
2486 setBlockTracking(1);
2487 }
2488 }
2489 {
2490 devtoolsComponentUpdated(ctx);
2491 }
2492 return res;
2493 };
2494 // mark normalized to avoid duplicated wrapping
2495 renderFnWithContext._n = true;
2496 // mark this as compiled by default
2497 // this is used in vnode.ts -> normalizeChildren() to set the slot
2498 // rendering flag.
2499 renderFnWithContext._c = true;
2500 // disable block tracking by default
2501 renderFnWithContext._d = true;
2502 return renderFnWithContext;
2503 }
2504
2505 /**
2506 * dev only flag to track whether $attrs was used during render.
2507 * If $attrs was used during render then the warning for failed attrs
2508 * fallthrough can be suppressed.
2509 */
2510 let accessedAttrs = false;
2511 function markAttrsAccessed() {
2512 accessedAttrs = true;
2513 }
2514 function renderComponentRoot(instance) {
2515 const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
2516 let result;
2517 let fallthroughAttrs;
2518 const prev = setCurrentRenderingInstance(instance);
2519 {
2520 accessedAttrs = false;
2521 }
2522 try {
2523 if (vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */) {
2524 // withProxy is a proxy with a different `has` trap only for
2525 // runtime-compiled render functions using `with` block.
2526 const proxyToUse = withProxy || proxy;
2527 result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
2528 fallthroughAttrs = attrs;
2529 }
2530 else {
2531 // functional
2532 const render = Component;
2533 // in dev, mark attrs accessed if optional props (attrs === props)
2534 if (true && attrs === props) {
2535 markAttrsAccessed();
2536 }
2537 result = normalizeVNode(render.length > 1
2538 ? render(props, true
2539 ? {
2540 get attrs() {
2541 markAttrsAccessed();
2542 return attrs;
2543 },
2544 slots,
2545 emit
2546 }
2547 : { attrs, slots, emit })
2548 : render(props, null /* we know it doesn't need it */));
2549 fallthroughAttrs = Component.props
2550 ? attrs
2551 : getFunctionalFallthrough(attrs);
2552 }
2553 }
2554 catch (err) {
2555 blockStack.length = 0;
2556 handleError(err, instance, 1 /* ErrorCodes.RENDER_FUNCTION */);
2557 result = createVNode(Comment);
2558 }
2559 // attr merging
2560 // in dev mode, comments are preserved, and it's possible for a template
2561 // to have comments along side the root element which makes it a fragment
2562 let root = result;
2563 let setRoot = undefined;
2564 if (result.patchFlag > 0 &&
2565 result.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */) {
2566 [root, setRoot] = getChildRoot(result);
2567 }
2568 if (fallthroughAttrs && inheritAttrs !== false) {
2569 const keys = Object.keys(fallthroughAttrs);
2570 const { shapeFlag } = root;
2571 if (keys.length) {
2572 if (shapeFlag & (1 /* ShapeFlags.ELEMENT */ | 6 /* ShapeFlags.COMPONENT */)) {
2573 if (propsOptions && keys.some(isModelListener)) {
2574 // If a v-model listener (onUpdate:xxx) has a corresponding declared
2575 // prop, it indicates this component expects to handle v-model and
2576 // it should not fallthrough.
2577 // related: #1543, #1643, #1989
2578 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
2579 }
2580 root = cloneVNode(root, fallthroughAttrs);
2581 }
2582 else if (!accessedAttrs && root.type !== Comment) {
2583 const allAttrs = Object.keys(attrs);
2584 const eventAttrs = [];
2585 const extraAttrs = [];
2586 for (let i = 0, l = allAttrs.length; i < l; i++) {
2587 const key = allAttrs[i];
2588 if (isOn(key)) {
2589 // ignore v-model handlers when they fail to fallthrough
2590 if (!isModelListener(key)) {
2591 // remove `on`, lowercase first letter to reflect event casing
2592 // accurately
2593 eventAttrs.push(key[2].toLowerCase() + key.slice(3));
2594 }
2595 }
2596 else {
2597 extraAttrs.push(key);
2598 }
2599 }
2600 if (extraAttrs.length) {
2601 warn(`Extraneous non-props attributes (` +
2602 `${extraAttrs.join(', ')}) ` +
2603 `were passed to component but could not be automatically inherited ` +
2604 `because component renders fragment or text root nodes.`);
2605 }
2606 if (eventAttrs.length) {
2607 warn(`Extraneous non-emits event listeners (` +
2608 `${eventAttrs.join(', ')}) ` +
2609 `were passed to component but could not be automatically inherited ` +
2610 `because component renders fragment or text root nodes. ` +
2611 `If the listener is intended to be a component custom event listener only, ` +
2612 `declare it using the "emits" option.`);
2613 }
2614 }
2615 }
2616 }
2617 // inherit directives
2618 if (vnode.dirs) {
2619 if (!isElementRoot(root)) {
2620 warn(`Runtime directive used on component with non-element root node. ` +
2621 `The directives will not function as intended.`);
2622 }
2623 // clone before mutating since the root may be a hoisted vnode
2624 root = cloneVNode(root);
2625 root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
2626 }
2627 // inherit transition data
2628 if (vnode.transition) {
2629 if (!isElementRoot(root)) {
2630 warn(`Component inside <Transition> renders non-element root node ` +
2631 `that cannot be animated.`);
2632 }
2633 root.transition = vnode.transition;
2634 }
2635 if (setRoot) {
2636 setRoot(root);
2637 }
2638 else {
2639 result = root;
2640 }
2641 setCurrentRenderingInstance(prev);
2642 return result;
2643 }
2644 /**
2645 * dev only
2646 * In dev mode, template root level comments are rendered, which turns the
2647 * template into a fragment root, but we need to locate the single element
2648 * root for attrs and scope id processing.
2649 */
2650 const getChildRoot = (vnode) => {
2651 const rawChildren = vnode.children;
2652 const dynamicChildren = vnode.dynamicChildren;
2653 const childRoot = filterSingleRoot(rawChildren);
2654 if (!childRoot) {
2655 return [vnode, undefined];
2656 }
2657 const index = rawChildren.indexOf(childRoot);
2658 const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
2659 const setRoot = (updatedRoot) => {
2660 rawChildren[index] = updatedRoot;
2661 if (dynamicChildren) {
2662 if (dynamicIndex > -1) {
2663 dynamicChildren[dynamicIndex] = updatedRoot;
2664 }
2665 else if (updatedRoot.patchFlag > 0) {
2666 vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
2667 }
2668 }
2669 };
2670 return [normalizeVNode(childRoot), setRoot];
2671 };
2672 function filterSingleRoot(children) {
2673 let singleRoot;
2674 for (let i = 0; i < children.length; i++) {
2675 const child = children[i];
2676 if (isVNode(child)) {
2677 // ignore user comment
2678 if (child.type !== Comment || child.children === 'v-if') {
2679 if (singleRoot) {
2680 // has more than 1 non-comment child, return now
2681 return;
2682 }
2683 else {
2684 singleRoot = child;
2685 }
2686 }
2687 }
2688 else {
2689 return;
2690 }
2691 }
2692 return singleRoot;
2693 }
2694 const getFunctionalFallthrough = (attrs) => {
2695 let res;
2696 for (const key in attrs) {
2697 if (key === 'class' || key === 'style' || isOn(key)) {
2698 (res || (res = {}))[key] = attrs[key];
2699 }
2700 }
2701 return res;
2702 };
2703 const filterModelListeners = (attrs, props) => {
2704 const res = {};
2705 for (const key in attrs) {
2706 if (!isModelListener(key) || !(key.slice(9) in props)) {
2707 res[key] = attrs[key];
2708 }
2709 }
2710 return res;
2711 };
2712 const isElementRoot = (vnode) => {
2713 return (vnode.shapeFlag & (6 /* ShapeFlags.COMPONENT */ | 1 /* ShapeFlags.ELEMENT */) ||
2714 vnode.type === Comment // potential v-if branch switch
2715 );
2716 };
2717 function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
2718 const { props: prevProps, children: prevChildren, component } = prevVNode;
2719 const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
2720 const emits = component.emitsOptions;
2721 // Parent component's render function was hot-updated. Since this may have
2722 // caused the child component's slots content to have changed, we need to
2723 // force the child to update as well.
2724 if ((prevChildren || nextChildren) && isHmrUpdating) {
2725 return true;
2726 }
2727 // force child update for runtime directive or transition on component vnode.
2728 if (nextVNode.dirs || nextVNode.transition) {
2729 return true;
2730 }
2731 if (optimized && patchFlag >= 0) {
2732 if (patchFlag & 1024 /* PatchFlags.DYNAMIC_SLOTS */) {
2733 // slot content that references values that might have changed,
2734 // e.g. in a v-for
2735 return true;
2736 }
2737 if (patchFlag & 16 /* PatchFlags.FULL_PROPS */) {
2738 if (!prevProps) {
2739 return !!nextProps;
2740 }
2741 // presence of this flag indicates props are always non-null
2742 return hasPropsChanged(prevProps, nextProps, emits);
2743 }
2744 else if (patchFlag & 8 /* PatchFlags.PROPS */) {
2745 const dynamicProps = nextVNode.dynamicProps;
2746 for (let i = 0; i < dynamicProps.length; i++) {
2747 const key = dynamicProps[i];
2748 if (nextProps[key] !== prevProps[key] &&
2749 !isEmitListener(emits, key)) {
2750 return true;
2751 }
2752 }
2753 }
2754 }
2755 else {
2756 // this path is only taken by manually written render functions
2757 // so presence of any children leads to a forced update
2758 if (prevChildren || nextChildren) {
2759 if (!nextChildren || !nextChildren.$stable) {
2760 return true;
2761 }
2762 }
2763 if (prevProps === nextProps) {
2764 return false;
2765 }
2766 if (!prevProps) {
2767 return !!nextProps;
2768 }
2769 if (!nextProps) {
2770 return true;
2771 }
2772 return hasPropsChanged(prevProps, nextProps, emits);
2773 }
2774 return false;
2775 }
2776 function hasPropsChanged(prevProps, nextProps, emitsOptions) {
2777 const nextKeys = Object.keys(nextProps);
2778 if (nextKeys.length !== Object.keys(prevProps).length) {
2779 return true;
2780 }
2781 for (let i = 0; i < nextKeys.length; i++) {
2782 const key = nextKeys[i];
2783 if (nextProps[key] !== prevProps[key] &&
2784 !isEmitListener(emitsOptions, key)) {
2785 return true;
2786 }
2787 }
2788 return false;
2789 }
2790 function updateHOCHostEl({ vnode, parent }, el // HostNode
2791 ) {
2792 while (parent && parent.subTree === vnode) {
2793 (vnode = parent.vnode).el = el;
2794 parent = parent.parent;
2795 }
2796 }
2797
2798 const isSuspense = (type) => type.__isSuspense;
2799 // Suspense exposes a component-like API, and is treated like a component
2800 // in the compiler, but internally it's a special built-in type that hooks
2801 // directly into the renderer.
2802 const SuspenseImpl = {
2803 name: 'Suspense',
2804 // In order to make Suspense tree-shakable, we need to avoid importing it
2805 // directly in the renderer. The renderer checks for the __isSuspense flag
2806 // on a vnode's type and calls the `process` method, passing in renderer
2807 // internals.
2808 __isSuspense: true,
2809 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
2810 // platform-specific impl passed from renderer
2811 rendererInternals) {
2812 if (n1 == null) {
2813 mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
2814 }
2815 else {
2816 patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
2817 }
2818 },
2819 hydrate: hydrateSuspense,
2820 create: createSuspenseBoundary,
2821 normalize: normalizeSuspenseChildren
2822 };
2823 // Force-casted public typing for h and TSX props inference
2824 const Suspense = (SuspenseImpl
2825 );
2826 function triggerEvent(vnode, name) {
2827 const eventListener = vnode.props && vnode.props[name];
2828 if (isFunction(eventListener)) {
2829 eventListener();
2830 }
2831 }
2832 function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
2833 const { p: patch, o: { createElement } } = rendererInternals;
2834 const hiddenContainer = createElement('div');
2835 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
2836 // start mounting the content subtree in an off-dom container
2837 patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
2838 // now check if we have encountered any async deps
2839 if (suspense.deps > 0) {
2840 // has async
2841 // invoke @fallback event
2842 triggerEvent(vnode, 'onPending');
2843 triggerEvent(vnode, 'onFallback');
2844 // mount the fallback tree
2845 patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2846 isSVG, slotScopeIds);
2847 setActiveBranch(suspense, vnode.ssFallback);
2848 }
2849 else {
2850 // Suspense has no async deps. Just resolve.
2851 suspense.resolve();
2852 }
2853 }
2854 function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
2855 const suspense = (n2.suspense = n1.suspense);
2856 suspense.vnode = n2;
2857 n2.el = n1.el;
2858 const newBranch = n2.ssContent;
2859 const newFallback = n2.ssFallback;
2860 const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
2861 if (pendingBranch) {
2862 suspense.pendingBranch = newBranch;
2863 if (isSameVNodeType(newBranch, pendingBranch)) {
2864 // same root type but content may have changed.
2865 patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2866 if (suspense.deps <= 0) {
2867 suspense.resolve();
2868 }
2869 else if (isInFallback) {
2870 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2871 isSVG, slotScopeIds, optimized);
2872 setActiveBranch(suspense, newFallback);
2873 }
2874 }
2875 else {
2876 // toggled before pending tree is resolved
2877 suspense.pendingId++;
2878 if (isHydrating) {
2879 // if toggled before hydration is finished, the current DOM tree is
2880 // no longer valid. set it as the active branch so it will be unmounted
2881 // when resolved
2882 suspense.isHydrating = false;
2883 suspense.activeBranch = pendingBranch;
2884 }
2885 else {
2886 unmount(pendingBranch, parentComponent, suspense);
2887 }
2888 // increment pending ID. this is used to invalidate async callbacks
2889 // reset suspense state
2890 suspense.deps = 0;
2891 // discard effects from pending branch
2892 suspense.effects.length = 0;
2893 // discard previous container
2894 suspense.hiddenContainer = createElement('div');
2895 if (isInFallback) {
2896 // already in fallback state
2897 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2898 if (suspense.deps <= 0) {
2899 suspense.resolve();
2900 }
2901 else {
2902 patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
2903 isSVG, slotScopeIds, optimized);
2904 setActiveBranch(suspense, newFallback);
2905 }
2906 }
2907 else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2908 // toggled "back" to current active branch
2909 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2910 // force resolve
2911 suspense.resolve(true);
2912 }
2913 else {
2914 // switched to a 3rd branch
2915 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2916 if (suspense.deps <= 0) {
2917 suspense.resolve();
2918 }
2919 }
2920 }
2921 }
2922 else {
2923 if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
2924 // root did not change, just normal patch
2925 patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2926 setActiveBranch(suspense, newBranch);
2927 }
2928 else {
2929 // root node toggled
2930 // invoke @pending event
2931 triggerEvent(n2, 'onPending');
2932 // mount pending branch in off-dom container
2933 suspense.pendingBranch = newBranch;
2934 suspense.pendingId++;
2935 patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
2936 if (suspense.deps <= 0) {
2937 // incoming branch has no async deps, resolve now.
2938 suspense.resolve();
2939 }
2940 else {
2941 const { timeout, pendingId } = suspense;
2942 if (timeout > 0) {
2943 setTimeout(() => {
2944 if (suspense.pendingId === pendingId) {
2945 suspense.fallback(newFallback);
2946 }
2947 }, timeout);
2948 }
2949 else if (timeout === 0) {
2950 suspense.fallback(newFallback);
2951 }
2952 }
2953 }
2954 }
2955 }
2956 let hasWarned = false;
2957 function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
2958 /* istanbul ignore if */
2959 if (!hasWarned) {
2960 hasWarned = true;
2961 // @ts-ignore `console.info` cannot be null error
2962 console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
2963 }
2964 const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
2965 const timeout = vnode.props ? toNumber(vnode.props.timeout) : undefined;
2966 {
2967 assertNumber(timeout, `Suspense timeout`);
2968 }
2969 const suspense = {
2970 vnode,
2971 parent,
2972 parentComponent,
2973 isSVG,
2974 container,
2975 hiddenContainer,
2976 anchor,
2977 deps: 0,
2978 pendingId: 0,
2979 timeout: typeof timeout === 'number' ? timeout : -1,
2980 activeBranch: null,
2981 pendingBranch: null,
2982 isInFallback: true,
2983 isHydrating,
2984 isUnmounted: false,
2985 effects: [],
2986 resolve(resume = false) {
2987 {
2988 if (!resume && !suspense.pendingBranch) {
2989 throw new Error(`suspense.resolve() is called without a pending branch.`);
2990 }
2991 if (suspense.isUnmounted) {
2992 throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
2993 }
2994 }
2995 const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
2996 if (suspense.isHydrating) {
2997 suspense.isHydrating = false;
2998 }
2999 else if (!resume) {
3000 const delayEnter = activeBranch &&
3001 pendingBranch.transition &&
3002 pendingBranch.transition.mode === 'out-in';
3003 if (delayEnter) {
3004 activeBranch.transition.afterLeave = () => {
3005 if (pendingId === suspense.pendingId) {
3006 move(pendingBranch, container, anchor, 0 /* MoveType.ENTER */);
3007 }
3008 };
3009 }
3010 // this is initial anchor on mount
3011 let { anchor } = suspense;
3012 // unmount current active tree
3013 if (activeBranch) {
3014 // if the fallback tree was mounted, it may have been moved
3015 // as part of a parent suspense. get the latest anchor for insertion
3016 anchor = next(activeBranch);
3017 unmount(activeBranch, parentComponent, suspense, true);
3018 }
3019 if (!delayEnter) {
3020 // move content from off-dom container to actual container
3021 move(pendingBranch, container, anchor, 0 /* MoveType.ENTER */);
3022 }
3023 }
3024 setActiveBranch(suspense, pendingBranch);
3025 suspense.pendingBranch = null;
3026 suspense.isInFallback = false;
3027 // flush buffered effects
3028 // check if there is a pending parent suspense
3029 let parent = suspense.parent;
3030 let hasUnresolvedAncestor = false;
3031 while (parent) {
3032 if (parent.pendingBranch) {
3033 // found a pending parent suspense, merge buffered post jobs
3034 // into that parent
3035 parent.effects.push(...effects);
3036 hasUnresolvedAncestor = true;
3037 break;
3038 }
3039 parent = parent.parent;
3040 }
3041 // no pending parent suspense, flush all jobs
3042 if (!hasUnresolvedAncestor) {
3043 queuePostFlushCb(effects);
3044 }
3045 suspense.effects = [];
3046 // invoke @resolve event
3047 triggerEvent(vnode, 'onResolve');
3048 },
3049 fallback(fallbackVNode) {
3050 if (!suspense.pendingBranch) {
3051 return;
3052 }
3053 const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
3054 // invoke @fallback event
3055 triggerEvent(vnode, 'onFallback');
3056 const anchor = next(activeBranch);
3057 const mountFallback = () => {
3058 if (!suspense.isInFallback) {
3059 return;
3060 }
3061 // mount the fallback tree
3062 patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
3063 isSVG, slotScopeIds, optimized);
3064 setActiveBranch(suspense, fallbackVNode);
3065 };
3066 const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
3067 if (delayEnter) {
3068 activeBranch.transition.afterLeave = mountFallback;
3069 }
3070 suspense.isInFallback = true;
3071 // unmount current active branch
3072 unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
3073 true // shouldRemove
3074 );
3075 if (!delayEnter) {
3076 mountFallback();
3077 }
3078 },
3079 move(container, anchor, type) {
3080 suspense.activeBranch &&
3081 move(suspense.activeBranch, container, anchor, type);
3082 suspense.container = container;
3083 },
3084 next() {
3085 return suspense.activeBranch && next(suspense.activeBranch);
3086 },
3087 registerDep(instance, setupRenderEffect) {
3088 const isInPendingSuspense = !!suspense.pendingBranch;
3089 if (isInPendingSuspense) {
3090 suspense.deps++;
3091 }
3092 const hydratedEl = instance.vnode.el;
3093 instance
3094 .asyncDep.catch(err => {
3095 handleError(err, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
3096 })
3097 .then(asyncSetupResult => {
3098 // retry when the setup() promise resolves.
3099 // component may have been unmounted before resolve.
3100 if (instance.isUnmounted ||
3101 suspense.isUnmounted ||
3102 suspense.pendingId !== instance.suspenseId) {
3103 return;
3104 }
3105 // retry from this component
3106 instance.asyncResolved = true;
3107 const { vnode } = instance;
3108 {
3109 pushWarningContext(vnode);
3110 }
3111 handleSetupResult(instance, asyncSetupResult, false);
3112 if (hydratedEl) {
3113 // vnode may have been replaced if an update happened before the
3114 // async dep is resolved.
3115 vnode.el = hydratedEl;
3116 }
3117 const placeholder = !hydratedEl && instance.subTree.el;
3118 setupRenderEffect(instance, vnode,
3119 // component may have been moved before resolve.
3120 // if this is not a hydration, instance.subTree will be the comment
3121 // placeholder.
3122 parentNode(hydratedEl || instance.subTree.el),
3123 // anchor will not be used if this is hydration, so only need to
3124 // consider the comment placeholder case.
3125 hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
3126 if (placeholder) {
3127 remove(placeholder);
3128 }
3129 updateHOCHostEl(instance, vnode.el);
3130 {
3131 popWarningContext();
3132 }
3133 // only decrease deps count if suspense is not already resolved
3134 if (isInPendingSuspense && --suspense.deps === 0) {
3135 suspense.resolve();
3136 }
3137 });
3138 },
3139 unmount(parentSuspense, doRemove) {
3140 suspense.isUnmounted = true;
3141 if (suspense.activeBranch) {
3142 unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
3143 }
3144 if (suspense.pendingBranch) {
3145 unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
3146 }
3147 }
3148 };
3149 return suspense;
3150 }
3151 function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
3152 /* eslint-disable no-restricted-globals */
3153 const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
3154 // there are two possible scenarios for server-rendered suspense:
3155 // - success: ssr content should be fully resolved
3156 // - failure: ssr content should be the fallback branch.
3157 // however, on the client we don't really know if it has failed or not
3158 // attempt to hydrate the DOM assuming it has succeeded, but we still
3159 // need to construct a suspense boundary first
3160 const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
3161 if (suspense.deps === 0) {
3162 suspense.resolve();
3163 }
3164 return result;
3165 /* eslint-enable no-restricted-globals */
3166 }
3167 function normalizeSuspenseChildren(vnode) {
3168 const { shapeFlag, children } = vnode;
3169 const isSlotChildren = shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */;
3170 vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
3171 vnode.ssFallback = isSlotChildren
3172 ? normalizeSuspenseSlot(children.fallback)
3173 : createVNode(Comment);
3174 }
3175 function normalizeSuspenseSlot(s) {
3176 let block;
3177 if (isFunction(s)) {
3178 const trackBlock = isBlockTreeEnabled && s._c;
3179 if (trackBlock) {
3180 // disableTracking: false
3181 // allow block tracking for compiled slots
3182 // (see ./componentRenderContext.ts)
3183 s._d = false;
3184 openBlock();
3185 }
3186 s = s();
3187 if (trackBlock) {
3188 s._d = true;
3189 block = currentBlock;
3190 closeBlock();
3191 }
3192 }
3193 if (isArray(s)) {
3194 const singleChild = filterSingleRoot(s);
3195 if (!singleChild) {
3196 warn(`<Suspense> slots expect a single root node.`);
3197 }
3198 s = singleChild;
3199 }
3200 s = normalizeVNode(s);
3201 if (block && !s.dynamicChildren) {
3202 s.dynamicChildren = block.filter(c => c !== s);
3203 }
3204 return s;
3205 }
3206 function queueEffectWithSuspense(fn, suspense) {
3207 if (suspense && suspense.pendingBranch) {
3208 if (isArray(fn)) {
3209 suspense.effects.push(...fn);
3210 }
3211 else {
3212 suspense.effects.push(fn);
3213 }
3214 }
3215 else {
3216 queuePostFlushCb(fn);
3217 }
3218 }
3219 function setActiveBranch(suspense, branch) {
3220 suspense.activeBranch = branch;
3221 const { vnode, parentComponent } = suspense;
3222 const el = (vnode.el = branch.el);
3223 // in case suspense is the root node of a component,
3224 // recursively update the HOC el
3225 if (parentComponent && parentComponent.subTree === vnode) {
3226 parentComponent.vnode.el = el;
3227 updateHOCHostEl(parentComponent, el);
3228 }
3229 }
3230
3231 function provide(key, value) {
3232 if (!currentInstance) {
3233 {
3234 warn(`provide() can only be used inside setup().`);
3235 }
3236 }
3237 else {
3238 let provides = currentInstance.provides;
3239 // by default an instance inherits its parent's provides object
3240 // but when it needs to provide values of its own, it creates its
3241 // own provides object using parent provides object as prototype.
3242 // this way in `inject` we can simply look up injections from direct
3243 // parent and let the prototype chain do the work.
3244 const parentProvides = currentInstance.parent && currentInstance.parent.provides;
3245 if (parentProvides === provides) {
3246 provides = currentInstance.provides = Object.create(parentProvides);
3247 }
3248 // TS doesn't allow symbol as index type
3249 provides[key] = value;
3250 }
3251 }
3252 function inject(key, defaultValue, treatDefaultAsFactory = false) {
3253 // fallback to `currentRenderingInstance` so that this can be called in
3254 // a functional component
3255 const instance = currentInstance || currentRenderingInstance;
3256 if (instance) {
3257 // #2400
3258 // to support `app.use` plugins,
3259 // fallback to appContext's `provides` if the instance is at root
3260 const provides = instance.parent == null
3261 ? instance.vnode.appContext && instance.vnode.appContext.provides
3262 : instance.parent.provides;
3263 if (provides && key in provides) {
3264 // TS doesn't allow symbol as index type
3265 return provides[key];
3266 }
3267 else if (arguments.length > 1) {
3268 return treatDefaultAsFactory && isFunction(defaultValue)
3269 ? defaultValue.call(instance.proxy)
3270 : defaultValue;
3271 }
3272 else {
3273 warn(`injection "${String(key)}" not found.`);
3274 }
3275 }
3276 else {
3277 warn(`inject() can only be used inside setup() or functional components.`);
3278 }
3279 }
3280
3281 // Simple effect.
3282 function watchEffect(effect, options) {
3283 return doWatch(effect, null, options);
3284 }
3285 function watchPostEffect(effect, options) {
3286 return doWatch(effect, null, Object.assign(Object.assign({}, options), { flush: 'post' }) );
3287 }
3288 function watchSyncEffect(effect, options) {
3289 return doWatch(effect, null, Object.assign(Object.assign({}, options), { flush: 'sync' }) );
3290 }
3291 // initial value for watchers to trigger on undefined initial values
3292 const INITIAL_WATCHER_VALUE = {};
3293 // implementation
3294 function watch(source, cb, options) {
3295 if (!isFunction(cb)) {
3296 warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
3297 `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
3298 `supports \`watch(source, cb, options?) signature.`);
3299 }
3300 return doWatch(source, cb, options);
3301 }
3302 function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
3303 if (!cb) {
3304 if (immediate !== undefined) {
3305 warn(`watch() "immediate" option is only respected when using the ` +
3306 `watch(source, callback, options?) signature.`);
3307 }
3308 if (deep !== undefined) {
3309 warn(`watch() "deep" option is only respected when using the ` +
3310 `watch(source, callback, options?) signature.`);
3311 }
3312 }
3313 const warnInvalidSource = (s) => {
3314 warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
3315 `a reactive object, or an array of these types.`);
3316 };
3317 const instance = getCurrentScope() === (currentInstance === null || currentInstance === void 0 ? void 0 : currentInstance.scope) ? currentInstance : null;
3318 // const instance = currentInstance
3319 let getter;
3320 let forceTrigger = false;
3321 let isMultiSource = false;
3322 if (isRef(source)) {
3323 getter = () => source.value;
3324 forceTrigger = isShallow(source);
3325 }
3326 else if (isReactive(source)) {
3327 getter = () => source;
3328 deep = true;
3329 }
3330 else if (isArray(source)) {
3331 isMultiSource = true;
3332 forceTrigger = source.some(s => isReactive(s) || isShallow(s));
3333 getter = () => source.map(s => {
3334 if (isRef(s)) {
3335 return s.value;
3336 }
3337 else if (isReactive(s)) {
3338 return traverse(s);
3339 }
3340 else if (isFunction(s)) {
3341 return callWithErrorHandling(s, instance, 2 /* ErrorCodes.WATCH_GETTER */);
3342 }
3343 else {
3344 warnInvalidSource(s);
3345 }
3346 });
3347 }
3348 else if (isFunction(source)) {
3349 if (cb) {
3350 // getter with cb
3351 getter = () => callWithErrorHandling(source, instance, 2 /* ErrorCodes.WATCH_GETTER */);
3352 }
3353 else {
3354 // no cb -> simple effect
3355 getter = () => {
3356 if (instance && instance.isUnmounted) {
3357 return;
3358 }
3359 if (cleanup) {
3360 cleanup();
3361 }
3362 return callWithAsyncErrorHandling(source, instance, 3 /* ErrorCodes.WATCH_CALLBACK */, [onCleanup]);
3363 };
3364 }
3365 }
3366 else {
3367 getter = NOOP;
3368 warnInvalidSource(source);
3369 }
3370 if (cb && deep) {
3371 const baseGetter = getter;
3372 getter = () => traverse(baseGetter());
3373 }
3374 let cleanup;
3375 let onCleanup = (fn) => {
3376 cleanup = effect.onStop = () => {
3377 callWithErrorHandling(fn, instance, 4 /* ErrorCodes.WATCH_CLEANUP */);
3378 };
3379 };
3380 let oldValue = isMultiSource
3381 ? new Array(source.length).fill(INITIAL_WATCHER_VALUE)
3382 : INITIAL_WATCHER_VALUE;
3383 const job = () => {
3384 if (!effect.active) {
3385 return;
3386 }
3387 if (cb) {
3388 // watch(source, cb)
3389 const newValue = effect.run();
3390 if (deep ||
3391 forceTrigger ||
3392 (isMultiSource
3393 ? newValue.some((v, i) => hasChanged(v, oldValue[i]))
3394 : hasChanged(newValue, oldValue)) ||
3395 (false )) {
3396 // cleanup before running cb again
3397 if (cleanup) {
3398 cleanup();
3399 }
3400 callWithAsyncErrorHandling(cb, instance, 3 /* ErrorCodes.WATCH_CALLBACK */, [
3401 newValue,
3402 // pass undefined as the old value when it's changed for the first time
3403 oldValue === INITIAL_WATCHER_VALUE
3404 ? undefined
3405 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE
3406 ? []
3407 : oldValue,
3408 onCleanup
3409 ]);
3410 oldValue = newValue;
3411 }
3412 }
3413 else {
3414 // watchEffect
3415 effect.run();
3416 }
3417 };
3418 // important: mark the job as a watcher callback so that scheduler knows
3419 // it is allowed to self-trigger (#1727)
3420 job.allowRecurse = !!cb;
3421 let scheduler;
3422 if (flush === 'sync') {
3423 scheduler = job; // the scheduler function gets called directly
3424 }
3425 else if (flush === 'post') {
3426 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
3427 }
3428 else {
3429 // default: 'pre'
3430 job.pre = true;
3431 if (instance)
3432 job.id = instance.uid;
3433 scheduler = () => queueJob(job);
3434 }
3435 const effect = new ReactiveEffect(getter, scheduler);
3436 {
3437 effect.onTrack = onTrack;
3438 effect.onTrigger = onTrigger;
3439 }
3440 // initial run
3441 if (cb) {
3442 if (immediate) {
3443 job();
3444 }
3445 else {
3446 oldValue = effect.run();
3447 }
3448 }
3449 else if (flush === 'post') {
3450 queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
3451 }
3452 else {
3453 effect.run();
3454 }
3455 const unwatch = () => {
3456 effect.stop();
3457 if (instance && instance.scope) {
3458 remove(instance.scope.effects, effect);
3459 }
3460 };
3461 return unwatch;
3462 }
3463 // this.$watch
3464 function instanceWatch(source, value, options) {
3465 const publicThis = this.proxy;
3466 const getter = isString(source)
3467 ? source.includes('.')
3468 ? createPathGetter(publicThis, source)
3469 : () => publicThis[source]
3470 : source.bind(publicThis, publicThis);
3471 let cb;
3472 if (isFunction(value)) {
3473 cb = value;
3474 }
3475 else {
3476 cb = value.handler;
3477 options = value;
3478 }
3479 const cur = currentInstance;
3480 setCurrentInstance(this);
3481 const res = doWatch(getter, cb.bind(publicThis), options);
3482 if (cur) {
3483 setCurrentInstance(cur);
3484 }
3485 else {
3486 unsetCurrentInstance();
3487 }
3488 return res;
3489 }
3490 function createPathGetter(ctx, path) {
3491 const segments = path.split('.');
3492 return () => {
3493 let cur = ctx;
3494 for (let i = 0; i < segments.length && cur; i++) {
3495 cur = cur[segments[i]];
3496 }
3497 return cur;
3498 };
3499 }
3500 function traverse(value, seen) {
3501 if (!isObject(value) || value["__v_skip" /* ReactiveFlags.SKIP */]) {
3502 return value;
3503 }
3504 seen = seen || new Set();
3505 if (seen.has(value)) {
3506 return value;
3507 }
3508 seen.add(value);
3509 if (isRef(value)) {
3510 traverse(value.value, seen);
3511 }
3512 else if (isArray(value)) {
3513 for (let i = 0; i < value.length; i++) {
3514 traverse(value[i], seen);
3515 }
3516 }
3517 else if (isSet(value) || isMap(value)) {
3518 value.forEach((v) => {
3519 traverse(v, seen);
3520 });
3521 }
3522 else if (isPlainObject(value)) {
3523 for (const key in value) {
3524 traverse(value[key], seen);
3525 }
3526 }
3527 return value;
3528 }
3529
3530 function useTransitionState() {
3531 const state = {
3532 isMounted: false,
3533 isLeaving: false,
3534 isUnmounting: false,
3535 leavingVNodes: new Map()
3536 };
3537 onMounted(() => {
3538 state.isMounted = true;
3539 });
3540 onBeforeUnmount(() => {
3541 state.isUnmounting = true;
3542 });
3543 return state;
3544 }
3545 const TransitionHookValidator = [Function, Array];
3546 const BaseTransitionImpl = {
3547 name: `BaseTransition`,
3548 props: {
3549 mode: String,
3550 appear: Boolean,
3551 persisted: Boolean,
3552 // enter
3553 onBeforeEnter: TransitionHookValidator,
3554 onEnter: TransitionHookValidator,
3555 onAfterEnter: TransitionHookValidator,
3556 onEnterCancelled: TransitionHookValidator,
3557 // leave
3558 onBeforeLeave: TransitionHookValidator,
3559 onLeave: TransitionHookValidator,
3560 onAfterLeave: TransitionHookValidator,
3561 onLeaveCancelled: TransitionHookValidator,
3562 // appear
3563 onBeforeAppear: TransitionHookValidator,
3564 onAppear: TransitionHookValidator,
3565 onAfterAppear: TransitionHookValidator,
3566 onAppearCancelled: TransitionHookValidator
3567 },
3568 setup(props, { slots }) {
3569 const instance = getCurrentInstance();
3570 const state = useTransitionState();
3571 let prevTransitionKey;
3572 return () => {
3573 const children = slots.default && getTransitionRawChildren(slots.default(), true);
3574 if (!children || !children.length) {
3575 return;
3576 }
3577 let child = children[0];
3578 if (children.length > 1) {
3579 let hasFound = false;
3580 // locate first non-comment child
3581 for (const c of children) {
3582 if (c.type !== Comment) {
3583 if (hasFound) {
3584 // warn more than one non-comment child
3585 warn('<transition> can only be used on a single element or component. ' +
3586 'Use <transition-group> for lists.');
3587 break;
3588 }
3589 child = c;
3590 hasFound = true;
3591 }
3592 }
3593 }
3594 // there's no need to track reactivity for these props so use the raw
3595 // props for a bit better perf
3596 const rawProps = toRaw(props);
3597 const { mode } = rawProps;
3598 // check mode
3599 if (mode &&
3600 mode !== 'in-out' &&
3601 mode !== 'out-in' &&
3602 mode !== 'default') {
3603 warn(`invalid <transition> mode: ${mode}`);
3604 }
3605 if (state.isLeaving) {
3606 return emptyPlaceholder(child);
3607 }
3608 // in the case of <transition><keep-alive/></transition>, we need to
3609 // compare the type of the kept-alive children.
3610 const innerChild = getKeepAliveChild(child);
3611 if (!innerChild) {
3612 return emptyPlaceholder(child);
3613 }
3614 const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
3615 setTransitionHooks(innerChild, enterHooks);
3616 const oldChild = instance.subTree;
3617 const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
3618 let transitionKeyChanged = false;
3619 const { getTransitionKey } = innerChild.type;
3620 if (getTransitionKey) {
3621 const key = getTransitionKey();
3622 if (prevTransitionKey === undefined) {
3623 prevTransitionKey = key;
3624 }
3625 else if (key !== prevTransitionKey) {
3626 prevTransitionKey = key;
3627 transitionKeyChanged = true;
3628 }
3629 }
3630 // handle mode
3631 if (oldInnerChild &&
3632 oldInnerChild.type !== Comment &&
3633 (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
3634 const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
3635 // update old tree's hooks in case of dynamic transition
3636 setTransitionHooks(oldInnerChild, leavingHooks);
3637 // switching between different views
3638 if (mode === 'out-in') {
3639 state.isLeaving = true;
3640 // return placeholder node and queue update when leave finishes
3641 leavingHooks.afterLeave = () => {
3642 state.isLeaving = false;
3643 // #6835
3644 // it also needs to be updated when active is undefined
3645 if (instance.update.active !== false) {
3646 instance.update();
3647 }
3648 };
3649 return emptyPlaceholder(child);
3650 }
3651 else if (mode === 'in-out' && innerChild.type !== Comment) {
3652 leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
3653 const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
3654 leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
3655 // early removal callback
3656 el._leaveCb = () => {
3657 earlyRemove();
3658 el._leaveCb = undefined;
3659 delete enterHooks.delayedLeave;
3660 };
3661 enterHooks.delayedLeave = delayedLeave;
3662 };
3663 }
3664 }
3665 return child;
3666 };
3667 }
3668 };
3669 // export the public type for h/tsx inference
3670 // also to avoid inline import() in generated d.ts files
3671 const BaseTransition = BaseTransitionImpl;
3672 function getLeavingNodesForType(state, vnode) {
3673 const { leavingVNodes } = state;
3674 let leavingVNodesCache = leavingVNodes.get(vnode.type);
3675 if (!leavingVNodesCache) {
3676 leavingVNodesCache = Object.create(null);
3677 leavingVNodes.set(vnode.type, leavingVNodesCache);
3678 }
3679 return leavingVNodesCache;
3680 }
3681 // The transition hooks are attached to the vnode as vnode.transition
3682 // and will be called at appropriate timing in the renderer.
3683 function resolveTransitionHooks(vnode, props, state, instance) {
3684 const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
3685 const key = String(vnode.key);
3686 const leavingVNodesCache = getLeavingNodesForType(state, vnode);
3687 const callHook = (hook, args) => {
3688 hook &&
3689 callWithAsyncErrorHandling(hook, instance, 9 /* ErrorCodes.TRANSITION_HOOK */, args);
3690 };
3691 const callAsyncHook = (hook, args) => {
3692 const done = args[1];
3693 callHook(hook, args);
3694 if (isArray(hook)) {
3695 if (hook.every(hook => hook.length <= 1))
3696 done();
3697 }
3698 else if (hook.length <= 1) {
3699 done();
3700 }
3701 };
3702 const hooks = {
3703 mode,
3704 persisted,
3705 beforeEnter(el) {
3706 let hook = onBeforeEnter;
3707 if (!state.isMounted) {
3708 if (appear) {
3709 hook = onBeforeAppear || onBeforeEnter;
3710 }
3711 else {
3712 return;
3713 }
3714 }
3715 // for same element (v-show)
3716 if (el._leaveCb) {
3717 el._leaveCb(true /* cancelled */);
3718 }
3719 // for toggled element with same key (v-if)
3720 const leavingVNode = leavingVNodesCache[key];
3721 if (leavingVNode &&
3722 isSameVNodeType(vnode, leavingVNode) &&
3723 leavingVNode.el._leaveCb) {
3724 // force early removal (not cancelled)
3725 leavingVNode.el._leaveCb();
3726 }
3727 callHook(hook, [el]);
3728 },
3729 enter(el) {
3730 let hook = onEnter;
3731 let afterHook = onAfterEnter;
3732 let cancelHook = onEnterCancelled;
3733 if (!state.isMounted) {
3734 if (appear) {
3735 hook = onAppear || onEnter;
3736 afterHook = onAfterAppear || onAfterEnter;
3737 cancelHook = onAppearCancelled || onEnterCancelled;
3738 }
3739 else {
3740 return;
3741 }
3742 }
3743 let called = false;
3744 const done = (el._enterCb = (cancelled) => {
3745 if (called)
3746 return;
3747 called = true;
3748 if (cancelled) {
3749 callHook(cancelHook, [el]);
3750 }
3751 else {
3752 callHook(afterHook, [el]);
3753 }
3754 if (hooks.delayedLeave) {
3755 hooks.delayedLeave();
3756 }
3757 el._enterCb = undefined;
3758 });
3759 if (hook) {
3760 callAsyncHook(hook, [el, done]);
3761 }
3762 else {
3763 done();
3764 }
3765 },
3766 leave(el, remove) {
3767 const key = String(vnode.key);
3768 if (el._enterCb) {
3769 el._enterCb(true /* cancelled */);
3770 }
3771 if (state.isUnmounting) {
3772 return remove();
3773 }
3774 callHook(onBeforeLeave, [el]);
3775 let called = false;
3776 const done = (el._leaveCb = (cancelled) => {
3777 if (called)
3778 return;
3779 called = true;
3780 remove();
3781 if (cancelled) {
3782 callHook(onLeaveCancelled, [el]);
3783 }
3784 else {
3785 callHook(onAfterLeave, [el]);
3786 }
3787 el._leaveCb = undefined;
3788 if (leavingVNodesCache[key] === vnode) {
3789 delete leavingVNodesCache[key];
3790 }
3791 });
3792 leavingVNodesCache[key] = vnode;
3793 if (onLeave) {
3794 callAsyncHook(onLeave, [el, done]);
3795 }
3796 else {
3797 done();
3798 }
3799 },
3800 clone(vnode) {
3801 return resolveTransitionHooks(vnode, props, state, instance);
3802 }
3803 };
3804 return hooks;
3805 }
3806 // the placeholder really only handles one special case: KeepAlive
3807 // in the case of a KeepAlive in a leave phase we need to return a KeepAlive
3808 // placeholder with empty content to avoid the KeepAlive instance from being
3809 // unmounted.
3810 function emptyPlaceholder(vnode) {
3811 if (isKeepAlive(vnode)) {
3812 vnode = cloneVNode(vnode);
3813 vnode.children = null;
3814 return vnode;
3815 }
3816 }
3817 function getKeepAliveChild(vnode) {
3818 return isKeepAlive(vnode)
3819 ? vnode.children
3820 ? vnode.children[0]
3821 : undefined
3822 : vnode;
3823 }
3824 function setTransitionHooks(vnode, hooks) {
3825 if (vnode.shapeFlag & 6 /* ShapeFlags.COMPONENT */ && vnode.component) {
3826 setTransitionHooks(vnode.component.subTree, hooks);
3827 }
3828 else if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
3829 vnode.ssContent.transition = hooks.clone(vnode.ssContent);
3830 vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
3831 }
3832 else {
3833 vnode.transition = hooks;
3834 }
3835 }
3836 function getTransitionRawChildren(children, keepComment = false, parentKey) {
3837 let ret = [];
3838 let keyedFragmentCount = 0;
3839 for (let i = 0; i < children.length; i++) {
3840 let child = children[i];
3841 // #5360 inherit parent key in case of <template v-for>
3842 const key = parentKey == null
3843 ? child.key
3844 : String(parentKey) + String(child.key != null ? child.key : i);
3845 // handle fragment children case, e.g. v-for
3846 if (child.type === Fragment) {
3847 if (child.patchFlag & 128 /* PatchFlags.KEYED_FRAGMENT */)
3848 keyedFragmentCount++;
3849 ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key));
3850 }
3851 // comment placeholders should be skipped, e.g. v-if
3852 else if (keepComment || child.type !== Comment) {
3853 ret.push(key != null ? cloneVNode(child, { key }) : child);
3854 }
3855 }
3856 // #1126 if a transition children list contains multiple sub fragments, these
3857 // fragments will be merged into a flat children array. Since each v-for
3858 // fragment may contain different static bindings inside, we need to de-op
3859 // these children to force full diffs to ensure correct behavior.
3860 if (keyedFragmentCount > 1) {
3861 for (let i = 0; i < ret.length; i++) {
3862 ret[i].patchFlag = -2 /* PatchFlags.BAIL */;
3863 }
3864 }
3865 return ret;
3866 }
3867
3868 // implementation, close to no-op
3869 function defineComponent(options) {
3870 return isFunction(options) ? { setup: options, name: options.name } : options;
3871 }
3872
3873 const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
3874 function defineAsyncComponent(source) {
3875 if (isFunction(source)) {
3876 source = { loader: source };
3877 }
3878 const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
3879 suspensible = true, onError: userOnError } = source;
3880 let pendingRequest = null;
3881 let resolvedComp;
3882 let retries = 0;
3883 const retry = () => {
3884 retries++;
3885 pendingRequest = null;
3886 return load();
3887 };
3888 const load = () => {
3889 let thisRequest;
3890 return (pendingRequest ||
3891 (thisRequest = pendingRequest =
3892 loader()
3893 .catch(err => {
3894 err = err instanceof Error ? err : new Error(String(err));
3895 if (userOnError) {
3896 return new Promise((resolve, reject) => {
3897 const userRetry = () => resolve(retry());
3898 const userFail = () => reject(err);
3899 userOnError(err, userRetry, userFail, retries + 1);
3900 });
3901 }
3902 else {
3903 throw err;
3904 }
3905 })
3906 .then((comp) => {
3907 if (thisRequest !== pendingRequest && pendingRequest) {
3908 return pendingRequest;
3909 }
3910 if (!comp) {
3911 warn(`Async component loader resolved to undefined. ` +
3912 `If you are using retry(), make sure to return its return value.`);
3913 }
3914 // interop module default
3915 if (comp &&
3916 (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
3917 comp = comp.default;
3918 }
3919 if (comp && !isObject(comp) && !isFunction(comp)) {
3920 throw new Error(`Invalid async component load result: ${comp}`);
3921 }
3922 resolvedComp = comp;
3923 return comp;
3924 })));
3925 };
3926 return defineComponent({
3927 name: 'AsyncComponentWrapper',
3928 __asyncLoader: load,
3929 get __asyncResolved() {
3930 return resolvedComp;
3931 },
3932 setup() {
3933 const instance = currentInstance;
3934 // already resolved
3935 if (resolvedComp) {
3936 return () => createInnerComp(resolvedComp, instance);
3937 }
3938 const onError = (err) => {
3939 pendingRequest = null;
3940 handleError(err, instance, 13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
3941 };
3942 // suspense-controlled or SSR.
3943 if ((suspensible && instance.suspense) ||
3944 (false )) {
3945 return load()
3946 .then(comp => {
3947 return () => createInnerComp(comp, instance);
3948 })
3949 .catch(err => {
3950 onError(err);
3951 return () => errorComponent
3952 ? createVNode(errorComponent, {
3953 error: err
3954 })
3955 : null;
3956 });
3957 }
3958 const loaded = ref(false);
3959 const error = ref();
3960 const delayed = ref(!!delay);
3961 if (delay) {
3962 setTimeout(() => {
3963 delayed.value = false;
3964 }, delay);
3965 }
3966 if (timeout != null) {
3967 setTimeout(() => {
3968 if (!loaded.value && !error.value) {
3969 const err = new Error(`Async component timed out after ${timeout}ms.`);
3970 onError(err);
3971 error.value = err;
3972 }
3973 }, timeout);
3974 }
3975 load()
3976 .then(() => {
3977 loaded.value = true;
3978 if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3979 // parent is keep-alive, force update so the loaded component's
3980 // name is taken into account
3981 queueJob(instance.parent.update);
3982 }
3983 })
3984 .catch(err => {
3985 onError(err);
3986 error.value = err;
3987 });
3988 return () => {
3989 if (loaded.value && resolvedComp) {
3990 return createInnerComp(resolvedComp, instance);
3991 }
3992 else if (error.value && errorComponent) {
3993 return createVNode(errorComponent, {
3994 error: error.value
3995 });
3996 }
3997 else if (loadingComponent && !delayed.value) {
3998 return createVNode(loadingComponent);
3999 }
4000 };
4001 }
4002 });
4003 }
4004 function createInnerComp(comp, parent) {
4005 const { ref, props, children, ce } = parent.vnode;
4006 const vnode = createVNode(comp, props, children);
4007 // ensure inner component inherits the async wrapper's ref owner
4008 vnode.ref = ref;
4009 // pass the custom element callback on to the inner comp
4010 // and remove it from the async wrapper
4011 vnode.ce = ce;
4012 delete parent.vnode.ce;
4013 return vnode;
4014 }
4015
4016 const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
4017 const KeepAliveImpl = {
4018 name: `KeepAlive`,
4019 // Marker for special handling inside the renderer. We are not using a ===
4020 // check directly on KeepAlive in the renderer, because importing it directly
4021 // would prevent it from being tree-shaken.
4022 __isKeepAlive: true,
4023 props: {
4024 include: [String, RegExp, Array],
4025 exclude: [String, RegExp, Array],
4026 max: [String, Number]
4027 },
4028 setup(props, { slots }) {
4029 const instance = getCurrentInstance();
4030 // KeepAlive communicates with the instantiated renderer via the
4031 // ctx where the renderer passes in its internals,
4032 // and the KeepAlive instance exposes activate/deactivate implementations.
4033 // The whole point of this is to avoid importing KeepAlive directly in the
4034 // renderer to facilitate tree-shaking.
4035 const sharedContext = instance.ctx;
4036 const cache = new Map();
4037 const keys = new Set();
4038 let current = null;
4039 {
4040 instance.__v_cache = cache;
4041 }
4042 const parentSuspense = instance.suspense;
4043 const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
4044 const storageContainer = createElement('div');
4045 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
4046 const instance = vnode.component;
4047 move(vnode, container, anchor, 0 /* MoveType.ENTER */, parentSuspense);
4048 // in case props have changed
4049 patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
4050 queuePostRenderEffect(() => {
4051 instance.isDeactivated = false;
4052 if (instance.a) {
4053 invokeArrayFns(instance.a);
4054 }
4055 const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
4056 if (vnodeHook) {
4057 invokeVNodeHook(vnodeHook, instance.parent, vnode);
4058 }
4059 }, parentSuspense);
4060 {
4061 // Update components tree
4062 devtoolsComponentAdded(instance);
4063 }
4064 };
4065 sharedContext.deactivate = (vnode) => {
4066 const instance = vnode.component;
4067 move(vnode, storageContainer, null, 1 /* MoveType.LEAVE */, parentSuspense);
4068 queuePostRenderEffect(() => {
4069 if (instance.da) {
4070 invokeArrayFns(instance.da);
4071 }
4072 const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
4073 if (vnodeHook) {
4074 invokeVNodeHook(vnodeHook, instance.parent, vnode);
4075 }
4076 instance.isDeactivated = true;
4077 }, parentSuspense);
4078 {
4079 // Update components tree
4080 devtoolsComponentAdded(instance);
4081 }
4082 };
4083 function unmount(vnode) {
4084 // reset the shapeFlag so it can be properly unmounted
4085 resetShapeFlag(vnode);
4086 _unmount(vnode, instance, parentSuspense, true);
4087 }
4088 function pruneCache(filter) {
4089 cache.forEach((vnode, key) => {
4090 const name = getComponentName(vnode.type);
4091 if (name && (!filter || !filter(name))) {
4092 pruneCacheEntry(key);
4093 }
4094 });
4095 }
4096 function pruneCacheEntry(key) {
4097 const cached = cache.get(key);
4098 if (!current || !isSameVNodeType(cached, current)) {
4099 unmount(cached);
4100 }
4101 else if (current) {
4102 // current active instance should no longer be kept-alive.
4103 // we can't unmount it now but it might be later, so reset its flag now.
4104 resetShapeFlag(current);
4105 }
4106 cache.delete(key);
4107 keys.delete(key);
4108 }
4109 // prune cache on include/exclude prop change
4110 watch(() => [props.include, props.exclude], ([include, exclude]) => {
4111 include && pruneCache(name => matches(include, name));
4112 exclude && pruneCache(name => !matches(exclude, name));
4113 },
4114 // prune post-render after `current` has been updated
4115 { flush: 'post', deep: true });
4116 // cache sub tree after render
4117 let pendingCacheKey = null;
4118 const cacheSubtree = () => {
4119 // fix #1621, the pendingCacheKey could be 0
4120 if (pendingCacheKey != null) {
4121 cache.set(pendingCacheKey, getInnerChild(instance.subTree));
4122 }
4123 };
4124 onMounted(cacheSubtree);
4125 onUpdated(cacheSubtree);
4126 onBeforeUnmount(() => {
4127 cache.forEach(cached => {
4128 const { subTree, suspense } = instance;
4129 const vnode = getInnerChild(subTree);
4130 if (cached.type === vnode.type && cached.key === vnode.key) {
4131 // current instance will be unmounted as part of keep-alive's unmount
4132 resetShapeFlag(vnode);
4133 // but invoke its deactivated hook here
4134 const da = vnode.component.da;
4135 da && queuePostRenderEffect(da, suspense);
4136 return;
4137 }
4138 unmount(cached);
4139 });
4140 });
4141 return () => {
4142 pendingCacheKey = null;
4143 if (!slots.default) {
4144 return null;
4145 }
4146 const children = slots.default();
4147 const rawVNode = children[0];
4148 if (children.length > 1) {
4149 {
4150 warn(`KeepAlive should contain exactly one component child.`);
4151 }
4152 current = null;
4153 return children;
4154 }
4155 else if (!isVNode(rawVNode) ||
4156 (!(rawVNode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */) &&
4157 !(rawVNode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */))) {
4158 current = null;
4159 return rawVNode;
4160 }
4161 let vnode = getInnerChild(rawVNode);
4162 const comp = vnode.type;
4163 // for async components, name check should be based in its loaded
4164 // inner component if available
4165 const name = getComponentName(isAsyncWrapper(vnode)
4166 ? vnode.type.__asyncResolved || {}
4167 : comp);
4168 const { include, exclude, max } = props;
4169 if ((include && (!name || !matches(include, name))) ||
4170 (exclude && name && matches(exclude, name))) {
4171 current = vnode;
4172 return rawVNode;
4173 }
4174 const key = vnode.key == null ? comp : vnode.key;
4175 const cachedVNode = cache.get(key);
4176 // clone vnode if it's reused because we are going to mutate it
4177 if (vnode.el) {
4178 vnode = cloneVNode(vnode);
4179 if (rawVNode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
4180 rawVNode.ssContent = vnode;
4181 }
4182 }
4183 // #1513 it's possible for the returned vnode to be cloned due to attr
4184 // fallthrough or scopeId, so the vnode here may not be the final vnode
4185 // that is mounted. Instead of caching it directly, we store the pending
4186 // key and cache `instance.subTree` (the normalized vnode) in
4187 // beforeMount/beforeUpdate hooks.
4188 pendingCacheKey = key;
4189 if (cachedVNode) {
4190 // copy over mounted state
4191 vnode.el = cachedVNode.el;
4192 vnode.component = cachedVNode.component;
4193 if (vnode.transition) {
4194 // recursively update transition hooks on subTree
4195 setTransitionHooks(vnode, vnode.transition);
4196 }
4197 // avoid vnode being mounted as fresh
4198 vnode.shapeFlag |= 512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */;
4199 // make this key the freshest
4200 keys.delete(key);
4201 keys.add(key);
4202 }
4203 else {
4204 keys.add(key);
4205 // prune oldest entry
4206 if (max && keys.size > parseInt(max, 10)) {
4207 pruneCacheEntry(keys.values().next().value);
4208 }
4209 }
4210 // avoid vnode being unmounted
4211 vnode.shapeFlag |= 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */;
4212 current = vnode;
4213 return isSuspense(rawVNode.type) ? rawVNode : vnode;
4214 };
4215 }
4216 };
4217 // export the public type for h/tsx inference
4218 // also to avoid inline import() in generated d.ts files
4219 const KeepAlive = KeepAliveImpl;
4220 function matches(pattern, name) {
4221 if (isArray(pattern)) {
4222 return pattern.some((p) => matches(p, name));
4223 }
4224 else if (isString(pattern)) {
4225 return pattern.split(',').includes(name);
4226 }
4227 else if (isRegExp(pattern)) {
4228 return pattern.test(name);
4229 }
4230 /* istanbul ignore next */
4231 return false;
4232 }
4233 function onActivated(hook, target) {
4234 registerKeepAliveHook(hook, "a" /* LifecycleHooks.ACTIVATED */, target);
4235 }
4236 function onDeactivated(hook, target) {
4237 registerKeepAliveHook(hook, "da" /* LifecycleHooks.DEACTIVATED */, target);
4238 }
4239 function registerKeepAliveHook(hook, type, target = currentInstance) {
4240 // cache the deactivate branch check wrapper for injected hooks so the same
4241 // hook can be properly deduped by the scheduler. "__wdc" stands for "with
4242 // deactivation check".
4243 const wrappedHook = hook.__wdc ||
4244 (hook.__wdc = () => {
4245 // only fire the hook if the target instance is NOT in a deactivated branch.
4246 let current = target;
4247 while (current) {
4248 if (current.isDeactivated) {
4249 return;
4250 }
4251 current = current.parent;
4252 }
4253 return hook();
4254 });
4255 injectHook(type, wrappedHook, target);
4256 // In addition to registering it on the target instance, we walk up the parent
4257 // chain and register it on all ancestor instances that are keep-alive roots.
4258 // This avoids the need to walk the entire component tree when invoking these
4259 // hooks, and more importantly, avoids the need to track child components in
4260 // arrays.
4261 if (target) {
4262 let current = target.parent;
4263 while (current && current.parent) {
4264 if (isKeepAlive(current.parent.vnode)) {
4265 injectToKeepAliveRoot(wrappedHook, type, target, current);
4266 }
4267 current = current.parent;
4268 }
4269 }
4270 }
4271 function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
4272 // injectHook wraps the original for error handling, so make sure to remove
4273 // the wrapped version.
4274 const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
4275 onUnmounted(() => {
4276 remove(keepAliveRoot[type], injected);
4277 }, target);
4278 }
4279 function resetShapeFlag(vnode) {
4280 // bitwise operations to remove keep alive flags
4281 vnode.shapeFlag &= ~256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */;
4282 vnode.shapeFlag &= ~512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */;
4283 }
4284 function getInnerChild(vnode) {
4285 return vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */ ? vnode.ssContent : vnode;
4286 }
4287
4288 function injectHook(type, hook, target = currentInstance, prepend = false) {
4289 if (target) {
4290 const hooks = target[type] || (target[type] = []);
4291 // cache the error handling wrapper for injected hooks so the same hook
4292 // can be properly deduped by the scheduler. "__weh" stands for "with error
4293 // handling".
4294 const wrappedHook = hook.__weh ||
4295 (hook.__weh = (...args) => {
4296 if (target.isUnmounted) {
4297 return;
4298 }
4299 // disable tracking inside all lifecycle hooks
4300 // since they can potentially be called inside effects.
4301 pauseTracking();
4302 // Set currentInstance during hook invocation.
4303 // This assumes the hook does not synchronously trigger other hooks, which
4304 // can only be false when the user does something really funky.
4305 setCurrentInstance(target);
4306 const res = callWithAsyncErrorHandling(hook, target, type, args);
4307 unsetCurrentInstance();
4308 resetTracking();
4309 return res;
4310 });
4311 if (prepend) {
4312 hooks.unshift(wrappedHook);
4313 }
4314 else {
4315 hooks.push(wrappedHook);
4316 }
4317 return wrappedHook;
4318 }
4319 else {
4320 const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
4321 warn(`${apiName} is called when there is no active component instance to be ` +
4322 `associated with. ` +
4323 `Lifecycle injection APIs can only be used during execution of setup().` +
4324 (` If you are using async setup(), make sure to register lifecycle ` +
4325 `hooks before the first await statement.`
4326 ));
4327 }
4328 }
4329 const createHook = (lifecycle) => (hook, target = currentInstance) =>
4330 // post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
4331 (!isInSSRComponentSetup || lifecycle === "sp" /* LifecycleHooks.SERVER_PREFETCH */) &&
4332 injectHook(lifecycle, (...args) => hook(...args), target);
4333 const onBeforeMount = createHook("bm" /* LifecycleHooks.BEFORE_MOUNT */);
4334 const onMounted = createHook("m" /* LifecycleHooks.MOUNTED */);
4335 const onBeforeUpdate = createHook("bu" /* LifecycleHooks.BEFORE_UPDATE */);
4336 const onUpdated = createHook("u" /* LifecycleHooks.UPDATED */);
4337 const onBeforeUnmount = createHook("bum" /* LifecycleHooks.BEFORE_UNMOUNT */);
4338 const onUnmounted = createHook("um" /* LifecycleHooks.UNMOUNTED */);
4339 const onServerPrefetch = createHook("sp" /* LifecycleHooks.SERVER_PREFETCH */);
4340 const onRenderTriggered = createHook("rtg" /* LifecycleHooks.RENDER_TRIGGERED */);
4341 const onRenderTracked = createHook("rtc" /* LifecycleHooks.RENDER_TRACKED */);
4342 function onErrorCaptured(hook, target = currentInstance) {
4343 injectHook("ec" /* LifecycleHooks.ERROR_CAPTURED */, hook, target);
4344 }
4345
4346 /**
4347 Runtime helper for applying directives to a vnode. Example usage:
4348
4349 const comp = resolveComponent('comp')
4350 const foo = resolveDirective('foo')
4351 const bar = resolveDirective('bar')
4352
4353 return withDirectives(h(comp), [
4354 [foo, this.x],
4355 [bar, this.y]
4356 ])
4357 */
4358 function validateDirectiveName(name) {
4359 if (isBuiltInDirective(name)) {
4360 warn('Do not use built-in directive ids as custom directive id: ' + name);
4361 }
4362 }
4363 /**
4364 * Adds directives to a VNode.
4365 */
4366 function withDirectives(vnode, directives) {
4367 const internalInstance = currentRenderingInstance;
4368 if (internalInstance === null) {
4369 warn(`withDirectives can only be used inside render functions.`);
4370 return vnode;
4371 }
4372 const instance = getExposeProxy(internalInstance) ||
4373 internalInstance.proxy;
4374 const bindings = vnode.dirs || (vnode.dirs = []);
4375 for (let i = 0; i < directives.length; i++) {
4376 let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];
4377 if (dir) {
4378 if (isFunction(dir)) {
4379 dir = {
4380 mounted: dir,
4381 updated: dir
4382 };
4383 }
4384 if (dir.deep) {
4385 traverse(value);
4386 }
4387 bindings.push({
4388 dir,
4389 instance,
4390 value,
4391 oldValue: void 0,
4392 arg,
4393 modifiers
4394 });
4395 }
4396 }
4397 return vnode;
4398 }
4399 function invokeDirectiveHook(vnode, prevVNode, instance, name) {
4400 const bindings = vnode.dirs;
4401 const oldBindings = prevVNode && prevVNode.dirs;
4402 for (let i = 0; i < bindings.length; i++) {
4403 const binding = bindings[i];
4404 if (oldBindings) {
4405 binding.oldValue = oldBindings[i].value;
4406 }
4407 let hook = binding.dir[name];
4408 if (hook) {
4409 // disable tracking inside all lifecycle hooks
4410 // since they can potentially be called inside effects.
4411 pauseTracking();
4412 callWithAsyncErrorHandling(hook, instance, 8 /* ErrorCodes.DIRECTIVE_HOOK */, [
4413 vnode.el,
4414 binding,
4415 vnode,
4416 prevVNode
4417 ]);
4418 resetTracking();
4419 }
4420 }
4421 }
4422
4423 const COMPONENTS = 'components';
4424 const DIRECTIVES = 'directives';
4425 /**
4426 * @private
4427 */
4428 function resolveComponent(name, maybeSelfReference) {
4429 return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
4430 }
4431 const NULL_DYNAMIC_COMPONENT = Symbol();
4432 /**
4433 * @private
4434 */
4435 function resolveDynamicComponent(component) {
4436 if (isString(component)) {
4437 return resolveAsset(COMPONENTS, component, false) || component;
4438 }
4439 else {
4440 // invalid types will fallthrough to createVNode and raise warning
4441 return (component || NULL_DYNAMIC_COMPONENT);
4442 }
4443 }
4444 /**
4445 * @private
4446 */
4447 function resolveDirective(name) {
4448 return resolveAsset(DIRECTIVES, name);
4449 }
4450 // implementation
4451 function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
4452 const instance = currentRenderingInstance || currentInstance;
4453 if (instance) {
4454 const Component = instance.type;
4455 // explicit self name has highest priority
4456 if (type === COMPONENTS) {
4457 const selfName = getComponentName(Component, false /* do not include inferred name to avoid breaking existing code */);
4458 if (selfName &&
4459 (selfName === name ||
4460 selfName === camelize(name) ||
4461 selfName === capitalize(camelize(name)))) {
4462 return Component;
4463 }
4464 }
4465 const res =
4466 // local registration
4467 // check instance[type] first which is resolved for options API
4468 resolve(instance[type] || Component[type], name) ||
4469 // global registration
4470 resolve(instance.appContext[type], name);
4471 if (!res && maybeSelfReference) {
4472 // fallback to implicit self-reference
4473 return Component;
4474 }
4475 if (warnMissing && !res) {
4476 const extra = type === COMPONENTS
4477 ? `\nIf this is a native custom element, make sure to exclude it from ` +
4478 `component resolution via compilerOptions.isCustomElement.`
4479 : ``;
4480 warn(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
4481 }
4482 return res;
4483 }
4484 else {
4485 warn(`resolve${capitalize(type.slice(0, -1))} ` +
4486 `can only be used in render() or setup().`);
4487 }
4488 }
4489 function resolve(registry, name) {
4490 return (registry &&
4491 (registry[name] ||
4492 registry[camelize(name)] ||
4493 registry[capitalize(camelize(name))]));
4494 }
4495
4496 /**
4497 * Actual implementation
4498 */
4499 function renderList(source, renderItem, cache, index) {
4500 let ret;
4501 const cached = (cache && cache[index]);
4502 if (isArray(source) || isString(source)) {
4503 ret = new Array(source.length);
4504 for (let i = 0, l = source.length; i < l; i++) {
4505 ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
4506 }
4507 }
4508 else if (typeof source === 'number') {
4509 if (!Number.isInteger(source)) {
4510 warn(`The v-for range expect an integer value but got ${source}.`);
4511 }
4512 ret = new Array(source);
4513 for (let i = 0; i < source; i++) {
4514 ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
4515 }
4516 }
4517 else if (isObject(source)) {
4518 if (source[Symbol.iterator]) {
4519 ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
4520 }
4521 else {
4522 const keys = Object.keys(source);
4523 ret = new Array(keys.length);
4524 for (let i = 0, l = keys.length; i < l; i++) {
4525 const key = keys[i];
4526 ret[i] = renderItem(source[key], key, i, cached && cached[i]);
4527 }
4528 }
4529 }
4530 else {
4531 ret = [];
4532 }
4533 if (cache) {
4534 cache[index] = ret;
4535 }
4536 return ret;
4537 }
4538
4539 /**
4540 * Compiler runtime helper for creating dynamic slots object
4541 * @private
4542 */
4543 function createSlots(slots, dynamicSlots) {
4544 for (let i = 0; i < dynamicSlots.length; i++) {
4545 const slot = dynamicSlots[i];
4546 // array of dynamic slot generated by <template v-for="..." #[...]>
4547 if (isArray(slot)) {
4548 for (let j = 0; j < slot.length; j++) {
4549 slots[slot[j].name] = slot[j].fn;
4550 }
4551 }
4552 else if (slot) {
4553 // conditional single slot generated by <template v-if="..." #foo>
4554 slots[slot.name] = slot.key
4555 ? (...args) => {
4556 const res = slot.fn(...args);
4557 // attach branch key so each conditional branch is considered a
4558 // different fragment
4559 if (res)
4560 res.key = slot.key;
4561 return res;
4562 }
4563 : slot.fn;
4564 }
4565 }
4566 return slots;
4567 }
4568
4569 /**
4570 * Compiler runtime helper for rendering `<slot/>`
4571 * @private
4572 */
4573 function renderSlot(slots, name, props = {},
4574 // this is not a user-facing function, so the fallback is always generated by
4575 // the compiler and guaranteed to be a function returning an array
4576 fallback, noSlotted) {
4577 if (currentRenderingInstance.isCE ||
4578 (currentRenderingInstance.parent &&
4579 isAsyncWrapper(currentRenderingInstance.parent) &&
4580 currentRenderingInstance.parent.isCE)) {
4581 if (name !== 'default')
4582 props.name = name;
4583 return createVNode('slot', props, fallback && fallback());
4584 }
4585 let slot = slots[name];
4586 if (slot && slot.length > 1) {
4587 warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
4588 `function. You need to mark this component with $dynamic-slots in the ` +
4589 `parent template.`);
4590 slot = () => [];
4591 }
4592 // a compiled slot disables block tracking by default to avoid manual
4593 // invocation interfering with template-based block tracking, but in
4594 // `renderSlot` we can be sure that it's template-based so we can force
4595 // enable it.
4596 if (slot && slot._c) {
4597 slot._d = false;
4598 }
4599 openBlock();
4600 const validSlotContent = slot && ensureValidVNode(slot(props));
4601 const rendered = createBlock(Fragment, {
4602 key: props.key ||
4603 // slot content array of a dynamic conditional slot may have a branch
4604 // key attached in the `createSlots` helper, respect that
4605 (validSlotContent && validSlotContent.key) ||
4606 `_${name}`
4607 }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* SlotFlags.STABLE */
4608 ? 64 /* PatchFlags.STABLE_FRAGMENT */
4609 : -2 /* PatchFlags.BAIL */);
4610 if (!noSlotted && rendered.scopeId) {
4611 rendered.slotScopeIds = [rendered.scopeId + '-s'];
4612 }
4613 if (slot && slot._c) {
4614 slot._d = true;
4615 }
4616 return rendered;
4617 }
4618 function ensureValidVNode(vnodes) {
4619 return vnodes.some(child => {
4620 if (!isVNode(child))
4621 return true;
4622 if (child.type === Comment)
4623 return false;
4624 if (child.type === Fragment &&
4625 !ensureValidVNode(child.children))
4626 return false;
4627 return true;
4628 })
4629 ? vnodes
4630 : null;
4631 }
4632
4633 /**
4634 * For prefixing keys in v-on="obj" with "on"
4635 * @private
4636 */
4637 function toHandlers(obj, preserveCaseIfNecessary) {
4638 const ret = {};
4639 if (!isObject(obj)) {
4640 warn(`v-on with no argument expects an object value.`);
4641 return ret;
4642 }
4643 for (const key in obj) {
4644 ret[preserveCaseIfNecessary && /[A-Z]/.test(key)
4645 ? `on:${key}`
4646 : toHandlerKey(key)] = obj[key];
4647 }
4648 return ret;
4649 }
4650
4651 /**
4652 * #2437 In Vue 3, functional components do not have a public instance proxy but
4653 * they exist in the internal parent chain. For code that relies on traversing
4654 * public $parent chains, skip functional ones and go to the parent instead.
4655 */
4656 const getPublicInstance = (i) => {
4657 if (!i)
4658 return null;
4659 if (isStatefulComponent(i))
4660 return getExposeProxy(i) || i.proxy;
4661 return getPublicInstance(i.parent);
4662 };
4663 const publicPropertiesMap =
4664 // Move PURE marker to new line to workaround compiler discarding it
4665 // due to type annotation
4666 /*#__PURE__*/ extend(Object.create(null), {
4667 $: i => i,
4668 $el: i => i.vnode.el,
4669 $data: i => i.data,
4670 $props: i => (shallowReadonly(i.props) ),
4671 $attrs: i => (shallowReadonly(i.attrs) ),
4672 $slots: i => (shallowReadonly(i.slots) ),
4673 $refs: i => (shallowReadonly(i.refs) ),
4674 $parent: i => getPublicInstance(i.parent),
4675 $root: i => getPublicInstance(i.root),
4676 $emit: i => i.emit,
4677 $options: i => (resolveMergedOptions(i) ),
4678 $forceUpdate: i => i.f || (i.f = () => queueJob(i.update)),
4679 $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)),
4680 $watch: i => (instanceWatch.bind(i) )
4681 });
4682 const isReservedPrefix = (key) => key === '_' || key === '$';
4683 const hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key);
4684 const PublicInstanceProxyHandlers = {
4685 get({ _: instance }, key) {
4686 const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
4687 // for internal formatters to know that this is a Vue instance
4688 if (key === '__isVue') {
4689 return true;
4690 }
4691 // data / props / ctx
4692 // This getter gets called for every property access on the render context
4693 // during render and is a major hotspot. The most expensive part of this
4694 // is the multiple hasOwn() calls. It's much faster to do a simple property
4695 // access on a plain object, so we use an accessCache object (with null
4696 // prototype) to memoize what access type a key corresponds to.
4697 let normalizedProps;
4698 if (key[0] !== '$') {
4699 const n = accessCache[key];
4700 if (n !== undefined) {
4701 switch (n) {
4702 case 1 /* AccessTypes.SETUP */:
4703 return setupState[key];
4704 case 2 /* AccessTypes.DATA */:
4705 return data[key];
4706 case 4 /* AccessTypes.CONTEXT */:
4707 return ctx[key];
4708 case 3 /* AccessTypes.PROPS */:
4709 return props[key];
4710 // default: just fallthrough
4711 }
4712 }
4713 else if (hasSetupBinding(setupState, key)) {
4714 accessCache[key] = 1 /* AccessTypes.SETUP */;
4715 return setupState[key];
4716 }
4717 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4718 accessCache[key] = 2 /* AccessTypes.DATA */;
4719 return data[key];
4720 }
4721 else if (
4722 // only cache other properties when instance has declared (thus stable)
4723 // props
4724 (normalizedProps = instance.propsOptions[0]) &&
4725 hasOwn(normalizedProps, key)) {
4726 accessCache[key] = 3 /* AccessTypes.PROPS */;
4727 return props[key];
4728 }
4729 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4730 accessCache[key] = 4 /* AccessTypes.CONTEXT */;
4731 return ctx[key];
4732 }
4733 else if (shouldCacheAccess) {
4734 accessCache[key] = 0 /* AccessTypes.OTHER */;
4735 }
4736 }
4737 const publicGetter = publicPropertiesMap[key];
4738 let cssModule, globalProperties;
4739 // public $xxx properties
4740 if (publicGetter) {
4741 if (key === '$attrs') {
4742 track(instance, "get" /* TrackOpTypes.GET */, key);
4743 markAttrsAccessed();
4744 }
4745 return publicGetter(instance);
4746 }
4747 else if (
4748 // css module (injected by vue-loader)
4749 (cssModule = type.__cssModules) &&
4750 (cssModule = cssModule[key])) {
4751 return cssModule;
4752 }
4753 else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
4754 // user may set custom properties to `this` that start with `$`
4755 accessCache[key] = 4 /* AccessTypes.CONTEXT */;
4756 return ctx[key];
4757 }
4758 else if (
4759 // global properties
4760 ((globalProperties = appContext.config.globalProperties),
4761 hasOwn(globalProperties, key))) {
4762 {
4763 return globalProperties[key];
4764 }
4765 }
4766 else if (currentRenderingInstance &&
4767 (!isString(key) ||
4768 // #1091 avoid internal isRef/isVNode checks on component instance leading
4769 // to infinite warning loop
4770 key.indexOf('__v') !== 0)) {
4771 if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {
4772 warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
4773 `character ("$" or "_") and is not proxied on the render context.`);
4774 }
4775 else if (instance === currentRenderingInstance) {
4776 warn(`Property ${JSON.stringify(key)} was accessed during render ` +
4777 `but is not defined on instance.`);
4778 }
4779 }
4780 },
4781 set({ _: instance }, key, value) {
4782 const { data, setupState, ctx } = instance;
4783 if (hasSetupBinding(setupState, key)) {
4784 setupState[key] = value;
4785 return true;
4786 }
4787 else if (setupState.__isScriptSetup &&
4788 hasOwn(setupState, key)) {
4789 warn(`Cannot mutate <script setup> binding "${key}" from Options API.`);
4790 return false;
4791 }
4792 else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
4793 data[key] = value;
4794 return true;
4795 }
4796 else if (hasOwn(instance.props, key)) {
4797 warn(`Attempting to mutate prop "${key}". Props are readonly.`);
4798 return false;
4799 }
4800 if (key[0] === '$' && key.slice(1) in instance) {
4801 warn(`Attempting to mutate public property "${key}". ` +
4802 `Properties starting with $ are reserved and readonly.`);
4803 return false;
4804 }
4805 else {
4806 if (key in instance.appContext.config.globalProperties) {
4807 Object.defineProperty(ctx, key, {
4808 enumerable: true,
4809 configurable: true,
4810 value
4811 });
4812 }
4813 else {
4814 ctx[key] = value;
4815 }
4816 }
4817 return true;
4818 },
4819 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
4820 let normalizedProps;
4821 return (!!accessCache[key] ||
4822 (data !== EMPTY_OBJ && hasOwn(data, key)) ||
4823 hasSetupBinding(setupState, key) ||
4824 ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
4825 hasOwn(ctx, key) ||
4826 hasOwn(publicPropertiesMap, key) ||
4827 hasOwn(appContext.config.globalProperties, key));
4828 },
4829 defineProperty(target, key, descriptor) {
4830 if (descriptor.get != null) {
4831 // invalidate key cache of a getter based property #5417
4832 target._.accessCache[key] = 0;
4833 }
4834 else if (hasOwn(descriptor, 'value')) {
4835 this.set(target, key, descriptor.value, null);
4836 }
4837 return Reflect.defineProperty(target, key, descriptor);
4838 }
4839 };
4840 {
4841 PublicInstanceProxyHandlers.ownKeys = (target) => {
4842 warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
4843 `The keys will be empty in production mode to avoid performance overhead.`);
4844 return Reflect.ownKeys(target);
4845 };
4846 }
4847 const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ extend({}, PublicInstanceProxyHandlers, {
4848 get(target, key) {
4849 // fast path for unscopables when using `with` block
4850 if (key === Symbol.unscopables) {
4851 return;
4852 }
4853 return PublicInstanceProxyHandlers.get(target, key, target);
4854 },
4855 has(_, key) {
4856 const has = key[0] !== '_' && !isGloballyWhitelisted(key);
4857 if (!has && PublicInstanceProxyHandlers.has(_, key)) {
4858 warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
4859 }
4860 return has;
4861 }
4862 });
4863 // dev only
4864 // In dev mode, the proxy target exposes the same properties as seen on `this`
4865 // for easier console inspection. In prod mode it will be an empty object so
4866 // these properties definitions can be skipped.
4867 function createDevRenderContext(instance) {
4868 const target = {};
4869 // expose internal instance for proxy handlers
4870 Object.defineProperty(target, `_`, {
4871 configurable: true,
4872 enumerable: false,
4873 get: () => instance
4874 });
4875 // expose public properties
4876 Object.keys(publicPropertiesMap).forEach(key => {
4877 Object.defineProperty(target, key, {
4878 configurable: true,
4879 enumerable: false,
4880 get: () => publicPropertiesMap[key](instance),
4881 // intercepted by the proxy so no need for implementation,
4882 // but needed to prevent set errors
4883 set: NOOP
4884 });
4885 });
4886 return target;
4887 }
4888 // dev only
4889 function exposePropsOnRenderContext(instance) {
4890 const { ctx, propsOptions: [propsOptions] } = instance;
4891 if (propsOptions) {
4892 Object.keys(propsOptions).forEach(key => {
4893 Object.defineProperty(ctx, key, {
4894 enumerable: true,
4895 configurable: true,
4896 get: () => instance.props[key],
4897 set: NOOP
4898 });
4899 });
4900 }
4901 }
4902 // dev only
4903 function exposeSetupStateOnRenderContext(instance) {
4904 const { ctx, setupState } = instance;
4905 Object.keys(toRaw(setupState)).forEach(key => {
4906 if (!setupState.__isScriptSetup) {
4907 if (isReservedPrefix(key[0])) {
4908 warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
4909 `which are reserved prefixes for Vue internals.`);
4910 return;
4911 }
4912 Object.defineProperty(ctx, key, {
4913 enumerable: true,
4914 configurable: true,
4915 get: () => setupState[key],
4916 set: NOOP
4917 });
4918 }
4919 });
4920 }
4921
4922 function createDuplicateChecker() {
4923 const cache = Object.create(null);
4924 return (type, key) => {
4925 if (cache[key]) {
4926 warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
4927 }
4928 else {
4929 cache[key] = type;
4930 }
4931 };
4932 }
4933 let shouldCacheAccess = true;
4934 function applyOptions(instance) {
4935 const options = resolveMergedOptions(instance);
4936 const publicThis = instance.proxy;
4937 const ctx = instance.ctx;
4938 // do not cache property access on public proxy during state initialization
4939 shouldCacheAccess = false;
4940 // call beforeCreate first before accessing other options since
4941 // the hook may mutate resolved options (#2791)
4942 if (options.beforeCreate) {
4943 callHook$1(options.beforeCreate, instance, "bc" /* LifecycleHooks.BEFORE_CREATE */);
4944 }
4945 const {
4946 // state
4947 data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
4948 // lifecycle
4949 created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
4950 // public API
4951 expose, inheritAttrs,
4952 // assets
4953 components, directives, filters } = options;
4954 const checkDuplicateProperties = createDuplicateChecker() ;
4955 {
4956 const [propsOptions] = instance.propsOptions;
4957 if (propsOptions) {
4958 for (const key in propsOptions) {
4959 checkDuplicateProperties("Props" /* OptionTypes.PROPS */, key);
4960 }
4961 }
4962 }
4963 // options initialization order (to be consistent with Vue 2):
4964 // - props (already done outside of this function)
4965 // - inject
4966 // - methods
4967 // - data (deferred since it relies on `this` access)
4968 // - computed
4969 // - watch (deferred since it relies on `this` access)
4970 if (injectOptions) {
4971 resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
4972 }
4973 if (methods) {
4974 for (const key in methods) {
4975 const methodHandler = methods[key];
4976 if (isFunction(methodHandler)) {
4977 // In dev mode, we use the `createRenderContext` function to define
4978 // methods to the proxy target, and those are read-only but
4979 // reconfigurable, so it needs to be redefined here
4980 {
4981 Object.defineProperty(ctx, key, {
4982 value: methodHandler.bind(publicThis),
4983 configurable: true,
4984 enumerable: true,
4985 writable: true
4986 });
4987 }
4988 {
4989 checkDuplicateProperties("Methods" /* OptionTypes.METHODS */, key);
4990 }
4991 }
4992 else {
4993 warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
4994 `Did you reference the function correctly?`);
4995 }
4996 }
4997 }
4998 if (dataOptions) {
4999 if (!isFunction(dataOptions)) {
5000 warn(`The data option must be a function. ` +
5001 `Plain object usage is no longer supported.`);
5002 }
5003 const data = dataOptions.call(publicThis, publicThis);
5004 if (isPromise(data)) {
5005 warn(`data() returned a Promise - note data() cannot be async; If you ` +
5006 `intend to perform data fetching before component renders, use ` +
5007 `async setup() + <Suspense>.`);
5008 }
5009 if (!isObject(data)) {
5010 warn(`data() should return an object.`);
5011 }
5012 else {
5013 instance.data = reactive(data);
5014 {
5015 for (const key in data) {
5016 checkDuplicateProperties("Data" /* OptionTypes.DATA */, key);
5017 // expose data on ctx during dev
5018 if (!isReservedPrefix(key[0])) {
5019 Object.defineProperty(ctx, key, {
5020 configurable: true,
5021 enumerable: true,
5022 get: () => data[key],
5023 set: NOOP
5024 });
5025 }
5026 }
5027 }
5028 }
5029 }
5030 // state initialization complete at this point - start caching access
5031 shouldCacheAccess = true;
5032 if (computedOptions) {
5033 for (const key in computedOptions) {
5034 const opt = computedOptions[key];
5035 const get = isFunction(opt)
5036 ? opt.bind(publicThis, publicThis)
5037 : isFunction(opt.get)
5038 ? opt.get.bind(publicThis, publicThis)
5039 : NOOP;
5040 if (get === NOOP) {
5041 warn(`Computed property "${key}" has no getter.`);
5042 }
5043 const set = !isFunction(opt) && isFunction(opt.set)
5044 ? opt.set.bind(publicThis)
5045 : () => {
5046 warn(`Write operation failed: computed property "${key}" is readonly.`);
5047 }
5048 ;
5049 const c = computed({
5050 get,
5051 set
5052 });
5053 Object.defineProperty(ctx, key, {
5054 enumerable: true,
5055 configurable: true,
5056 get: () => c.value,
5057 set: v => (c.value = v)
5058 });
5059 {
5060 checkDuplicateProperties("Computed" /* OptionTypes.COMPUTED */, key);
5061 }
5062 }
5063 }
5064 if (watchOptions) {
5065 for (const key in watchOptions) {
5066 createWatcher(watchOptions[key], ctx, publicThis, key);
5067 }
5068 }
5069 if (provideOptions) {
5070 const provides = isFunction(provideOptions)
5071 ? provideOptions.call(publicThis)
5072 : provideOptions;
5073 Reflect.ownKeys(provides).forEach(key => {
5074 provide(key, provides[key]);
5075 });
5076 }
5077 if (created) {
5078 callHook$1(created, instance, "c" /* LifecycleHooks.CREATED */);
5079 }
5080 function registerLifecycleHook(register, hook) {
5081 if (isArray(hook)) {
5082 hook.forEach(_hook => register(_hook.bind(publicThis)));
5083 }
5084 else if (hook) {
5085 register(hook.bind(publicThis));
5086 }
5087 }
5088 registerLifecycleHook(onBeforeMount, beforeMount);
5089 registerLifecycleHook(onMounted, mounted);
5090 registerLifecycleHook(onBeforeUpdate, beforeUpdate);
5091 registerLifecycleHook(onUpdated, updated);
5092 registerLifecycleHook(onActivated, activated);
5093 registerLifecycleHook(onDeactivated, deactivated);
5094 registerLifecycleHook(onErrorCaptured, errorCaptured);
5095 registerLifecycleHook(onRenderTracked, renderTracked);
5096 registerLifecycleHook(onRenderTriggered, renderTriggered);
5097 registerLifecycleHook(onBeforeUnmount, beforeUnmount);
5098 registerLifecycleHook(onUnmounted, unmounted);
5099 registerLifecycleHook(onServerPrefetch, serverPrefetch);
5100 if (isArray(expose)) {
5101 if (expose.length) {
5102 const exposed = instance.exposed || (instance.exposed = {});
5103 expose.forEach(key => {
5104 Object.defineProperty(exposed, key, {
5105 get: () => publicThis[key],
5106 set: val => (publicThis[key] = val)
5107 });
5108 });
5109 }
5110 else if (!instance.exposed) {
5111 instance.exposed = {};
5112 }
5113 }
5114 // options that are handled when creating the instance but also need to be
5115 // applied from mixins
5116 if (render && instance.render === NOOP) {
5117 instance.render = render;
5118 }
5119 if (inheritAttrs != null) {
5120 instance.inheritAttrs = inheritAttrs;
5121 }
5122 // asset options.
5123 if (components)
5124 instance.components = components;
5125 if (directives)
5126 instance.directives = directives;
5127 }
5128 function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP, unwrapRef = false) {
5129 if (isArray(injectOptions)) {
5130 injectOptions = normalizeInject(injectOptions);
5131 }
5132 for (const key in injectOptions) {
5133 const opt = injectOptions[key];
5134 let injected;
5135 if (isObject(opt)) {
5136 if ('default' in opt) {
5137 injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
5138 }
5139 else {
5140 injected = inject(opt.from || key);
5141 }
5142 }
5143 else {
5144 injected = inject(opt);
5145 }
5146 if (isRef(injected)) {
5147 // TODO remove the check in 3.3
5148 if (unwrapRef) {
5149 Object.defineProperty(ctx, key, {
5150 enumerable: true,
5151 configurable: true,
5152 get: () => injected.value,
5153 set: v => (injected.value = v)
5154 });
5155 }
5156 else {
5157 {
5158 warn(`injected property "${key}" is a ref and will be auto-unwrapped ` +
5159 `and no longer needs \`.value\` in the next minor release. ` +
5160 `To opt-in to the new behavior now, ` +
5161 `set \`app.config.unwrapInjectedRef = true\` (this config is ` +
5162 `temporary and will not be needed in the future.)`);
5163 }
5164 ctx[key] = injected;
5165 }
5166 }
5167 else {
5168 ctx[key] = injected;
5169 }
5170 {
5171 checkDuplicateProperties("Inject" /* OptionTypes.INJECT */, key);
5172 }
5173 }
5174 }
5175 function callHook$1(hook, instance, type) {
5176 callWithAsyncErrorHandling(isArray(hook)
5177 ? hook.map(h => h.bind(instance.proxy))
5178 : hook.bind(instance.proxy), instance, type);
5179 }
5180 function createWatcher(raw, ctx, publicThis, key) {
5181 const getter = key.includes('.')
5182 ? createPathGetter(publicThis, key)
5183 : () => publicThis[key];
5184 if (isString(raw)) {
5185 const handler = ctx[raw];
5186 if (isFunction(handler)) {
5187 watch(getter, handler);
5188 }
5189 else {
5190 warn(`Invalid watch handler specified by key "${raw}"`, handler);
5191 }
5192 }
5193 else if (isFunction(raw)) {
5194 watch(getter, raw.bind(publicThis));
5195 }
5196 else if (isObject(raw)) {
5197 if (isArray(raw)) {
5198 raw.forEach(r => createWatcher(r, ctx, publicThis, key));
5199 }
5200 else {
5201 const handler = isFunction(raw.handler)
5202 ? raw.handler.bind(publicThis)
5203 : ctx[raw.handler];
5204 if (isFunction(handler)) {
5205 watch(getter, handler, raw);
5206 }
5207 else {
5208 warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
5209 }
5210 }
5211 }
5212 else {
5213 warn(`Invalid watch option: "${key}"`, raw);
5214 }
5215 }
5216 /**
5217 * Resolve merged options and cache it on the component.
5218 * This is done only once per-component since the merging does not involve
5219 * instances.
5220 */
5221 function resolveMergedOptions(instance) {
5222 const base = instance.type;
5223 const { mixins, extends: extendsOptions } = base;
5224 const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
5225 const cached = cache.get(base);
5226 let resolved;
5227 if (cached) {
5228 resolved = cached;
5229 }
5230 else if (!globalMixins.length && !mixins && !extendsOptions) {
5231 {
5232 resolved = base;
5233 }
5234 }
5235 else {
5236 resolved = {};
5237 if (globalMixins.length) {
5238 globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
5239 }
5240 mergeOptions(resolved, base, optionMergeStrategies);
5241 }
5242 if (isObject(base)) {
5243 cache.set(base, resolved);
5244 }
5245 return resolved;
5246 }
5247 function mergeOptions(to, from, strats, asMixin = false) {
5248 const { mixins, extends: extendsOptions } = from;
5249 if (extendsOptions) {
5250 mergeOptions(to, extendsOptions, strats, true);
5251 }
5252 if (mixins) {
5253 mixins.forEach((m) => mergeOptions(to, m, strats, true));
5254 }
5255 for (const key in from) {
5256 if (asMixin && key === 'expose') {
5257 warn(`"expose" option is ignored when declared in mixins or extends. ` +
5258 `It should only be declared in the base component itself.`);
5259 }
5260 else {
5261 const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
5262 to[key] = strat ? strat(to[key], from[key]) : from[key];
5263 }
5264 }
5265 return to;
5266 }
5267 const internalOptionMergeStrats = {
5268 data: mergeDataFn,
5269 props: mergeObjectOptions,
5270 emits: mergeObjectOptions,
5271 // objects
5272 methods: mergeObjectOptions,
5273 computed: mergeObjectOptions,
5274 // lifecycle
5275 beforeCreate: mergeAsArray$1,
5276 created: mergeAsArray$1,
5277 beforeMount: mergeAsArray$1,
5278 mounted: mergeAsArray$1,
5279 beforeUpdate: mergeAsArray$1,
5280 updated: mergeAsArray$1,
5281 beforeDestroy: mergeAsArray$1,
5282 beforeUnmount: mergeAsArray$1,
5283 destroyed: mergeAsArray$1,
5284 unmounted: mergeAsArray$1,
5285 activated: mergeAsArray$1,
5286 deactivated: mergeAsArray$1,
5287 errorCaptured: mergeAsArray$1,
5288 serverPrefetch: mergeAsArray$1,
5289 // assets
5290 components: mergeObjectOptions,
5291 directives: mergeObjectOptions,
5292 // watch
5293 watch: mergeWatchOptions,
5294 // provide / inject
5295 provide: mergeDataFn,
5296 inject: mergeInject
5297 };
5298 function mergeDataFn(to, from) {
5299 if (!from) {
5300 return to;
5301 }
5302 if (!to) {
5303 return from;
5304 }
5305 return function mergedDataFn() {
5306 return (extend)(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from);
5307 };
5308 }
5309 function mergeInject(to, from) {
5310 return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
5311 }
5312 function normalizeInject(raw) {
5313 if (isArray(raw)) {
5314 const res = {};
5315 for (let i = 0; i < raw.length; i++) {
5316 res[raw[i]] = raw[i];
5317 }
5318 return res;
5319 }
5320 return raw;
5321 }
5322 function mergeAsArray$1(to, from) {
5323 return to ? [...new Set([].concat(to, from))] : from;
5324 }
5325 function mergeObjectOptions(to, from) {
5326 return to ? extend(extend(Object.create(null), to), from) : from;
5327 }
5328 function mergeWatchOptions(to, from) {
5329 if (!to)
5330 return from;
5331 if (!from)
5332 return to;
5333 const merged = extend(Object.create(null), to);
5334 for (const key in from) {
5335 merged[key] = mergeAsArray$1(to[key], from[key]);
5336 }
5337 return merged;
5338 }
5339
5340 function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
5341 isSSR = false) {
5342 const props = {};
5343 const attrs = {};
5344 def(attrs, InternalObjectKey, 1);
5345 instance.propsDefaults = Object.create(null);
5346 setFullProps(instance, rawProps, props, attrs);
5347 // ensure all declared prop keys are present
5348 for (const key in instance.propsOptions[0]) {
5349 if (!(key in props)) {
5350 props[key] = undefined;
5351 }
5352 }
5353 // validation
5354 {
5355 validateProps(rawProps || {}, props, instance);
5356 }
5357 if (isStateful) {
5358 // stateful
5359 instance.props = isSSR ? props : shallowReactive(props);
5360 }
5361 else {
5362 if (!instance.type.props) {
5363 // functional w/ optional props, props === attrs
5364 instance.props = attrs;
5365 }
5366 else {
5367 // functional w/ declared props
5368 instance.props = props;
5369 }
5370 }
5371 instance.attrs = attrs;
5372 }
5373 function isInHmrContext(instance) {
5374 while (instance) {
5375 if (instance.type.__hmrId)
5376 return true;
5377 instance = instance.parent;
5378 }
5379 }
5380 function updateProps(instance, rawProps, rawPrevProps, optimized) {
5381 const { props, attrs, vnode: { patchFlag } } = instance;
5382 const rawCurrentProps = toRaw(props);
5383 const [options] = instance.propsOptions;
5384 let hasAttrsChanged = false;
5385 if (
5386 // always force full diff in dev
5387 // - #1942 if hmr is enabled with sfc component
5388 // - vite#872 non-sfc component used by sfc component
5389 !(isInHmrContext(instance)) &&
5390 (optimized || patchFlag > 0) &&
5391 !(patchFlag & 16 /* PatchFlags.FULL_PROPS */)) {
5392 if (patchFlag & 8 /* PatchFlags.PROPS */) {
5393 // Compiler-generated props & no keys change, just set the updated
5394 // the props.
5395 const propsToUpdate = instance.vnode.dynamicProps;
5396 for (let i = 0; i < propsToUpdate.length; i++) {
5397 let key = propsToUpdate[i];
5398 // skip if the prop key is a declared emit event listener
5399 if (isEmitListener(instance.emitsOptions, key)) {
5400 continue;
5401 }
5402 // PROPS flag guarantees rawProps to be non-null
5403 const value = rawProps[key];
5404 if (options) {
5405 // attr / props separation was done on init and will be consistent
5406 // in this code path, so just check if attrs have it.
5407 if (hasOwn(attrs, key)) {
5408 if (value !== attrs[key]) {
5409 attrs[key] = value;
5410 hasAttrsChanged = true;
5411 }
5412 }
5413 else {
5414 const camelizedKey = camelize(key);
5415 props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
5416 }
5417 }
5418 else {
5419 if (value !== attrs[key]) {
5420 attrs[key] = value;
5421 hasAttrsChanged = true;
5422 }
5423 }
5424 }
5425 }
5426 }
5427 else {
5428 // full props update.
5429 if (setFullProps(instance, rawProps, props, attrs)) {
5430 hasAttrsChanged = true;
5431 }
5432 // in case of dynamic props, check if we need to delete keys from
5433 // the props object
5434 let kebabKey;
5435 for (const key in rawCurrentProps) {
5436 if (!rawProps ||
5437 // for camelCase
5438 (!hasOwn(rawProps, key) &&
5439 // it's possible the original props was passed in as kebab-case
5440 // and converted to camelCase (#955)
5441 ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
5442 if (options) {
5443 if (rawPrevProps &&
5444 // for camelCase
5445 (rawPrevProps[key] !== undefined ||
5446 // for kebab-case
5447 rawPrevProps[kebabKey] !== undefined)) {
5448 props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
5449 }
5450 }
5451 else {
5452 delete props[key];
5453 }
5454 }
5455 }
5456 // in the case of functional component w/o props declaration, props and
5457 // attrs point to the same object so it should already have been updated.
5458 if (attrs !== rawCurrentProps) {
5459 for (const key in attrs) {
5460 if (!rawProps ||
5461 (!hasOwn(rawProps, key) &&
5462 (!false ))) {
5463 delete attrs[key];
5464 hasAttrsChanged = true;
5465 }
5466 }
5467 }
5468 }
5469 // trigger updates for $attrs in case it's used in component slots
5470 if (hasAttrsChanged) {
5471 trigger(instance, "set" /* TriggerOpTypes.SET */, '$attrs');
5472 }
5473 {
5474 validateProps(rawProps || {}, props, instance);
5475 }
5476 }
5477 function setFullProps(instance, rawProps, props, attrs) {
5478 const [options, needCastKeys] = instance.propsOptions;
5479 let hasAttrsChanged = false;
5480 let rawCastValues;
5481 if (rawProps) {
5482 for (let key in rawProps) {
5483 // key, ref are reserved and never passed down
5484 if (isReservedProp(key)) {
5485 continue;
5486 }
5487 const value = rawProps[key];
5488 // prop option names are camelized during normalization, so to support
5489 // kebab -> camel conversion here we need to camelize the key.
5490 let camelKey;
5491 if (options && hasOwn(options, (camelKey = camelize(key)))) {
5492 if (!needCastKeys || !needCastKeys.includes(camelKey)) {
5493 props[camelKey] = value;
5494 }
5495 else {
5496 (rawCastValues || (rawCastValues = {}))[camelKey] = value;
5497 }
5498 }
5499 else if (!isEmitListener(instance.emitsOptions, key)) {
5500 if (!(key in attrs) || value !== attrs[key]) {
5501 attrs[key] = value;
5502 hasAttrsChanged = true;
5503 }
5504 }
5505 }
5506 }
5507 if (needCastKeys) {
5508 const rawCurrentProps = toRaw(props);
5509 const castValues = rawCastValues || EMPTY_OBJ;
5510 for (let i = 0; i < needCastKeys.length; i++) {
5511 const key = needCastKeys[i];
5512 props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !hasOwn(castValues, key));
5513 }
5514 }
5515 return hasAttrsChanged;
5516 }
5517 function resolvePropValue(options, props, key, value, instance, isAbsent) {
5518 const opt = options[key];
5519 if (opt != null) {
5520 const hasDefault = hasOwn(opt, 'default');
5521 // default values
5522 if (hasDefault && value === undefined) {
5523 const defaultValue = opt.default;
5524 if (opt.type !== Function && isFunction(defaultValue)) {
5525 const { propsDefaults } = instance;
5526 if (key in propsDefaults) {
5527 value = propsDefaults[key];
5528 }
5529 else {
5530 setCurrentInstance(instance);
5531 value = propsDefaults[key] = defaultValue.call(null, props);
5532 unsetCurrentInstance();
5533 }
5534 }
5535 else {
5536 value = defaultValue;
5537 }
5538 }
5539 // boolean casting
5540 if (opt[0 /* BooleanFlags.shouldCast */]) {
5541 if (isAbsent && !hasDefault) {
5542 value = false;
5543 }
5544 else if (opt[1 /* BooleanFlags.shouldCastTrue */] &&
5545 (value === '' || value === hyphenate(key))) {
5546 value = true;
5547 }
5548 }
5549 }
5550 return value;
5551 }
5552 function normalizePropsOptions(comp, appContext, asMixin = false) {
5553 const cache = appContext.propsCache;
5554 const cached = cache.get(comp);
5555 if (cached) {
5556 return cached;
5557 }
5558 const raw = comp.props;
5559 const normalized = {};
5560 const needCastKeys = [];
5561 // apply mixin/extends props
5562 let hasExtends = false;
5563 if (!isFunction(comp)) {
5564 const extendProps = (raw) => {
5565 hasExtends = true;
5566 const [props, keys] = normalizePropsOptions(raw, appContext, true);
5567 extend(normalized, props);
5568 if (keys)
5569 needCastKeys.push(...keys);
5570 };
5571 if (!asMixin && appContext.mixins.length) {
5572 appContext.mixins.forEach(extendProps);
5573 }
5574 if (comp.extends) {
5575 extendProps(comp.extends);
5576 }
5577 if (comp.mixins) {
5578 comp.mixins.forEach(extendProps);
5579 }
5580 }
5581 if (!raw && !hasExtends) {
5582 if (isObject(comp)) {
5583 cache.set(comp, EMPTY_ARR);
5584 }
5585 return EMPTY_ARR;
5586 }
5587 if (isArray(raw)) {
5588 for (let i = 0; i < raw.length; i++) {
5589 if (!isString(raw[i])) {
5590 warn(`props must be strings when using array syntax.`, raw[i]);
5591 }
5592 const normalizedKey = camelize(raw[i]);
5593 if (validatePropName(normalizedKey)) {
5594 normalized[normalizedKey] = EMPTY_OBJ;
5595 }
5596 }
5597 }
5598 else if (raw) {
5599 if (!isObject(raw)) {
5600 warn(`invalid props options`, raw);
5601 }
5602 for (const key in raw) {
5603 const normalizedKey = camelize(key);
5604 if (validatePropName(normalizedKey)) {
5605 const opt = raw[key];
5606 const prop = (normalized[normalizedKey] =
5607 isArray(opt) || isFunction(opt) ? { type: opt } : Object.assign({}, opt));
5608 if (prop) {
5609 const booleanIndex = getTypeIndex(Boolean, prop.type);
5610 const stringIndex = getTypeIndex(String, prop.type);
5611 prop[0 /* BooleanFlags.shouldCast */] = booleanIndex > -1;
5612 prop[1 /* BooleanFlags.shouldCastTrue */] =
5613 stringIndex < 0 || booleanIndex < stringIndex;
5614 // if the prop needs boolean casting or default value
5615 if (booleanIndex > -1 || hasOwn(prop, 'default')) {
5616 needCastKeys.push(normalizedKey);
5617 }
5618 }
5619 }
5620 }
5621 }
5622 const res = [normalized, needCastKeys];
5623 if (isObject(comp)) {
5624 cache.set(comp, res);
5625 }
5626 return res;
5627 }
5628 function validatePropName(key) {
5629 if (key[0] !== '$') {
5630 return true;
5631 }
5632 else {
5633 warn(`Invalid prop name: "${key}" is a reserved property.`);
5634 }
5635 return false;
5636 }
5637 // use function string name to check type constructors
5638 // so that it works across vms / iframes.
5639 function getType(ctor) {
5640 const match = ctor && ctor.toString().match(/^\s*(function|class) (\w+)/);
5641 return match ? match[2] : ctor === null ? 'null' : '';
5642 }
5643 function isSameType(a, b) {
5644 return getType(a) === getType(b);
5645 }
5646 function getTypeIndex(type, expectedTypes) {
5647 if (isArray(expectedTypes)) {
5648 return expectedTypes.findIndex(t => isSameType(t, type));
5649 }
5650 else if (isFunction(expectedTypes)) {
5651 return isSameType(expectedTypes, type) ? 0 : -1;
5652 }
5653 return -1;
5654 }
5655 /**
5656 * dev only
5657 */
5658 function validateProps(rawProps, props, instance) {
5659 const resolvedValues = toRaw(props);
5660 const options = instance.propsOptions[0];
5661 for (const key in options) {
5662 let opt = options[key];
5663 if (opt == null)
5664 continue;
5665 validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key)));
5666 }
5667 }
5668 /**
5669 * dev only
5670 */
5671 function validateProp(name, value, prop, isAbsent) {
5672 const { type, required, validator } = prop;
5673 // required!
5674 if (required && isAbsent) {
5675 warn('Missing required prop: "' + name + '"');
5676 return;
5677 }
5678 // missing but optional
5679 if (value == null && !prop.required) {
5680 return;
5681 }
5682 // type check
5683 if (type != null && type !== true) {
5684 let isValid = false;
5685 const types = isArray(type) ? type : [type];
5686 const expectedTypes = [];
5687 // value is valid as long as one of the specified types match
5688 for (let i = 0; i < types.length && !isValid; i++) {
5689 const { valid, expectedType } = assertType(value, types[i]);
5690 expectedTypes.push(expectedType || '');
5691 isValid = valid;
5692 }
5693 if (!isValid) {
5694 warn(getInvalidTypeMessage(name, value, expectedTypes));
5695 return;
5696 }
5697 }
5698 // custom validator
5699 if (validator && !validator(value)) {
5700 warn('Invalid prop: custom validator check failed for prop "' + name + '".');
5701 }
5702 }
5703 const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol,BigInt');
5704 /**
5705 * dev only
5706 */
5707 function assertType(value, type) {
5708 let valid;
5709 const expectedType = getType(type);
5710 if (isSimpleType(expectedType)) {
5711 const t = typeof value;
5712 valid = t === expectedType.toLowerCase();
5713 // for primitive wrapper objects
5714 if (!valid && t === 'object') {
5715 valid = value instanceof type;
5716 }
5717 }
5718 else if (expectedType === 'Object') {
5719 valid = isObject(value);
5720 }
5721 else if (expectedType === 'Array') {
5722 valid = isArray(value);
5723 }
5724 else if (expectedType === 'null') {
5725 valid = value === null;
5726 }
5727 else {
5728 valid = value instanceof type;
5729 }
5730 return {
5731 valid,
5732 expectedType
5733 };
5734 }
5735 /**
5736 * dev only
5737 */
5738 function getInvalidTypeMessage(name, value, expectedTypes) {
5739 let message = `Invalid prop: type check failed for prop "${name}".` +
5740 ` Expected ${expectedTypes.map(capitalize).join(' | ')}`;
5741 const expectedType = expectedTypes[0];
5742 const receivedType = toRawType(value);
5743 const expectedValue = styleValue(value, expectedType);
5744 const receivedValue = styleValue(value, receivedType);
5745 // check if we need to specify expected value
5746 if (expectedTypes.length === 1 &&
5747 isExplicable(expectedType) &&
5748 !isBoolean(expectedType, receivedType)) {
5749 message += ` with value ${expectedValue}`;
5750 }
5751 message += `, got ${receivedType} `;
5752 // check if we need to specify received value
5753 if (isExplicable(receivedType)) {
5754 message += `with value ${receivedValue}.`;
5755 }
5756 return message;
5757 }
5758 /**
5759 * dev only
5760 */
5761 function styleValue(value, type) {
5762 if (type === 'String') {
5763 return `"${value}"`;
5764 }
5765 else if (type === 'Number') {
5766 return `${Number(value)}`;
5767 }
5768 else {
5769 return `${value}`;
5770 }
5771 }
5772 /**
5773 * dev only
5774 */
5775 function isExplicable(type) {
5776 const explicitTypes = ['string', 'number', 'boolean'];
5777 return explicitTypes.some(elem => type.toLowerCase() === elem);
5778 }
5779 /**
5780 * dev only
5781 */
5782 function isBoolean(...args) {
5783 return args.some(elem => elem.toLowerCase() === 'boolean');
5784 }
5785
5786 const isInternalKey = (key) => key[0] === '_' || key === '$stable';
5787 const normalizeSlotValue = (value) => isArray(value)
5788 ? value.map(normalizeVNode)
5789 : [normalizeVNode(value)];
5790 const normalizeSlot = (key, rawSlot, ctx) => {
5791 if (rawSlot._n) {
5792 // already normalized - #5353
5793 return rawSlot;
5794 }
5795 const normalized = withCtx((...args) => {
5796 if (true && currentInstance) {
5797 warn(`Slot "${key}" invoked outside of the render function: ` +
5798 `this will not track dependencies used in the slot. ` +
5799 `Invoke the slot function inside the render function instead.`);
5800 }
5801 return normalizeSlotValue(rawSlot(...args));
5802 }, ctx);
5803 normalized._c = false;
5804 return normalized;
5805 };
5806 const normalizeObjectSlots = (rawSlots, slots, instance) => {
5807 const ctx = rawSlots._ctx;
5808 for (const key in rawSlots) {
5809 if (isInternalKey(key))
5810 continue;
5811 const value = rawSlots[key];
5812 if (isFunction(value)) {
5813 slots[key] = normalizeSlot(key, value, ctx);
5814 }
5815 else if (value != null) {
5816 {
5817 warn(`Non-function value encountered for slot "${key}". ` +
5818 `Prefer function slots for better performance.`);
5819 }
5820 const normalized = normalizeSlotValue(value);
5821 slots[key] = () => normalized;
5822 }
5823 }
5824 };
5825 const normalizeVNodeSlots = (instance, children) => {
5826 if (!isKeepAlive(instance.vnode) &&
5827 !(false )) {
5828 warn(`Non-function value encountered for default slot. ` +
5829 `Prefer function slots for better performance.`);
5830 }
5831 const normalized = normalizeSlotValue(children);
5832 instance.slots.default = () => normalized;
5833 };
5834 const initSlots = (instance, children) => {
5835 if (instance.vnode.shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */) {
5836 const type = children._;
5837 if (type) {
5838 // users can get the shallow readonly version of the slots object through `this.$slots`,
5839 // we should avoid the proxy object polluting the slots of the internal instance
5840 instance.slots = toRaw(children);
5841 // make compiler marker non-enumerable
5842 def(children, '_', type);
5843 }
5844 else {
5845 normalizeObjectSlots(children, (instance.slots = {}));
5846 }
5847 }
5848 else {
5849 instance.slots = {};
5850 if (children) {
5851 normalizeVNodeSlots(instance, children);
5852 }
5853 }
5854 def(instance.slots, InternalObjectKey, 1);
5855 };
5856 const updateSlots = (instance, children, optimized) => {
5857 const { vnode, slots } = instance;
5858 let needDeletionCheck = true;
5859 let deletionComparisonTarget = EMPTY_OBJ;
5860 if (vnode.shapeFlag & 32 /* ShapeFlags.SLOTS_CHILDREN */) {
5861 const type = children._;
5862 if (type) {
5863 // compiled slots.
5864 if (isHmrUpdating) {
5865 // Parent was HMR updated so slot content may have changed.
5866 // force update slots and mark instance for hmr as well
5867 extend(slots, children);
5868 }
5869 else if (optimized && type === 1 /* SlotFlags.STABLE */) {
5870 // compiled AND stable.
5871 // no need to update, and skip stale slots removal.
5872 needDeletionCheck = false;
5873 }
5874 else {
5875 // compiled but dynamic (v-if/v-for on slots) - update slots, but skip
5876 // normalization.
5877 extend(slots, children);
5878 // #2893
5879 // when rendering the optimized slots by manually written render function,
5880 // we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
5881 // i.e. let the `renderSlot` create the bailed Fragment
5882 if (!optimized && type === 1 /* SlotFlags.STABLE */) {
5883 delete slots._;
5884 }
5885 }
5886 }
5887 else {
5888 needDeletionCheck = !children.$stable;
5889 normalizeObjectSlots(children, slots);
5890 }
5891 deletionComparisonTarget = children;
5892 }
5893 else if (children) {
5894 // non slot object children (direct value) passed to a component
5895 normalizeVNodeSlots(instance, children);
5896 deletionComparisonTarget = { default: 1 };
5897 }
5898 // delete stale slots
5899 if (needDeletionCheck) {
5900 for (const key in slots) {
5901 if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
5902 delete slots[key];
5903 }
5904 }
5905 }
5906 };
5907
5908 function createAppContext() {
5909 return {
5910 app: null,
5911 config: {
5912 isNativeTag: NO,
5913 performance: false,
5914 globalProperties: {},
5915 optionMergeStrategies: {},
5916 errorHandler: undefined,
5917 warnHandler: undefined,
5918 compilerOptions: {}
5919 },
5920 mixins: [],
5921 components: {},
5922 directives: {},
5923 provides: Object.create(null),
5924 optionsCache: new WeakMap(),
5925 propsCache: new WeakMap(),
5926 emitsCache: new WeakMap()
5927 };
5928 }
5929 let uid$1 = 0;
5930 function createAppAPI(render, hydrate) {
5931 return function createApp(rootComponent, rootProps = null) {
5932 if (!isFunction(rootComponent)) {
5933 rootComponent = Object.assign({}, rootComponent);
5934 }
5935 if (rootProps != null && !isObject(rootProps)) {
5936 warn(`root props passed to app.mount() must be an object.`);
5937 rootProps = null;
5938 }
5939 const context = createAppContext();
5940 const installedPlugins = new Set();
5941 let isMounted = false;
5942 const app = (context.app = {
5943 _uid: uid$1++,
5944 _component: rootComponent,
5945 _props: rootProps,
5946 _container: null,
5947 _context: context,
5948 _instance: null,
5949 version,
5950 get config() {
5951 return context.config;
5952 },
5953 set config(v) {
5954 {
5955 warn(`app.config cannot be replaced. Modify individual options instead.`);
5956 }
5957 },
5958 use(plugin, ...options) {
5959 if (installedPlugins.has(plugin)) {
5960 warn(`Plugin has already been applied to target app.`);
5961 }
5962 else if (plugin && isFunction(plugin.install)) {
5963 installedPlugins.add(plugin);
5964 plugin.install(app, ...options);
5965 }
5966 else if (isFunction(plugin)) {
5967 installedPlugins.add(plugin);
5968 plugin(app, ...options);
5969 }
5970 else {
5971 warn(`A plugin must either be a function or an object with an "install" ` +
5972 `function.`);
5973 }
5974 return app;
5975 },
5976 mixin(mixin) {
5977 {
5978 if (!context.mixins.includes(mixin)) {
5979 context.mixins.push(mixin);
5980 }
5981 else {
5982 warn('Mixin has already been applied to target app' +
5983 (mixin.name ? `: ${mixin.name}` : ''));
5984 }
5985 }
5986 return app;
5987 },
5988 component(name, component) {
5989 {
5990 validateComponentName(name, context.config);
5991 }
5992 if (!component) {
5993 return context.components[name];
5994 }
5995 if (context.components[name]) {
5996 warn(`Component "${name}" has already been registered in target app.`);
5997 }
5998 context.components[name] = component;
5999 return app;
6000 },
6001 directive(name, directive) {
6002 {
6003 validateDirectiveName(name);
6004 }
6005 if (!directive) {
6006 return context.directives[name];
6007 }
6008 if (context.directives[name]) {
6009 warn(`Directive "${name}" has already been registered in target app.`);
6010 }
6011 context.directives[name] = directive;
6012 return app;
6013 },
6014 mount(rootContainer, isHydrate, isSVG) {
6015 if (!isMounted) {
6016 // #5571
6017 if (rootContainer.__vue_app__) {
6018 warn(`There is already an app instance mounted on the host container.\n` +
6019 ` If you want to mount another app on the same host container,` +
6020 ` you need to unmount the previous app by calling \`app.unmount()\` first.`);
6021 }
6022 const vnode = createVNode(rootComponent, rootProps);
6023 // store app context on the root VNode.
6024 // this will be set on the root instance on initial mount.
6025 vnode.appContext = context;
6026 // HMR root reload
6027 {
6028 context.reload = () => {
6029 render(cloneVNode(vnode), rootContainer, isSVG);
6030 };
6031 }
6032 if (isHydrate && hydrate) {
6033 hydrate(vnode, rootContainer);
6034 }
6035 else {
6036 render(vnode, rootContainer, isSVG);
6037 }
6038 isMounted = true;
6039 app._container = rootContainer;
6040 rootContainer.__vue_app__ = app;
6041 {
6042 app._instance = vnode.component;
6043 devtoolsInitApp(app, version);
6044 }
6045 return getExposeProxy(vnode.component) || vnode.component.proxy;
6046 }
6047 else {
6048 warn(`App has already been mounted.\n` +
6049 `If you want to remount the same app, move your app creation logic ` +
6050 `into a factory function and create fresh app instances for each ` +
6051 `mount - e.g. \`const createMyApp = () => createApp(App)\``);
6052 }
6053 },
6054 unmount() {
6055 if (isMounted) {
6056 render(null, app._container);
6057 {
6058 app._instance = null;
6059 devtoolsUnmountApp(app);
6060 }
6061 delete app._container.__vue_app__;
6062 }
6063 else {
6064 warn(`Cannot unmount an app that is not mounted.`);
6065 }
6066 },
6067 provide(key, value) {
6068 if (key in context.provides) {
6069 warn(`App already provides property with key "${String(key)}". ` +
6070 `It will be overwritten with the new value.`);
6071 }
6072 context.provides[key] = value;
6073 return app;
6074 }
6075 });
6076 return app;
6077 };
6078 }
6079
6080 /**
6081 * Function for handling a template ref
6082 */
6083 function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6084 if (isArray(rawRef)) {
6085 rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6086 return;
6087 }
6088 if (isAsyncWrapper(vnode) && !isUnmount) {
6089 // when mounting async components, nothing needs to be done,
6090 // because the template ref is forwarded to inner component
6091 return;
6092 }
6093 const refValue = vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */
6094 ? getExposeProxy(vnode.component) || vnode.component.proxy
6095 : vnode.el;
6096 const value = isUnmount ? null : refValue;
6097 const { i: owner, r: ref } = rawRef;
6098 if (!owner) {
6099 warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
6100 `A vnode with ref must be created inside the render function.`);
6101 return;
6102 }
6103 const oldRef = oldRawRef && oldRawRef.r;
6104 const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6105 const setupState = owner.setupState;
6106 // dynamic ref changed. unset old ref
6107 if (oldRef != null && oldRef !== ref) {
6108 if (isString(oldRef)) {
6109 refs[oldRef] = null;
6110 if (hasOwn(setupState, oldRef)) {
6111 setupState[oldRef] = null;
6112 }
6113 }
6114 else if (isRef(oldRef)) {
6115 oldRef.value = null;
6116 }
6117 }
6118 if (isFunction(ref)) {
6119 callWithErrorHandling(ref, owner, 12 /* ErrorCodes.FUNCTION_REF */, [value, refs]);
6120 }
6121 else {
6122 const _isString = isString(ref);
6123 const _isRef = isRef(ref);
6124 if (_isString || _isRef) {
6125 const doSet = () => {
6126 if (rawRef.f) {
6127 const existing = _isString
6128 ? hasOwn(setupState, ref)
6129 ? setupState[ref]
6130 : refs[ref]
6131 : ref.value;
6132 if (isUnmount) {
6133 isArray(existing) && remove(existing, refValue);
6134 }
6135 else {
6136 if (!isArray(existing)) {
6137 if (_isString) {
6138 refs[ref] = [refValue];
6139 if (hasOwn(setupState, ref)) {
6140 setupState[ref] = refs[ref];
6141 }
6142 }
6143 else {
6144 ref.value = [refValue];
6145 if (rawRef.k)
6146 refs[rawRef.k] = ref.value;
6147 }
6148 }
6149 else if (!existing.includes(refValue)) {
6150 existing.push(refValue);
6151 }
6152 }
6153 }
6154 else if (_isString) {
6155 refs[ref] = value;
6156 if (hasOwn(setupState, ref)) {
6157 setupState[ref] = value;
6158 }
6159 }
6160 else if (_isRef) {
6161 ref.value = value;
6162 if (rawRef.k)
6163 refs[rawRef.k] = value;
6164 }
6165 else {
6166 warn('Invalid template ref type:', ref, `(${typeof ref})`);
6167 }
6168 };
6169 if (value) {
6170 doSet.id = -1;
6171 queuePostRenderEffect(doSet, parentSuspense);
6172 }
6173 else {
6174 doSet();
6175 }
6176 }
6177 else {
6178 warn('Invalid template ref type:', ref, `(${typeof ref})`);
6179 }
6180 }
6181 }
6182
6183 let hasMismatch = false;
6184 const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
6185 const isComment = (node) => node.nodeType === 8 /* DOMNodeTypes.COMMENT */;
6186 // Note: hydration is DOM-specific
6187 // But we have to place it in core due to tight coupling with core - splitting
6188 // it out creates a ton of unnecessary complexity.
6189 // Hydration also depends on some renderer internal logic which needs to be
6190 // passed in via arguments.
6191 function createHydrationFunctions(rendererInternals) {
6192 const { mt: mountComponent, p: patch, o: { patchProp, createText, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
6193 const hydrate = (vnode, container) => {
6194 if (!container.hasChildNodes()) {
6195 warn(`Attempting to hydrate existing markup but container is empty. ` +
6196 `Performing full mount instead.`);
6197 patch(null, vnode, container);
6198 flushPostFlushCbs();
6199 container._vnode = vnode;
6200 return;
6201 }
6202 hasMismatch = false;
6203 hydrateNode(container.firstChild, vnode, null, null, null);
6204 flushPostFlushCbs();
6205 container._vnode = vnode;
6206 if (hasMismatch && !false) {
6207 // this error should show up in production
6208 console.error(`Hydration completed but contains mismatches.`);
6209 }
6210 };
6211 const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
6212 const isFragmentStart = isComment(node) && node.data === '[';
6213 const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
6214 const { type, ref, shapeFlag, patchFlag } = vnode;
6215 let domType = node.nodeType;
6216 vnode.el = node;
6217 if (patchFlag === -2 /* PatchFlags.BAIL */) {
6218 optimized = false;
6219 vnode.dynamicChildren = null;
6220 }
6221 let nextNode = null;
6222 switch (type) {
6223 case Text:
6224 if (domType !== 3 /* DOMNodeTypes.TEXT */) {
6225 // #5728 empty text node inside a slot can cause hydration failure
6226 // because the server rendered HTML won't contain a text node
6227 if (vnode.children === '') {
6228 insert((vnode.el = createText('')), parentNode(node), node);
6229 nextNode = node;
6230 }
6231 else {
6232 nextNode = onMismatch();
6233 }
6234 }
6235 else {
6236 if (node.data !== vnode.children) {
6237 hasMismatch = true;
6238 warn(`Hydration text mismatch:` +
6239 `\n- Client: ${JSON.stringify(node.data)}` +
6240 `\n- Server: ${JSON.stringify(vnode.children)}`);
6241 node.data = vnode.children;
6242 }
6243 nextNode = nextSibling(node);
6244 }
6245 break;
6246 case Comment:
6247 if (domType !== 8 /* DOMNodeTypes.COMMENT */ || isFragmentStart) {
6248 nextNode = onMismatch();
6249 }
6250 else {
6251 nextNode = nextSibling(node);
6252 }
6253 break;
6254 case Static:
6255 if (isFragmentStart) {
6256 // entire template is static but SSRed as a fragment
6257 node = nextSibling(node);
6258 domType = node.nodeType;
6259 }
6260 if (domType === 1 /* DOMNodeTypes.ELEMENT */ || domType === 3 /* DOMNodeTypes.TEXT */) {
6261 // determine anchor, adopt content
6262 nextNode = node;
6263 // if the static vnode has its content stripped during build,
6264 // adopt it from the server-rendered HTML.
6265 const needToAdoptContent = !vnode.children.length;
6266 for (let i = 0; i < vnode.staticCount; i++) {
6267 if (needToAdoptContent)
6268 vnode.children +=
6269 nextNode.nodeType === 1 /* DOMNodeTypes.ELEMENT */
6270 ? nextNode.outerHTML
6271 : nextNode.data;
6272 if (i === vnode.staticCount - 1) {
6273 vnode.anchor = nextNode;
6274 }
6275 nextNode = nextSibling(nextNode);
6276 }
6277 return isFragmentStart ? nextSibling(nextNode) : nextNode;
6278 }
6279 else {
6280 onMismatch();
6281 }
6282 break;
6283 case Fragment:
6284 if (!isFragmentStart) {
6285 nextNode = onMismatch();
6286 }
6287 else {
6288 nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6289 }
6290 break;
6291 default:
6292 if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
6293 if (domType !== 1 /* DOMNodeTypes.ELEMENT */ ||
6294 vnode.type.toLowerCase() !==
6295 node.tagName.toLowerCase()) {
6296 nextNode = onMismatch();
6297 }
6298 else {
6299 nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6300 }
6301 }
6302 else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
6303 // when setting up the render effect, if the initial vnode already
6304 // has .el set, the component will perform hydration instead of mount
6305 // on its sub-tree.
6306 vnode.slotScopeIds = slotScopeIds;
6307 const container = parentNode(node);
6308 mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
6309 // component may be async, so in the case of fragments we cannot rely
6310 // on component's rendered output to determine the end of the fragment
6311 // instead, we do a lookahead to find the end anchor node.
6312 nextNode = isFragmentStart
6313 ? locateClosingAsyncAnchor(node)
6314 : nextSibling(node);
6315 // #4293 teleport as component root
6316 if (nextNode &&
6317 isComment(nextNode) &&
6318 nextNode.data === 'teleport end') {
6319 nextNode = nextSibling(nextNode);
6320 }
6321 // #3787
6322 // if component is async, it may get moved / unmounted before its
6323 // inner component is loaded, so we need to give it a placeholder
6324 // vnode that matches its adopted DOM.
6325 if (isAsyncWrapper(vnode)) {
6326 let subTree;
6327 if (isFragmentStart) {
6328 subTree = createVNode(Fragment);
6329 subTree.anchor = nextNode
6330 ? nextNode.previousSibling
6331 : container.lastChild;
6332 }
6333 else {
6334 subTree =
6335 node.nodeType === 3 ? createTextVNode('') : createVNode('div');
6336 }
6337 subTree.el = node;
6338 vnode.component.subTree = subTree;
6339 }
6340 }
6341 else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
6342 if (domType !== 8 /* DOMNodeTypes.COMMENT */) {
6343 nextNode = onMismatch();
6344 }
6345 else {
6346 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
6347 }
6348 }
6349 else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
6350 nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
6351 }
6352 else {
6353 warn('Invalid HostVNode type:', type, `(${typeof type})`);
6354 }
6355 }
6356 if (ref != null) {
6357 setRef(ref, null, parentSuspense, vnode);
6358 }
6359 return nextNode;
6360 };
6361 const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6362 optimized = optimized || !!vnode.dynamicChildren;
6363 const { type, props, patchFlag, shapeFlag, dirs } = vnode;
6364 // #4006 for form elements with non-string v-model value bindings
6365 // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
6366 const forcePatchValue = (type === 'input' && dirs) || type === 'option';
6367 // skip props & children if this is hoisted static nodes
6368 // #5405 in dev, always hydrate children for HMR
6369 {
6370 if (dirs) {
6371 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6372 }
6373 // props
6374 if (props) {
6375 if (forcePatchValue ||
6376 !optimized ||
6377 patchFlag & (16 /* PatchFlags.FULL_PROPS */ | 32 /* PatchFlags.HYDRATE_EVENTS */)) {
6378 for (const key in props) {
6379 if ((forcePatchValue && key.endsWith('value')) ||
6380 (isOn(key) && !isReservedProp(key))) {
6381 patchProp(el, key, null, props[key], false, undefined, parentComponent);
6382 }
6383 }
6384 }
6385 else if (props.onClick) {
6386 // Fast path for click listeners (which is most often) to avoid
6387 // iterating through props.
6388 patchProp(el, 'onClick', null, props.onClick, false, undefined, parentComponent);
6389 }
6390 }
6391 // vnode / directive hooks
6392 let vnodeHooks;
6393 if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
6394 invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6395 }
6396 if (dirs) {
6397 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6398 }
6399 if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
6400 queueEffectWithSuspense(() => {
6401 vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
6402 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6403 }, parentSuspense);
6404 }
6405 // children
6406 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */ &&
6407 // skip if element has innerHTML / textContent
6408 !(props && (props.innerHTML || props.textContent))) {
6409 let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
6410 let hasWarned = false;
6411 while (next) {
6412 hasMismatch = true;
6413 if (!hasWarned) {
6414 warn(`Hydration children mismatch in <${vnode.type}>: ` +
6415 `server rendered element contains more child nodes than client vdom.`);
6416 hasWarned = true;
6417 }
6418 // The SSRed DOM contains more nodes than it should. Remove them.
6419 const cur = next;
6420 next = next.nextSibling;
6421 remove(cur);
6422 }
6423 }
6424 else if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
6425 if (el.textContent !== vnode.children) {
6426 hasMismatch = true;
6427 warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
6428 `- Client: ${el.textContent}\n` +
6429 `- Server: ${vnode.children}`);
6430 el.textContent = vnode.children;
6431 }
6432 }
6433 }
6434 return el.nextSibling;
6435 };
6436 const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6437 optimized = optimized || !!parentVNode.dynamicChildren;
6438 const children = parentVNode.children;
6439 const l = children.length;
6440 let hasWarned = false;
6441 for (let i = 0; i < l; i++) {
6442 const vnode = optimized
6443 ? children[i]
6444 : (children[i] = normalizeVNode(children[i]));
6445 if (node) {
6446 node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
6447 }
6448 else if (vnode.type === Text && !vnode.children) {
6449 continue;
6450 }
6451 else {
6452 hasMismatch = true;
6453 if (!hasWarned) {
6454 warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
6455 `server rendered element contains fewer child nodes than client vdom.`);
6456 hasWarned = true;
6457 }
6458 // the SSRed DOM didn't contain enough nodes. Mount the missing ones.
6459 patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6460 }
6461 }
6462 return node;
6463 };
6464 const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
6465 const { slotScopeIds: fragmentSlotScopeIds } = vnode;
6466 if (fragmentSlotScopeIds) {
6467 slotScopeIds = slotScopeIds
6468 ? slotScopeIds.concat(fragmentSlotScopeIds)
6469 : fragmentSlotScopeIds;
6470 }
6471 const container = parentNode(node);
6472 const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
6473 if (next && isComment(next) && next.data === ']') {
6474 return nextSibling((vnode.anchor = next));
6475 }
6476 else {
6477 // fragment didn't hydrate successfully, since we didn't get a end anchor
6478 // back. This should have led to node/children mismatch warnings.
6479 hasMismatch = true;
6480 // since the anchor is missing, we need to create one and insert it
6481 insert((vnode.anchor = createComment(`]`)), container, next);
6482 return next;
6483 }
6484 };
6485 const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
6486 hasMismatch = true;
6487 warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* DOMNodeTypes.TEXT */
6488 ? `(text)`
6489 : isComment(node) && node.data === '['
6490 ? `(start of fragment)`
6491 : ``);
6492 vnode.el = null;
6493 if (isFragment) {
6494 // remove excessive fragment nodes
6495 const end = locateClosingAsyncAnchor(node);
6496 while (true) {
6497 const next = nextSibling(node);
6498 if (next && next !== end) {
6499 remove(next);
6500 }
6501 else {
6502 break;
6503 }
6504 }
6505 }
6506 const next = nextSibling(node);
6507 const container = parentNode(node);
6508 remove(node);
6509 patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
6510 return next;
6511 };
6512 const locateClosingAsyncAnchor = (node) => {
6513 let match = 0;
6514 while (node) {
6515 node = nextSibling(node);
6516 if (node && isComment(node)) {
6517 if (node.data === '[')
6518 match++;
6519 if (node.data === ']') {
6520 if (match === 0) {
6521 return nextSibling(node);
6522 }
6523 else {
6524 match--;
6525 }
6526 }
6527 }
6528 }
6529 return node;
6530 };
6531 return [hydrate, hydrateNode];
6532 }
6533
6534 /* eslint-disable no-restricted-globals */
6535 let supported;
6536 let perf;
6537 function startMeasure(instance, type) {
6538 if (instance.appContext.config.performance && isSupported()) {
6539 perf.mark(`vue-${type}-${instance.uid}`);
6540 }
6541 {
6542 devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now());
6543 }
6544 }
6545 function endMeasure(instance, type) {
6546 if (instance.appContext.config.performance && isSupported()) {
6547 const startTag = `vue-${type}-${instance.uid}`;
6548 const endTag = startTag + `:end`;
6549 perf.mark(endTag);
6550 perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
6551 perf.clearMarks(startTag);
6552 perf.clearMarks(endTag);
6553 }
6554 {
6555 devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now());
6556 }
6557 }
6558 function isSupported() {
6559 if (supported !== undefined) {
6560 return supported;
6561 }
6562 if (typeof window !== 'undefined' && window.performance) {
6563 supported = true;
6564 perf = window.performance;
6565 }
6566 else {
6567 supported = false;
6568 }
6569 return supported;
6570 }
6571
6572 const queuePostRenderEffect = queueEffectWithSuspense
6573 ;
6574 /**
6575 * The createRenderer function accepts two generic arguments:
6576 * HostNode and HostElement, corresponding to Node and Element types in the
6577 * host environment. For example, for runtime-dom, HostNode would be the DOM
6578 * `Node` interface and HostElement would be the DOM `Element` interface.
6579 *
6580 * Custom renderers can pass in the platform specific types like this:
6581 *
6582 * ``` js
6583 * const { render, createApp } = createRenderer<Node, Element>({
6584 * patchProp,
6585 * ...nodeOps
6586 * })
6587 * ```
6588 */
6589 function createRenderer(options) {
6590 return baseCreateRenderer(options);
6591 }
6592 // Separate API for creating hydration-enabled renderer.
6593 // Hydration logic is only used when calling this function, making it
6594 // tree-shakable.
6595 function createHydrationRenderer(options) {
6596 return baseCreateRenderer(options, createHydrationFunctions);
6597 }
6598 // implementation
6599 function baseCreateRenderer(options, createHydrationFns) {
6600 const target = getGlobalThis();
6601 target.__VUE__ = true;
6602 {
6603 setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
6604 }
6605 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;
6606 // Note: functions inside this closure should use `const xxx = () => {}`
6607 // style in order to prevent being inlined by minifiers.
6608 const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = isHmrUpdating ? false : !!n2.dynamicChildren) => {
6609 if (n1 === n2) {
6610 return;
6611 }
6612 // patching & not same type, unmount old tree
6613 if (n1 && !isSameVNodeType(n1, n2)) {
6614 anchor = getNextHostNode(n1);
6615 unmount(n1, parentComponent, parentSuspense, true);
6616 n1 = null;
6617 }
6618 if (n2.patchFlag === -2 /* PatchFlags.BAIL */) {
6619 optimized = false;
6620 n2.dynamicChildren = null;
6621 }
6622 const { type, ref, shapeFlag } = n2;
6623 switch (type) {
6624 case Text:
6625 processText(n1, n2, container, anchor);
6626 break;
6627 case Comment:
6628 processCommentNode(n1, n2, container, anchor);
6629 break;
6630 case Static:
6631 if (n1 == null) {
6632 mountStaticNode(n2, container, anchor, isSVG);
6633 }
6634 else {
6635 patchStaticNode(n1, n2, container, isSVG);
6636 }
6637 break;
6638 case Fragment:
6639 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6640 break;
6641 default:
6642 if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
6643 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6644 }
6645 else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
6646 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6647 }
6648 else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
6649 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6650 }
6651 else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
6652 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
6653 }
6654 else {
6655 warn('Invalid VNode type:', type, `(${typeof type})`);
6656 }
6657 }
6658 // set ref
6659 if (ref != null && parentComponent) {
6660 setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
6661 }
6662 };
6663 const processText = (n1, n2, container, anchor) => {
6664 if (n1 == null) {
6665 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
6666 }
6667 else {
6668 const el = (n2.el = n1.el);
6669 if (n2.children !== n1.children) {
6670 hostSetText(el, n2.children);
6671 }
6672 }
6673 };
6674 const processCommentNode = (n1, n2, container, anchor) => {
6675 if (n1 == null) {
6676 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
6677 }
6678 else {
6679 // there's no support for dynamic comments
6680 n2.el = n1.el;
6681 }
6682 };
6683 const mountStaticNode = (n2, container, anchor, isSVG) => {
6684 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG, n2.el, n2.anchor);
6685 };
6686 /**
6687 * Dev / HMR only
6688 */
6689 const patchStaticNode = (n1, n2, container, isSVG) => {
6690 // static nodes are only patched during dev for HMR
6691 if (n2.children !== n1.children) {
6692 const anchor = hostNextSibling(n1.anchor);
6693 // remove existing
6694 removeStaticNode(n1);
6695 [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
6696 }
6697 else {
6698 n2.el = n1.el;
6699 n2.anchor = n1.anchor;
6700 }
6701 };
6702 const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
6703 let next;
6704 while (el && el !== anchor) {
6705 next = hostNextSibling(el);
6706 hostInsert(el, container, nextSibling);
6707 el = next;
6708 }
6709 hostInsert(anchor, container, nextSibling);
6710 };
6711 const removeStaticNode = ({ el, anchor }) => {
6712 let next;
6713 while (el && el !== anchor) {
6714 next = hostNextSibling(el);
6715 hostRemove(el);
6716 el = next;
6717 }
6718 hostRemove(anchor);
6719 };
6720 const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6721 isSVG = isSVG || n2.type === 'svg';
6722 if (n1 == null) {
6723 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6724 }
6725 else {
6726 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6727 }
6728 };
6729 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6730 let el;
6731 let vnodeHook;
6732 const { type, props, shapeFlag, transition, dirs } = vnode;
6733 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6734 // mount children first, since some props may rely on child content
6735 // being already rendered, e.g. `<select value>`
6736 if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
6737 hostSetElementText(el, vnode.children);
6738 }
6739 else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
6740 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6741 }
6742 if (dirs) {
6743 invokeDirectiveHook(vnode, null, parentComponent, 'created');
6744 }
6745 // scopeId
6746 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6747 // props
6748 if (props) {
6749 for (const key in props) {
6750 if (key !== 'value' && !isReservedProp(key)) {
6751 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6752 }
6753 }
6754 /**
6755 * Special case for setting value on DOM elements:
6756 * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6757 * - it needs to be forced (#1471)
6758 * #2353 proposes adding another renderer option to configure this, but
6759 * the properties affects are so finite it is worth special casing it
6760 * here to reduce the complexity. (Special casing it also should not
6761 * affect non-DOM renderers)
6762 */
6763 if ('value' in props) {
6764 hostPatchProp(el, 'value', null, props.value);
6765 }
6766 if ((vnodeHook = props.onVnodeBeforeMount)) {
6767 invokeVNodeHook(vnodeHook, parentComponent, vnode);
6768 }
6769 }
6770 {
6771 Object.defineProperty(el, '__vnode', {
6772 value: vnode,
6773 enumerable: false
6774 });
6775 Object.defineProperty(el, '__vueParentComponent', {
6776 value: parentComponent,
6777 enumerable: false
6778 });
6779 }
6780 if (dirs) {
6781 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6782 }
6783 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
6784 // #1689 For inside suspense + suspense resolved case, just call it
6785 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
6786 transition &&
6787 !transition.persisted;
6788 if (needCallTransitionHooks) {
6789 transition.beforeEnter(el);
6790 }
6791 hostInsert(el, container, anchor);
6792 if ((vnodeHook = props && props.onVnodeMounted) ||
6793 needCallTransitionHooks ||
6794 dirs) {
6795 queuePostRenderEffect(() => {
6796 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
6797 needCallTransitionHooks && transition.enter(el);
6798 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
6799 }, parentSuspense);
6800 }
6801 };
6802 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
6803 if (scopeId) {
6804 hostSetScopeId(el, scopeId);
6805 }
6806 if (slotScopeIds) {
6807 for (let i = 0; i < slotScopeIds.length; i++) {
6808 hostSetScopeId(el, slotScopeIds[i]);
6809 }
6810 }
6811 if (parentComponent) {
6812 let subTree = parentComponent.subTree;
6813 if (subTree.patchFlag > 0 &&
6814 subTree.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */) {
6815 subTree =
6816 filterSingleRoot(subTree.children) || subTree;
6817 }
6818 if (vnode === subTree) {
6819 const parentVNode = parentComponent.vnode;
6820 setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
6821 }
6822 }
6823 };
6824 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
6825 for (let i = start; i < children.length; i++) {
6826 const child = (children[i] = optimized
6827 ? cloneIfMounted(children[i])
6828 : normalizeVNode(children[i]));
6829 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
6830 }
6831 };
6832 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6833 const el = (n2.el = n1.el);
6834 let { patchFlag, dynamicChildren, dirs } = n2;
6835 // #1426 take the old vnode's patch flag into account since user may clone a
6836 // compiler-generated vnode, which de-opts to FULL_PROPS
6837 patchFlag |= n1.patchFlag & 16 /* PatchFlags.FULL_PROPS */;
6838 const oldProps = n1.props || EMPTY_OBJ;
6839 const newProps = n2.props || EMPTY_OBJ;
6840 let vnodeHook;
6841 // disable recurse in beforeUpdate hooks
6842 parentComponent && toggleRecurse(parentComponent, false);
6843 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6844 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6845 }
6846 if (dirs) {
6847 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6848 }
6849 parentComponent && toggleRecurse(parentComponent, true);
6850 if (isHmrUpdating) {
6851 // HMR updated, force full diff
6852 patchFlag = 0;
6853 optimized = false;
6854 dynamicChildren = null;
6855 }
6856 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
6857 if (dynamicChildren) {
6858 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
6859 if (parentComponent && parentComponent.type.__hmrId) {
6860 traverseStaticChildren(n1, n2);
6861 }
6862 }
6863 else if (!optimized) {
6864 // full diff
6865 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
6866 }
6867 if (patchFlag > 0) {
6868 // the presence of a patchFlag means this element's render code was
6869 // generated by the compiler and can take the fast path.
6870 // in this path old node and new node are guaranteed to have the same shape
6871 // (i.e. at the exact same position in the source template)
6872 if (patchFlag & 16 /* PatchFlags.FULL_PROPS */) {
6873 // element props contain dynamic keys, full diff needed
6874 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6875 }
6876 else {
6877 // class
6878 // this flag is matched when the element has dynamic class bindings.
6879 if (patchFlag & 2 /* PatchFlags.CLASS */) {
6880 if (oldProps.class !== newProps.class) {
6881 hostPatchProp(el, 'class', null, newProps.class, isSVG);
6882 }
6883 }
6884 // style
6885 // this flag is matched when the element has dynamic style bindings
6886 if (patchFlag & 4 /* PatchFlags.STYLE */) {
6887 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
6888 }
6889 // props
6890 // This flag is matched when the element has dynamic prop/attr bindings
6891 // other than class and style. The keys of dynamic prop/attrs are saved for
6892 // faster iteration.
6893 // Note dynamic keys like :[foo]="bar" will cause this optimization to
6894 // bail out and go through a full diff because we need to unset the old key
6895 if (patchFlag & 8 /* PatchFlags.PROPS */) {
6896 // if the flag is present then dynamicProps must be non-null
6897 const propsToUpdate = n2.dynamicProps;
6898 for (let i = 0; i < propsToUpdate.length; i++) {
6899 const key = propsToUpdate[i];
6900 const prev = oldProps[key];
6901 const next = newProps[key];
6902 // #1471 force patch value
6903 if (next !== prev || key === 'value') {
6904 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
6905 }
6906 }
6907 }
6908 }
6909 // text
6910 // This flag is matched when the element has only dynamic text children.
6911 if (patchFlag & 1 /* PatchFlags.TEXT */) {
6912 if (n1.children !== n2.children) {
6913 hostSetElementText(el, n2.children);
6914 }
6915 }
6916 }
6917 else if (!optimized && dynamicChildren == null) {
6918 // unoptimized, full diff
6919 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
6920 }
6921 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
6922 queuePostRenderEffect(() => {
6923 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6924 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
6925 }, parentSuspense);
6926 }
6927 };
6928 // The fast path for blocks.
6929 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
6930 for (let i = 0; i < newChildren.length; i++) {
6931 const oldVNode = oldChildren[i];
6932 const newVNode = newChildren[i];
6933 // Determine the container (parent element) for the patch.
6934 const container =
6935 // oldVNode may be an errored async setup() component inside Suspense
6936 // which will not have a mounted element
6937 oldVNode.el &&
6938 // - In the case of a Fragment, we need to provide the actual parent
6939 // of the Fragment itself so it can move its children.
6940 (oldVNode.type === Fragment ||
6941 // - In the case of different nodes, there is going to be a replacement
6942 // which also requires the correct parent container
6943 !isSameVNodeType(oldVNode, newVNode) ||
6944 // - In the case of a component, it could contain anything.
6945 oldVNode.shapeFlag & (6 /* ShapeFlags.COMPONENT */ | 64 /* ShapeFlags.TELEPORT */))
6946 ? hostParentNode(oldVNode.el)
6947 : // In other cases, the parent container is not actually used so we
6948 // just pass the block element here to avoid a DOM parentNode call.
6949 fallbackContainer;
6950 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
6951 }
6952 };
6953 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
6954 if (oldProps !== newProps) {
6955 if (oldProps !== EMPTY_OBJ) {
6956 for (const key in oldProps) {
6957 if (!isReservedProp(key) && !(key in newProps)) {
6958 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6959 }
6960 }
6961 }
6962 for (const key in newProps) {
6963 // empty string is not valid prop
6964 if (isReservedProp(key))
6965 continue;
6966 const next = newProps[key];
6967 const prev = oldProps[key];
6968 // defer patching value
6969 if (next !== prev && key !== 'value') {
6970 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6971 }
6972 }
6973 if ('value' in newProps) {
6974 hostPatchProp(el, 'value', oldProps.value, newProps.value);
6975 }
6976 }
6977 };
6978 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6979 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
6980 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
6981 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
6982 if (// #5523 dev root fragment may inherit directives
6983 (isHmrUpdating || patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */)) {
6984 // HMR updated / Dev root fragment (w/ comments), force full diff
6985 patchFlag = 0;
6986 optimized = false;
6987 dynamicChildren = null;
6988 }
6989 // check if this is a slot fragment with :slotted scope ids
6990 if (fragmentSlotScopeIds) {
6991 slotScopeIds = slotScopeIds
6992 ? slotScopeIds.concat(fragmentSlotScopeIds)
6993 : fragmentSlotScopeIds;
6994 }
6995 if (n1 == null) {
6996 hostInsert(fragmentStartAnchor, container, anchor);
6997 hostInsert(fragmentEndAnchor, container, anchor);
6998 // a fragment can only have array children
6999 // since they are either generated by the compiler, or implicitly created
7000 // from arrays.
7001 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7002 }
7003 else {
7004 if (patchFlag > 0 &&
7005 patchFlag & 64 /* PatchFlags.STABLE_FRAGMENT */ &&
7006 dynamicChildren &&
7007 // #2715 the previous fragment could've been a BAILed one as a result
7008 // of renderSlot() with no valid children
7009 n1.dynamicChildren) {
7010 // a stable fragment (template root or <template v-for>) doesn't need to
7011 // patch children order, but it may contain dynamicChildren.
7012 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
7013 if (parentComponent && parentComponent.type.__hmrId) {
7014 traverseStaticChildren(n1, n2);
7015 }
7016 else if (
7017 // #2080 if the stable fragment has a key, it's a <template v-for> that may
7018 // get moved around. Make sure all root level vnodes inherit el.
7019 // #2134 or if it's a component root, it may also get moved around
7020 // as the component is being moved.
7021 n2.key != null ||
7022 (parentComponent && n2 === parentComponent.subTree)) {
7023 traverseStaticChildren(n1, n2, true /* shallow */);
7024 }
7025 }
7026 else {
7027 // keyed / unkeyed, or manual fragments.
7028 // for keyed & unkeyed, since they are compiler generated from v-for,
7029 // each child is guaranteed to be a block so the fragment will never
7030 // have dynamicChildren.
7031 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7032 }
7033 }
7034 };
7035 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7036 n2.slotScopeIds = slotScopeIds;
7037 if (n1 == null) {
7038 if (n2.shapeFlag & 512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */) {
7039 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
7040 }
7041 else {
7042 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
7043 }
7044 }
7045 else {
7046 updateComponent(n1, n2, optimized);
7047 }
7048 };
7049 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
7050 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
7051 if (instance.type.__hmrId) {
7052 registerHMR(instance);
7053 }
7054 {
7055 pushWarningContext(initialVNode);
7056 startMeasure(instance, `mount`);
7057 }
7058 // inject renderer internals for keepAlive
7059 if (isKeepAlive(initialVNode)) {
7060 instance.ctx.renderer = internals;
7061 }
7062 // resolve props and slots for setup context
7063 {
7064 {
7065 startMeasure(instance, `init`);
7066 }
7067 setupComponent(instance);
7068 {
7069 endMeasure(instance, `init`);
7070 }
7071 }
7072 // setup() is async. This component relies on async logic to be resolved
7073 // before proceeding
7074 if (instance.asyncDep) {
7075 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
7076 // Give it a placeholder if this is not hydration
7077 // TODO handle self-defined fallback
7078 if (!initialVNode.el) {
7079 const placeholder = (instance.subTree = createVNode(Comment));
7080 processCommentNode(null, placeholder, container, anchor);
7081 }
7082 return;
7083 }
7084 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
7085 {
7086 popWarningContext();
7087 endMeasure(instance, `mount`);
7088 }
7089 };
7090 const updateComponent = (n1, n2, optimized) => {
7091 const instance = (n2.component = n1.component);
7092 if (shouldUpdateComponent(n1, n2, optimized)) {
7093 if (instance.asyncDep &&
7094 !instance.asyncResolved) {
7095 // async & still pending - just update props and slots
7096 // since the component's reactive effect for render isn't set-up yet
7097 {
7098 pushWarningContext(n2);
7099 }
7100 updateComponentPreRender(instance, n2, optimized);
7101 {
7102 popWarningContext();
7103 }
7104 return;
7105 }
7106 else {
7107 // normal update
7108 instance.next = n2;
7109 // in case the child component is also queued, remove it to avoid
7110 // double updating the same child component in the same flush.
7111 invalidateJob(instance.update);
7112 // instance.update is the reactive effect.
7113 instance.update();
7114 }
7115 }
7116 else {
7117 // no update needed. just copy over properties
7118 n2.el = n1.el;
7119 instance.vnode = n2;
7120 }
7121 };
7122 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
7123 const componentUpdateFn = () => {
7124 if (!instance.isMounted) {
7125 let vnodeHook;
7126 const { el, props } = initialVNode;
7127 const { bm, m, parent } = instance;
7128 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
7129 toggleRecurse(instance, false);
7130 // beforeMount hook
7131 if (bm) {
7132 invokeArrayFns(bm);
7133 }
7134 // onVnodeBeforeMount
7135 if (!isAsyncWrapperVNode &&
7136 (vnodeHook = props && props.onVnodeBeforeMount)) {
7137 invokeVNodeHook(vnodeHook, parent, initialVNode);
7138 }
7139 toggleRecurse(instance, true);
7140 if (el && hydrateNode) {
7141 // vnode has adopted host node - perform hydration instead of mount.
7142 const hydrateSubTree = () => {
7143 {
7144 startMeasure(instance, `render`);
7145 }
7146 instance.subTree = renderComponentRoot(instance);
7147 {
7148 endMeasure(instance, `render`);
7149 }
7150 {
7151 startMeasure(instance, `hydrate`);
7152 }
7153 hydrateNode(el, instance.subTree, instance, parentSuspense, null);
7154 {
7155 endMeasure(instance, `hydrate`);
7156 }
7157 };
7158 if (isAsyncWrapperVNode) {
7159 initialVNode.type.__asyncLoader().then(
7160 // note: we are moving the render call into an async callback,
7161 // which means it won't track dependencies - but it's ok because
7162 // a server-rendered async wrapper is already in resolved state
7163 // and it will never need to change.
7164 () => !instance.isUnmounted && hydrateSubTree());
7165 }
7166 else {
7167 hydrateSubTree();
7168 }
7169 }
7170 else {
7171 {
7172 startMeasure(instance, `render`);
7173 }
7174 const subTree = (instance.subTree = renderComponentRoot(instance));
7175 {
7176 endMeasure(instance, `render`);
7177 }
7178 {
7179 startMeasure(instance, `patch`);
7180 }
7181 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
7182 {
7183 endMeasure(instance, `patch`);
7184 }
7185 initialVNode.el = subTree.el;
7186 }
7187 // mounted hook
7188 if (m) {
7189 queuePostRenderEffect(m, parentSuspense);
7190 }
7191 // onVnodeMounted
7192 if (!isAsyncWrapperVNode &&
7193 (vnodeHook = props && props.onVnodeMounted)) {
7194 const scopedInitialVNode = initialVNode;
7195 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
7196 }
7197 // activated hook for keep-alive roots.
7198 // #1742 activated hook must be accessed after first render
7199 // since the hook may be injected by a child keep-alive
7200 if (initialVNode.shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */ ||
7201 (parent &&
7202 isAsyncWrapper(parent.vnode) &&
7203 parent.vnode.shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */)) {
7204 instance.a && queuePostRenderEffect(instance.a, parentSuspense);
7205 }
7206 instance.isMounted = true;
7207 {
7208 devtoolsComponentAdded(instance);
7209 }
7210 // #2458: deference mount-only object parameters to prevent memleaks
7211 initialVNode = container = anchor = null;
7212 }
7213 else {
7214 // updateComponent
7215 // This is triggered by mutation of component's own state (next: null)
7216 // OR parent calling processComponent (next: VNode)
7217 let { next, bu, u, parent, vnode } = instance;
7218 let originNext = next;
7219 let vnodeHook;
7220 {
7221 pushWarningContext(next || instance.vnode);
7222 }
7223 // Disallow component effect recursion during pre-lifecycle hooks.
7224 toggleRecurse(instance, false);
7225 if (next) {
7226 next.el = vnode.el;
7227 updateComponentPreRender(instance, next, optimized);
7228 }
7229 else {
7230 next = vnode;
7231 }
7232 // beforeUpdate hook
7233 if (bu) {
7234 invokeArrayFns(bu);
7235 }
7236 // onVnodeBeforeUpdate
7237 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
7238 invokeVNodeHook(vnodeHook, parent, next, vnode);
7239 }
7240 toggleRecurse(instance, true);
7241 // render
7242 {
7243 startMeasure(instance, `render`);
7244 }
7245 const nextTree = renderComponentRoot(instance);
7246 {
7247 endMeasure(instance, `render`);
7248 }
7249 const prevTree = instance.subTree;
7250 instance.subTree = nextTree;
7251 {
7252 startMeasure(instance, `patch`);
7253 }
7254 patch(prevTree, nextTree,
7255 // parent may have changed if it's in a teleport
7256 hostParentNode(prevTree.el),
7257 // anchor may have changed if it's in a fragment
7258 getNextHostNode(prevTree), instance, parentSuspense, isSVG);
7259 {
7260 endMeasure(instance, `patch`);
7261 }
7262 next.el = nextTree.el;
7263 if (originNext === null) {
7264 // self-triggered update. In case of HOC, update parent component
7265 // vnode el. HOC is indicated by parent instance's subTree pointing
7266 // to child component's vnode
7267 updateHOCHostEl(instance, nextTree.el);
7268 }
7269 // updated hook
7270 if (u) {
7271 queuePostRenderEffect(u, parentSuspense);
7272 }
7273 // onVnodeUpdated
7274 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
7275 queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
7276 }
7277 {
7278 devtoolsComponentUpdated(instance);
7279 }
7280 {
7281 popWarningContext();
7282 }
7283 }
7284 };
7285 // create reactive effect for rendering
7286 const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(update), instance.scope // track it in component's effect scope
7287 ));
7288 const update = (instance.update = () => effect.run());
7289 update.id = instance.uid;
7290 // allowRecurse
7291 // #1801, #2043 component render effects should allow recursive updates
7292 toggleRecurse(instance, true);
7293 {
7294 effect.onTrack = instance.rtc
7295 ? e => invokeArrayFns(instance.rtc, e)
7296 : void 0;
7297 effect.onTrigger = instance.rtg
7298 ? e => invokeArrayFns(instance.rtg, e)
7299 : void 0;
7300 update.ownerInstance = instance;
7301 }
7302 update();
7303 };
7304 const updateComponentPreRender = (instance, nextVNode, optimized) => {
7305 nextVNode.component = instance;
7306 const prevProps = instance.vnode.props;
7307 instance.vnode = nextVNode;
7308 instance.next = null;
7309 updateProps(instance, nextVNode.props, prevProps, optimized);
7310 updateSlots(instance, nextVNode.children, optimized);
7311 pauseTracking();
7312 // props update may have triggered pre-flush watchers.
7313 // flush them before the render update.
7314 flushPreFlushCbs();
7315 resetTracking();
7316 };
7317 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
7318 const c1 = n1 && n1.children;
7319 const prevShapeFlag = n1 ? n1.shapeFlag : 0;
7320 const c2 = n2.children;
7321 const { patchFlag, shapeFlag } = n2;
7322 // fast path
7323 if (patchFlag > 0) {
7324 if (patchFlag & 128 /* PatchFlags.KEYED_FRAGMENT */) {
7325 // this could be either fully-keyed or mixed (some keyed some not)
7326 // presence of patchFlag means children are guaranteed to be arrays
7327 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7328 return;
7329 }
7330 else if (patchFlag & 256 /* PatchFlags.UNKEYED_FRAGMENT */) {
7331 // unkeyed
7332 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7333 return;
7334 }
7335 }
7336 // children has 3 possibilities: text, array or no children.
7337 if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
7338 // text children fast path
7339 if (prevShapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7340 unmountChildren(c1, parentComponent, parentSuspense);
7341 }
7342 if (c2 !== c1) {
7343 hostSetElementText(container, c2);
7344 }
7345 }
7346 else {
7347 if (prevShapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7348 // prev children was array
7349 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7350 // two arrays, cannot assume anything, do full diff
7351 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7352 }
7353 else {
7354 // no new children, just unmount old
7355 unmountChildren(c1, parentComponent, parentSuspense, true);
7356 }
7357 }
7358 else {
7359 // prev children was text OR null
7360 // new children is array OR null
7361 if (prevShapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
7362 hostSetElementText(container, '');
7363 }
7364 // mount new if array
7365 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7366 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7367 }
7368 }
7369 }
7370 };
7371 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7372 c1 = c1 || EMPTY_ARR;
7373 c2 = c2 || EMPTY_ARR;
7374 const oldLength = c1.length;
7375 const newLength = c2.length;
7376 const commonLength = Math.min(oldLength, newLength);
7377 let i;
7378 for (i = 0; i < commonLength; i++) {
7379 const nextChild = (c2[i] = optimized
7380 ? cloneIfMounted(c2[i])
7381 : normalizeVNode(c2[i]));
7382 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7383 }
7384 if (oldLength > newLength) {
7385 // remove old
7386 unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
7387 }
7388 else {
7389 // mount new
7390 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
7391 }
7392 };
7393 // can be all-keyed or mixed
7394 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
7395 let i = 0;
7396 const l2 = c2.length;
7397 let e1 = c1.length - 1; // prev ending index
7398 let e2 = l2 - 1; // next ending index
7399 // 1. sync from start
7400 // (a b) c
7401 // (a b) d e
7402 while (i <= e1 && i <= e2) {
7403 const n1 = c1[i];
7404 const n2 = (c2[i] = optimized
7405 ? cloneIfMounted(c2[i])
7406 : normalizeVNode(c2[i]));
7407 if (isSameVNodeType(n1, n2)) {
7408 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7409 }
7410 else {
7411 break;
7412 }
7413 i++;
7414 }
7415 // 2. sync from end
7416 // a (b c)
7417 // d e (b c)
7418 while (i <= e1 && i <= e2) {
7419 const n1 = c1[e1];
7420 const n2 = (c2[e2] = optimized
7421 ? cloneIfMounted(c2[e2])
7422 : normalizeVNode(c2[e2]));
7423 if (isSameVNodeType(n1, n2)) {
7424 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7425 }
7426 else {
7427 break;
7428 }
7429 e1--;
7430 e2--;
7431 }
7432 // 3. common sequence + mount
7433 // (a b)
7434 // (a b) c
7435 // i = 2, e1 = 1, e2 = 2
7436 // (a b)
7437 // c (a b)
7438 // i = 0, e1 = -1, e2 = 0
7439 if (i > e1) {
7440 if (i <= e2) {
7441 const nextPos = e2 + 1;
7442 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
7443 while (i <= e2) {
7444 patch(null, (c2[i] = optimized
7445 ? cloneIfMounted(c2[i])
7446 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7447 i++;
7448 }
7449 }
7450 }
7451 // 4. common sequence + unmount
7452 // (a b) c
7453 // (a b)
7454 // i = 2, e1 = 2, e2 = 1
7455 // a (b c)
7456 // (b c)
7457 // i = 0, e1 = 0, e2 = -1
7458 else if (i > e2) {
7459 while (i <= e1) {
7460 unmount(c1[i], parentComponent, parentSuspense, true);
7461 i++;
7462 }
7463 }
7464 // 5. unknown sequence
7465 // [i ... e1 + 1]: a b [c d e] f g
7466 // [i ... e2 + 1]: a b [e d c h] f g
7467 // i = 2, e1 = 4, e2 = 5
7468 else {
7469 const s1 = i; // prev starting index
7470 const s2 = i; // next starting index
7471 // 5.1 build key:index map for newChildren
7472 const keyToNewIndexMap = new Map();
7473 for (i = s2; i <= e2; i++) {
7474 const nextChild = (c2[i] = optimized
7475 ? cloneIfMounted(c2[i])
7476 : normalizeVNode(c2[i]));
7477 if (nextChild.key != null) {
7478 if (keyToNewIndexMap.has(nextChild.key)) {
7479 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
7480 }
7481 keyToNewIndexMap.set(nextChild.key, i);
7482 }
7483 }
7484 // 5.2 loop through old children left to be patched and try to patch
7485 // matching nodes & remove nodes that are no longer present
7486 let j;
7487 let patched = 0;
7488 const toBePatched = e2 - s2 + 1;
7489 let moved = false;
7490 // used to track whether any node has moved
7491 let maxNewIndexSoFar = 0;
7492 // works as Map<newIndex, oldIndex>
7493 // Note that oldIndex is offset by +1
7494 // and oldIndex = 0 is a special value indicating the new node has
7495 // no corresponding old node.
7496 // used for determining longest stable subsequence
7497 const newIndexToOldIndexMap = new Array(toBePatched);
7498 for (i = 0; i < toBePatched; i++)
7499 newIndexToOldIndexMap[i] = 0;
7500 for (i = s1; i <= e1; i++) {
7501 const prevChild = c1[i];
7502 if (patched >= toBePatched) {
7503 // all new children have been patched so this can only be a removal
7504 unmount(prevChild, parentComponent, parentSuspense, true);
7505 continue;
7506 }
7507 let newIndex;
7508 if (prevChild.key != null) {
7509 newIndex = keyToNewIndexMap.get(prevChild.key);
7510 }
7511 else {
7512 // key-less node, try to locate a key-less node of the same type
7513 for (j = s2; j <= e2; j++) {
7514 if (newIndexToOldIndexMap[j - s2] === 0 &&
7515 isSameVNodeType(prevChild, c2[j])) {
7516 newIndex = j;
7517 break;
7518 }
7519 }
7520 }
7521 if (newIndex === undefined) {
7522 unmount(prevChild, parentComponent, parentSuspense, true);
7523 }
7524 else {
7525 newIndexToOldIndexMap[newIndex - s2] = i + 1;
7526 if (newIndex >= maxNewIndexSoFar) {
7527 maxNewIndexSoFar = newIndex;
7528 }
7529 else {
7530 moved = true;
7531 }
7532 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7533 patched++;
7534 }
7535 }
7536 // 5.3 move and mount
7537 // generate longest stable subsequence only when nodes have moved
7538 const increasingNewIndexSequence = moved
7539 ? getSequence(newIndexToOldIndexMap)
7540 : EMPTY_ARR;
7541 j = increasingNewIndexSequence.length - 1;
7542 // looping backwards so that we can use last patched node as anchor
7543 for (i = toBePatched - 1; i >= 0; i--) {
7544 const nextIndex = s2 + i;
7545 const nextChild = c2[nextIndex];
7546 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
7547 if (newIndexToOldIndexMap[i] === 0) {
7548 // mount new
7549 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7550 }
7551 else if (moved) {
7552 // move if:
7553 // There is no stable subsequence (e.g. a reverse)
7554 // OR current node is not among the stable sequence
7555 if (j < 0 || i !== increasingNewIndexSequence[j]) {
7556 move(nextChild, container, anchor, 2 /* MoveType.REORDER */);
7557 }
7558 else {
7559 j--;
7560 }
7561 }
7562 }
7563 }
7564 };
7565 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
7566 const { el, type, transition, children, shapeFlag } = vnode;
7567 if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
7568 move(vnode.component.subTree, container, anchor, moveType);
7569 return;
7570 }
7571 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
7572 vnode.suspense.move(container, anchor, moveType);
7573 return;
7574 }
7575 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
7576 type.move(vnode, container, anchor, internals);
7577 return;
7578 }
7579 if (type === Fragment) {
7580 hostInsert(el, container, anchor);
7581 for (let i = 0; i < children.length; i++) {
7582 move(children[i], container, anchor, moveType);
7583 }
7584 hostInsert(vnode.anchor, container, anchor);
7585 return;
7586 }
7587 if (type === Static) {
7588 moveStaticNode(vnode, container, anchor);
7589 return;
7590 }
7591 // single nodes
7592 const needTransition = moveType !== 2 /* MoveType.REORDER */ &&
7593 shapeFlag & 1 /* ShapeFlags.ELEMENT */ &&
7594 transition;
7595 if (needTransition) {
7596 if (moveType === 0 /* MoveType.ENTER */) {
7597 transition.beforeEnter(el);
7598 hostInsert(el, container, anchor);
7599 queuePostRenderEffect(() => transition.enter(el), parentSuspense);
7600 }
7601 else {
7602 const { leave, delayLeave, afterLeave } = transition;
7603 const remove = () => hostInsert(el, container, anchor);
7604 const performLeave = () => {
7605 leave(el, () => {
7606 remove();
7607 afterLeave && afterLeave();
7608 });
7609 };
7610 if (delayLeave) {
7611 delayLeave(el, remove, performLeave);
7612 }
7613 else {
7614 performLeave();
7615 }
7616 }
7617 }
7618 else {
7619 hostInsert(el, container, anchor);
7620 }
7621 };
7622 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
7623 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
7624 // unset ref
7625 if (ref != null) {
7626 setRef(ref, null, parentSuspense, vnode, true);
7627 }
7628 if (shapeFlag & 256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */) {
7629 parentComponent.ctx.deactivate(vnode);
7630 return;
7631 }
7632 const shouldInvokeDirs = shapeFlag & 1 /* ShapeFlags.ELEMENT */ && dirs;
7633 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
7634 let vnodeHook;
7635 if (shouldInvokeVnodeHook &&
7636 (vnodeHook = props && props.onVnodeBeforeUnmount)) {
7637 invokeVNodeHook(vnodeHook, parentComponent, vnode);
7638 }
7639 if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
7640 unmountComponent(vnode.component, parentSuspense, doRemove);
7641 }
7642 else {
7643 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
7644 vnode.suspense.unmount(parentSuspense, doRemove);
7645 return;
7646 }
7647 if (shouldInvokeDirs) {
7648 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
7649 }
7650 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
7651 vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
7652 }
7653 else if (dynamicChildren &&
7654 // #1153: fast path should not be taken for non-stable (v-for) fragments
7655 (type !== Fragment ||
7656 (patchFlag > 0 && patchFlag & 64 /* PatchFlags.STABLE_FRAGMENT */))) {
7657 // fast path for block nodes: only need to unmount dynamic children.
7658 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
7659 }
7660 else if ((type === Fragment &&
7661 patchFlag &
7662 (128 /* PatchFlags.KEYED_FRAGMENT */ | 256 /* PatchFlags.UNKEYED_FRAGMENT */)) ||
7663 (!optimized && shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */)) {
7664 unmountChildren(children, parentComponent, parentSuspense);
7665 }
7666 if (doRemove) {
7667 remove(vnode);
7668 }
7669 }
7670 if ((shouldInvokeVnodeHook &&
7671 (vnodeHook = props && props.onVnodeUnmounted)) ||
7672 shouldInvokeDirs) {
7673 queuePostRenderEffect(() => {
7674 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
7675 shouldInvokeDirs &&
7676 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
7677 }, parentSuspense);
7678 }
7679 };
7680 const remove = vnode => {
7681 const { type, el, anchor, transition } = vnode;
7682 if (type === Fragment) {
7683 if (vnode.patchFlag > 0 &&
7684 vnode.patchFlag & 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */ &&
7685 transition &&
7686 !transition.persisted) {
7687 vnode.children.forEach(child => {
7688 if (child.type === Comment) {
7689 hostRemove(child.el);
7690 }
7691 else {
7692 remove(child);
7693 }
7694 });
7695 }
7696 else {
7697 removeFragment(el, anchor);
7698 }
7699 return;
7700 }
7701 if (type === Static) {
7702 removeStaticNode(vnode);
7703 return;
7704 }
7705 const performRemove = () => {
7706 hostRemove(el);
7707 if (transition && !transition.persisted && transition.afterLeave) {
7708 transition.afterLeave();
7709 }
7710 };
7711 if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */ &&
7712 transition &&
7713 !transition.persisted) {
7714 const { leave, delayLeave } = transition;
7715 const performLeave = () => leave(el, performRemove);
7716 if (delayLeave) {
7717 delayLeave(vnode.el, performRemove, performLeave);
7718 }
7719 else {
7720 performLeave();
7721 }
7722 }
7723 else {
7724 performRemove();
7725 }
7726 };
7727 const removeFragment = (cur, end) => {
7728 // For fragments, directly remove all contained DOM nodes.
7729 // (fragment child nodes cannot have transition)
7730 let next;
7731 while (cur !== end) {
7732 next = hostNextSibling(cur);
7733 hostRemove(cur);
7734 cur = next;
7735 }
7736 hostRemove(end);
7737 };
7738 const unmountComponent = (instance, parentSuspense, doRemove) => {
7739 if (instance.type.__hmrId) {
7740 unregisterHMR(instance);
7741 }
7742 const { bum, scope, update, subTree, um } = instance;
7743 // beforeUnmount hook
7744 if (bum) {
7745 invokeArrayFns(bum);
7746 }
7747 // stop effects in component scope
7748 scope.stop();
7749 // update may be null if a component is unmounted before its async
7750 // setup has resolved.
7751 if (update) {
7752 // so that scheduler will no longer invoke it
7753 update.active = false;
7754 unmount(subTree, instance, parentSuspense, doRemove);
7755 }
7756 // unmounted hook
7757 if (um) {
7758 queuePostRenderEffect(um, parentSuspense);
7759 }
7760 queuePostRenderEffect(() => {
7761 instance.isUnmounted = true;
7762 }, parentSuspense);
7763 // A component with async dep inside a pending suspense is unmounted before
7764 // its async dep resolves. This should remove the dep from the suspense, and
7765 // cause the suspense to resolve immediately if that was the last dep.
7766 if (parentSuspense &&
7767 parentSuspense.pendingBranch &&
7768 !parentSuspense.isUnmounted &&
7769 instance.asyncDep &&
7770 !instance.asyncResolved &&
7771 instance.suspenseId === parentSuspense.pendingId) {
7772 parentSuspense.deps--;
7773 if (parentSuspense.deps === 0) {
7774 parentSuspense.resolve();
7775 }
7776 }
7777 {
7778 devtoolsComponentRemoved(instance);
7779 }
7780 };
7781 const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
7782 for (let i = start; i < children.length; i++) {
7783 unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
7784 }
7785 };
7786 const getNextHostNode = vnode => {
7787 if (vnode.shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
7788 return getNextHostNode(vnode.component.subTree);
7789 }
7790 if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
7791 return vnode.suspense.next();
7792 }
7793 return hostNextSibling((vnode.anchor || vnode.el));
7794 };
7795 const render = (vnode, container, isSVG) => {
7796 if (vnode == null) {
7797 if (container._vnode) {
7798 unmount(container._vnode, null, null, true);
7799 }
7800 }
7801 else {
7802 patch(container._vnode || null, vnode, container, null, null, null, isSVG);
7803 }
7804 flushPreFlushCbs();
7805 flushPostFlushCbs();
7806 container._vnode = vnode;
7807 };
7808 const internals = {
7809 p: patch,
7810 um: unmount,
7811 m: move,
7812 r: remove,
7813 mt: mountComponent,
7814 mc: mountChildren,
7815 pc: patchChildren,
7816 pbc: patchBlockChildren,
7817 n: getNextHostNode,
7818 o: options
7819 };
7820 let hydrate;
7821 let hydrateNode;
7822 if (createHydrationFns) {
7823 [hydrate, hydrateNode] = createHydrationFns(internals);
7824 }
7825 return {
7826 render,
7827 hydrate,
7828 createApp: createAppAPI(render, hydrate)
7829 };
7830 }
7831 function toggleRecurse({ effect, update }, allowed) {
7832 effect.allowRecurse = update.allowRecurse = allowed;
7833 }
7834 /**
7835 * #1156
7836 * When a component is HMR-enabled, we need to make sure that all static nodes
7837 * inside a block also inherit the DOM element from the previous tree so that
7838 * HMR updates (which are full updates) can retrieve the element for patching.
7839 *
7840 * #2080
7841 * Inside keyed `template` fragment static children, if a fragment is moved,
7842 * the children will always be moved. Therefore, in order to ensure correct move
7843 * position, el should be inherited from previous nodes.
7844 */
7845 function traverseStaticChildren(n1, n2, shallow = false) {
7846 const ch1 = n1.children;
7847 const ch2 = n2.children;
7848 if (isArray(ch1) && isArray(ch2)) {
7849 for (let i = 0; i < ch1.length; i++) {
7850 // this is only called in the optimized path so array children are
7851 // guaranteed to be vnodes
7852 const c1 = ch1[i];
7853 let c2 = ch2[i];
7854 if (c2.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && !c2.dynamicChildren) {
7855 if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* PatchFlags.HYDRATE_EVENTS */) {
7856 c2 = ch2[i] = cloneIfMounted(ch2[i]);
7857 c2.el = c1.el;
7858 }
7859 if (!shallow)
7860 traverseStaticChildren(c1, c2);
7861 }
7862 // #6852 also inherit for text nodes
7863 if (c2.type === Text) {
7864 c2.el = c1.el;
7865 }
7866 // also inherit for comment nodes, but not placeholders (e.g. v-if which
7867 // would have received .el during block patch)
7868 if (c2.type === Comment && !c2.el) {
7869 c2.el = c1.el;
7870 }
7871 }
7872 }
7873 }
7874 // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
7875 function getSequence(arr) {
7876 const p = arr.slice();
7877 const result = [0];
7878 let i, j, u, v, c;
7879 const len = arr.length;
7880 for (i = 0; i < len; i++) {
7881 const arrI = arr[i];
7882 if (arrI !== 0) {
7883 j = result[result.length - 1];
7884 if (arr[j] < arrI) {
7885 p[i] = j;
7886 result.push(i);
7887 continue;
7888 }
7889 u = 0;
7890 v = result.length - 1;
7891 while (u < v) {
7892 c = (u + v) >> 1;
7893 if (arr[result[c]] < arrI) {
7894 u = c + 1;
7895 }
7896 else {
7897 v = c;
7898 }
7899 }
7900 if (arrI < arr[result[u]]) {
7901 if (u > 0) {
7902 p[i] = result[u - 1];
7903 }
7904 result[u] = i;
7905 }
7906 }
7907 }
7908 u = result.length;
7909 v = result[u - 1];
7910 while (u-- > 0) {
7911 result[u] = v;
7912 v = p[v];
7913 }
7914 return result;
7915 }
7916
7917 const isTeleport = (type) => type.__isTeleport;
7918 const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
7919 const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
7920 const resolveTarget = (props, select) => {
7921 const targetSelector = props && props.to;
7922 if (isString(targetSelector)) {
7923 if (!select) {
7924 warn(`Current renderer does not support string target for Teleports. ` +
7925 `(missing querySelector renderer option)`);
7926 return null;
7927 }
7928 else {
7929 const target = select(targetSelector);
7930 if (!target) {
7931 warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
7932 `Note the target element must exist before the component is mounted - ` +
7933 `i.e. the target cannot be rendered by the component itself, and ` +
7934 `ideally should be outside of the entire Vue component tree.`);
7935 }
7936 return target;
7937 }
7938 }
7939 else {
7940 if (!targetSelector && !isTeleportDisabled(props)) {
7941 warn(`Invalid Teleport target: ${targetSelector}`);
7942 }
7943 return targetSelector;
7944 }
7945 };
7946 const TeleportImpl = {
7947 __isTeleport: true,
7948 process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
7949 const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
7950 const disabled = isTeleportDisabled(n2.props);
7951 let { shapeFlag, children, dynamicChildren } = n2;
7952 // #3302
7953 // HMR updated, force full diff
7954 if (isHmrUpdating) {
7955 optimized = false;
7956 dynamicChildren = null;
7957 }
7958 if (n1 == null) {
7959 // insert anchors in the main view
7960 const placeholder = (n2.el = createComment('teleport start')
7961 );
7962 const mainAnchor = (n2.anchor = createComment('teleport end')
7963 );
7964 insert(placeholder, container, anchor);
7965 insert(mainAnchor, container, anchor);
7966 const target = (n2.target = resolveTarget(n2.props, querySelector));
7967 const targetAnchor = (n2.targetAnchor = createText(''));
7968 if (target) {
7969 insert(targetAnchor, target);
7970 // #2652 we could be teleporting from a non-SVG tree into an SVG tree
7971 isSVG = isSVG || isTargetSVG(target);
7972 }
7973 else if (!disabled) {
7974 warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
7975 }
7976 const mount = (container, anchor) => {
7977 // Teleport *always* has Array children. This is enforced in both the
7978 // compiler and vnode children normalization.
7979 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
7980 mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
7981 }
7982 };
7983 if (disabled) {
7984 mount(container, mainAnchor);
7985 }
7986 else if (target) {
7987 mount(target, targetAnchor);
7988 }
7989 }
7990 else {
7991 // update content
7992 n2.el = n1.el;
7993 const mainAnchor = (n2.anchor = n1.anchor);
7994 const target = (n2.target = n1.target);
7995 const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
7996 const wasDisabled = isTeleportDisabled(n1.props);
7997 const currentContainer = wasDisabled ? container : target;
7998 const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
7999 isSVG = isSVG || isTargetSVG(target);
8000 if (dynamicChildren) {
8001 // fast path when the teleport happens to be a block root
8002 patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
8003 // even in block tree mode we need to make sure all root-level nodes
8004 // in the teleport inherit previous DOM references so that they can
8005 // be moved in future patches.
8006 traverseStaticChildren(n1, n2, true);
8007 }
8008 else if (!optimized) {
8009 patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
8010 }
8011 if (disabled) {
8012 if (!wasDisabled) {
8013 // enabled -> disabled
8014 // move into main container
8015 moveTeleport(n2, container, mainAnchor, internals, 1 /* TeleportMoveTypes.TOGGLE */);
8016 }
8017 }
8018 else {
8019 // target changed
8020 if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
8021 const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
8022 if (nextTarget) {
8023 moveTeleport(n2, nextTarget, null, internals, 0 /* TeleportMoveTypes.TARGET_CHANGE */);
8024 }
8025 else {
8026 warn('Invalid Teleport target on update:', target, `(${typeof target})`);
8027 }
8028 }
8029 else if (wasDisabled) {
8030 // disabled -> enabled
8031 // move into teleport target
8032 moveTeleport(n2, target, targetAnchor, internals, 1 /* TeleportMoveTypes.TOGGLE */);
8033 }
8034 }
8035 }
8036 updateCssVars(n2);
8037 },
8038 remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
8039 const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
8040 if (target) {
8041 hostRemove(targetAnchor);
8042 }
8043 // an unmounted teleport should always remove its children if not disabled
8044 if (doRemove || !isTeleportDisabled(props)) {
8045 hostRemove(anchor);
8046 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
8047 for (let i = 0; i < children.length; i++) {
8048 const child = children[i];
8049 unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
8050 }
8051 }
8052 }
8053 },
8054 move: moveTeleport,
8055 hydrate: hydrateTeleport
8056 };
8057 function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* TeleportMoveTypes.REORDER */) {
8058 // move target anchor if this is a target change.
8059 if (moveType === 0 /* TeleportMoveTypes.TARGET_CHANGE */) {
8060 insert(vnode.targetAnchor, container, parentAnchor);
8061 }
8062 const { el, anchor, shapeFlag, children, props } = vnode;
8063 const isReorder = moveType === 2 /* TeleportMoveTypes.REORDER */;
8064 // move main view anchor if this is a re-order.
8065 if (isReorder) {
8066 insert(el, container, parentAnchor);
8067 }
8068 // if this is a re-order and teleport is enabled (content is in target)
8069 // do not move children. So the opposite is: only move children if this
8070 // is not a reorder, or the teleport is disabled
8071 if (!isReorder || isTeleportDisabled(props)) {
8072 // Teleport has either Array children or no children.
8073 if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
8074 for (let i = 0; i < children.length; i++) {
8075 move(children[i], container, parentAnchor, 2 /* MoveType.REORDER */);
8076 }
8077 }
8078 }
8079 // move main view anchor if this is a re-order.
8080 if (isReorder) {
8081 insert(anchor, container, parentAnchor);
8082 }
8083 }
8084 function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
8085 const target = (vnode.target = resolveTarget(vnode.props, querySelector));
8086 if (target) {
8087 // if multiple teleports rendered to the same target element, we need to
8088 // pick up from where the last teleport finished instead of the first node
8089 const targetNode = target._lpa || target.firstChild;
8090 if (vnode.shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
8091 if (isTeleportDisabled(vnode.props)) {
8092 vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
8093 vnode.targetAnchor = targetNode;
8094 }
8095 else {
8096 vnode.anchor = nextSibling(node);
8097 // lookahead until we find the target anchor
8098 // we cannot rely on return value of hydrateChildren() because there
8099 // could be nested teleports
8100 let targetAnchor = targetNode;
8101 while (targetAnchor) {
8102 targetAnchor = nextSibling(targetAnchor);
8103 if (targetAnchor &&
8104 targetAnchor.nodeType === 8 &&
8105 targetAnchor.data === 'teleport anchor') {
8106 vnode.targetAnchor = targetAnchor;
8107 target._lpa =
8108 vnode.targetAnchor && nextSibling(vnode.targetAnchor);
8109 break;
8110 }
8111 }
8112 hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
8113 }
8114 }
8115 updateCssVars(vnode);
8116 }
8117 return vnode.anchor && nextSibling(vnode.anchor);
8118 }
8119 // Force-casted public typing for h and TSX props inference
8120 const Teleport = TeleportImpl;
8121 function updateCssVars(vnode) {
8122 // presence of .ut method indicates owner component uses css vars.
8123 // code path here can assume browser environment.
8124 const ctx = vnode.ctx;
8125 if (ctx && ctx.ut) {
8126 let node = vnode.children[0].el;
8127 while (node !== vnode.targetAnchor) {
8128 if (node.nodeType === 1)
8129 node.setAttribute('data-v-owner', ctx.uid);
8130 node = node.nextSibling;
8131 }
8132 ctx.ut();
8133 }
8134 }
8135
8136 const Fragment = Symbol('Fragment' );
8137 const Text = Symbol('Text' );
8138 const Comment = Symbol('Comment' );
8139 const Static = Symbol('Static' );
8140 // Since v-if and v-for are the two possible ways node structure can dynamically
8141 // change, once we consider v-if branches and each v-for fragment a block, we
8142 // can divide a template into nested blocks, and within each block the node
8143 // structure would be stable. This allows us to skip most children diffing
8144 // and only worry about the dynamic nodes (indicated by patch flags).
8145 const blockStack = [];
8146 let currentBlock = null;
8147 /**
8148 * Open a block.
8149 * This must be called before `createBlock`. It cannot be part of `createBlock`
8150 * because the children of the block are evaluated before `createBlock` itself
8151 * is called. The generated code typically looks like this:
8152 *
8153 * ```js
8154 * function render() {
8155 * return (openBlock(),createBlock('div', null, [...]))
8156 * }
8157 * ```
8158 * disableTracking is true when creating a v-for fragment block, since a v-for
8159 * fragment always diffs its children.
8160 *
8161 * @private
8162 */
8163 function openBlock(disableTracking = false) {
8164 blockStack.push((currentBlock = disableTracking ? null : []));
8165 }
8166 function closeBlock() {
8167 blockStack.pop();
8168 currentBlock = blockStack[blockStack.length - 1] || null;
8169 }
8170 // Whether we should be tracking dynamic child nodes inside a block.
8171 // Only tracks when this value is > 0
8172 // We are not using a simple boolean because this value may need to be
8173 // incremented/decremented by nested usage of v-once (see below)
8174 let isBlockTreeEnabled = 1;
8175 /**
8176 * Block tracking sometimes needs to be disabled, for example during the
8177 * creation of a tree that needs to be cached by v-once. The compiler generates
8178 * code like this:
8179 *
8180 * ``` js
8181 * _cache[1] || (
8182 * setBlockTracking(-1),
8183 * _cache[1] = createVNode(...),
8184 * setBlockTracking(1),
8185 * _cache[1]
8186 * )
8187 * ```
8188 *
8189 * @private
8190 */
8191 function setBlockTracking(value) {
8192 isBlockTreeEnabled += value;
8193 }
8194 function setupBlock(vnode) {
8195 // save current block children on the block vnode
8196 vnode.dynamicChildren =
8197 isBlockTreeEnabled > 0 ? currentBlock || EMPTY_ARR : null;
8198 // close block
8199 closeBlock();
8200 // a block is always going to be patched, so track it as a child of its
8201 // parent block
8202 if (isBlockTreeEnabled > 0 && currentBlock) {
8203 currentBlock.push(vnode);
8204 }
8205 return vnode;
8206 }
8207 /**
8208 * @private
8209 */
8210 function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
8211 return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
8212 }
8213 /**
8214 * Create a block root vnode. Takes the same exact arguments as `createVNode`.
8215 * A block root keeps track of dynamic nodes within the block in the
8216 * `dynamicChildren` array.
8217 *
8218 * @private
8219 */
8220 function createBlock(type, props, children, patchFlag, dynamicProps) {
8221 return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
8222 }
8223 function isVNode(value) {
8224 return value ? value.__v_isVNode === true : false;
8225 }
8226 function isSameVNodeType(n1, n2) {
8227 if (n2.shapeFlag & 6 /* ShapeFlags.COMPONENT */ &&
8228 hmrDirtyComponents.has(n2.type)) {
8229 // #7042, ensure the vnode being unmounted during HMR
8230 // bitwise operations to remove keep alive flags
8231 n1.shapeFlag &= ~256 /* ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE */;
8232 n2.shapeFlag &= ~512 /* ShapeFlags.COMPONENT_KEPT_ALIVE */;
8233 // HMR only: if the component has been hot-updated, force a reload.
8234 return false;
8235 }
8236 return n1.type === n2.type && n1.key === n2.key;
8237 }
8238 let vnodeArgsTransformer;
8239 /**
8240 * Internal API for registering an arguments transform for createVNode
8241 * used for creating stubs in the test-utils
8242 * It is *internal* but needs to be exposed for test-utils to pick up proper
8243 * typings
8244 */
8245 function transformVNodeArgs(transformer) {
8246 vnodeArgsTransformer = transformer;
8247 }
8248 const createVNodeWithArgsTransform = (...args) => {
8249 return _createVNode(...(vnodeArgsTransformer
8250 ? vnodeArgsTransformer(args, currentRenderingInstance)
8251 : args));
8252 };
8253 const InternalObjectKey = `__vInternal`;
8254 const normalizeKey = ({ key }) => key != null ? key : null;
8255 const normalizeRef = ({ ref, ref_key, ref_for }) => {
8256 return (ref != null
8257 ? isString(ref) || isRef(ref) || isFunction(ref)
8258 ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8259 : ref
8260 : null);
8261 };
8262 function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ShapeFlags.ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
8263 const vnode = {
8264 __v_isVNode: true,
8265 __v_skip: true,
8266 type,
8267 props,
8268 key: props && normalizeKey(props),
8269 ref: props && normalizeRef(props),
8270 scopeId: currentScopeId,
8271 slotScopeIds: null,
8272 children,
8273 component: null,
8274 suspense: null,
8275 ssContent: null,
8276 ssFallback: null,
8277 dirs: null,
8278 transition: null,
8279 el: null,
8280 anchor: null,
8281 target: null,
8282 targetAnchor: null,
8283 staticCount: 0,
8284 shapeFlag,
8285 patchFlag,
8286 dynamicProps,
8287 dynamicChildren: null,
8288 appContext: null,
8289 ctx: currentRenderingInstance
8290 };
8291 if (needFullChildrenNormalization) {
8292 normalizeChildren(vnode, children);
8293 // normalize suspense children
8294 if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
8295 type.normalize(vnode);
8296 }
8297 }
8298 else if (children) {
8299 // compiled element vnode - if children is passed, only possible types are
8300 // string or Array.
8301 vnode.shapeFlag |= isString(children)
8302 ? 8 /* ShapeFlags.TEXT_CHILDREN */
8303 : 16 /* ShapeFlags.ARRAY_CHILDREN */;
8304 }
8305 // validate key
8306 if (vnode.key !== vnode.key) {
8307 warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
8308 }
8309 // track vnode for block tree
8310 if (isBlockTreeEnabled > 0 &&
8311 // avoid a block node from tracking itself
8312 !isBlockNode &&
8313 // has current parent block
8314 currentBlock &&
8315 // presence of a patch flag indicates this node needs patching on updates.
8316 // component nodes also should always be patched, because even if the
8317 // component doesn't need to update, it needs to persist the instance on to
8318 // the next vnode so that it can be properly unmounted later.
8319 (vnode.patchFlag > 0 || shapeFlag & 6 /* ShapeFlags.COMPONENT */) &&
8320 // the EVENTS flag is only for hydration and if it is the only flag, the
8321 // vnode should not be considered dynamic due to handler caching.
8322 vnode.patchFlag !== 32 /* PatchFlags.HYDRATE_EVENTS */) {
8323 currentBlock.push(vnode);
8324 }
8325 return vnode;
8326 }
8327 const createVNode = (createVNodeWithArgsTransform );
8328 function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
8329 if (!type || type === NULL_DYNAMIC_COMPONENT) {
8330 if (!type) {
8331 warn(`Invalid vnode type when creating vnode: ${type}.`);
8332 }
8333 type = Comment;
8334 }
8335 if (isVNode(type)) {
8336 // createVNode receiving an existing vnode. This happens in cases like
8337 // <component :is="vnode"/>
8338 // #2078 make sure to merge refs during the clone instead of overwriting it
8339 const cloned = cloneVNode(type, props, true /* mergeRef: true */);
8340 if (children) {
8341 normalizeChildren(cloned, children);
8342 }
8343 if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) {
8344 if (cloned.shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
8345 currentBlock[currentBlock.indexOf(type)] = cloned;
8346 }
8347 else {
8348 currentBlock.push(cloned);
8349 }
8350 }
8351 cloned.patchFlag |= -2 /* PatchFlags.BAIL */;
8352 return cloned;
8353 }
8354 // class component normalization.
8355 if (isClassComponent(type)) {
8356 type = type.__vccOpts;
8357 }
8358 // class & style normalization.
8359 if (props) {
8360 // for reactive or proxy objects, we need to clone it to enable mutation.
8361 props = guardReactiveProps(props);
8362 let { class: klass, style } = props;
8363 if (klass && !isString(klass)) {
8364 props.class = normalizeClass(klass);
8365 }
8366 if (isObject(style)) {
8367 // reactive state objects need to be cloned since they are likely to be
8368 // mutated
8369 if (isProxy(style) && !isArray(style)) {
8370 style = extend({}, style);
8371 }
8372 props.style = normalizeStyle(style);
8373 }
8374 }
8375 // encode the vnode type information into a bitmap
8376 const shapeFlag = isString(type)
8377 ? 1 /* ShapeFlags.ELEMENT */
8378 : isSuspense(type)
8379 ? 128 /* ShapeFlags.SUSPENSE */
8380 : isTeleport(type)
8381 ? 64 /* ShapeFlags.TELEPORT */
8382 : isObject(type)
8383 ? 4 /* ShapeFlags.STATEFUL_COMPONENT */
8384 : isFunction(type)
8385 ? 2 /* ShapeFlags.FUNCTIONAL_COMPONENT */
8386 : 0;
8387 if (shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */ && isProxy(type)) {
8388 type = toRaw(type);
8389 warn(`Vue received a Component which was made a reactive object. This can ` +
8390 `lead to unnecessary performance overhead, and should be avoided by ` +
8391 `marking the component with \`markRaw\` or using \`shallowRef\` ` +
8392 `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
8393 }
8394 return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
8395 }
8396 function guardReactiveProps(props) {
8397 if (!props)
8398 return null;
8399 return isProxy(props) || InternalObjectKey in props
8400 ? extend({}, props)
8401 : props;
8402 }
8403 function cloneVNode(vnode, extraProps, mergeRef = false) {
8404 // This is intentionally NOT using spread or extend to avoid the runtime
8405 // key enumeration cost.
8406 const { props, ref, patchFlag, children } = vnode;
8407 const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
8408 const cloned = {
8409 __v_isVNode: true,
8410 __v_skip: true,
8411 type: vnode.type,
8412 props: mergedProps,
8413 key: mergedProps && normalizeKey(mergedProps),
8414 ref: extraProps && extraProps.ref
8415 ? // #2078 in the case of <component :is="vnode" ref="extra"/>
8416 // if the vnode itself already has a ref, cloneVNode will need to merge
8417 // the refs so the single vnode can be set on multiple refs
8418 mergeRef && ref
8419 ? isArray(ref)
8420 ? ref.concat(normalizeRef(extraProps))
8421 : [ref, normalizeRef(extraProps)]
8422 : normalizeRef(extraProps)
8423 : ref,
8424 scopeId: vnode.scopeId,
8425 slotScopeIds: vnode.slotScopeIds,
8426 children: patchFlag === -1 /* PatchFlags.HOISTED */ && isArray(children)
8427 ? children.map(deepCloneVNode)
8428 : children,
8429 target: vnode.target,
8430 targetAnchor: vnode.targetAnchor,
8431 staticCount: vnode.staticCount,
8432 shapeFlag: vnode.shapeFlag,
8433 // if the vnode is cloned with extra props, we can no longer assume its
8434 // existing patch flag to be reliable and need to add the FULL_PROPS flag.
8435 // note: preserve flag for fragments since they use the flag for children
8436 // fast paths only.
8437 patchFlag: extraProps && vnode.type !== Fragment
8438 ? patchFlag === -1 // hoisted node
8439 ? 16 /* PatchFlags.FULL_PROPS */
8440 : patchFlag | 16 /* PatchFlags.FULL_PROPS */
8441 : patchFlag,
8442 dynamicProps: vnode.dynamicProps,
8443 dynamicChildren: vnode.dynamicChildren,
8444 appContext: vnode.appContext,
8445 dirs: vnode.dirs,
8446 transition: vnode.transition,
8447 // These should technically only be non-null on mounted VNodes. However,
8448 // they *should* be copied for kept-alive vnodes. So we just always copy
8449 // them since them being non-null during a mount doesn't affect the logic as
8450 // they will simply be overwritten.
8451 component: vnode.component,
8452 suspense: vnode.suspense,
8453 ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
8454 ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
8455 el: vnode.el,
8456 anchor: vnode.anchor,
8457 ctx: vnode.ctx,
8458 ce: vnode.ce
8459 };
8460 return cloned;
8461 }
8462 /**
8463 * Dev only, for HMR of hoisted vnodes reused in v-for
8464 * https://github.com/vitejs/vite/issues/2022
8465 */
8466 function deepCloneVNode(vnode) {
8467 const cloned = cloneVNode(vnode);
8468 if (isArray(vnode.children)) {
8469 cloned.children = vnode.children.map(deepCloneVNode);
8470 }
8471 return cloned;
8472 }
8473 /**
8474 * @private
8475 */
8476 function createTextVNode(text = ' ', flag = 0) {
8477 return createVNode(Text, null, text, flag);
8478 }
8479 /**
8480 * @private
8481 */
8482 function createStaticVNode(content, numberOfNodes) {
8483 // A static vnode can contain multiple stringified elements, and the number
8484 // of elements is necessary for hydration.
8485 const vnode = createVNode(Static, null, content);
8486 vnode.staticCount = numberOfNodes;
8487 return vnode;
8488 }
8489 /**
8490 * @private
8491 */
8492 function createCommentVNode(text = '',
8493 // when used as the v-else branch, the comment node must be created as a
8494 // block to ensure correct updates.
8495 asBlock = false) {
8496 return asBlock
8497 ? (openBlock(), createBlock(Comment, null, text))
8498 : createVNode(Comment, null, text);
8499 }
8500 function normalizeVNode(child) {
8501 if (child == null || typeof child === 'boolean') {
8502 // empty placeholder
8503 return createVNode(Comment);
8504 }
8505 else if (isArray(child)) {
8506 // fragment
8507 return createVNode(Fragment, null,
8508 // #3666, avoid reference pollution when reusing vnode
8509 child.slice());
8510 }
8511 else if (typeof child === 'object') {
8512 // already vnode, this should be the most common since compiled templates
8513 // always produce all-vnode children arrays
8514 return cloneIfMounted(child);
8515 }
8516 else {
8517 // strings and numbers
8518 return createVNode(Text, null, String(child));
8519 }
8520 }
8521 // optimized normalization for template-compiled render fns
8522 function cloneIfMounted(child) {
8523 return (child.el === null && child.patchFlag !== -1 /* PatchFlags.HOISTED */) ||
8524 child.memo
8525 ? child
8526 : cloneVNode(child);
8527 }
8528 function normalizeChildren(vnode, children) {
8529 let type = 0;
8530 const { shapeFlag } = vnode;
8531 if (children == null) {
8532 children = null;
8533 }
8534 else if (isArray(children)) {
8535 type = 16 /* ShapeFlags.ARRAY_CHILDREN */;
8536 }
8537 else if (typeof children === 'object') {
8538 if (shapeFlag & (1 /* ShapeFlags.ELEMENT */ | 64 /* ShapeFlags.TELEPORT */)) {
8539 // Normalize slot to plain children for plain element and Teleport
8540 const slot = children.default;
8541 if (slot) {
8542 // _c marker is added by withCtx() indicating this is a compiled slot
8543 slot._c && (slot._d = false);
8544 normalizeChildren(vnode, slot());
8545 slot._c && (slot._d = true);
8546 }
8547 return;
8548 }
8549 else {
8550 type = 32 /* ShapeFlags.SLOTS_CHILDREN */;
8551 const slotFlag = children._;
8552 if (!slotFlag && !(InternalObjectKey in children)) {
8553 children._ctx = currentRenderingInstance;
8554 }
8555 else if (slotFlag === 3 /* SlotFlags.FORWARDED */ && currentRenderingInstance) {
8556 // a child component receives forwarded slots from the parent.
8557 // its slot type is determined by its parent's slot type.
8558 if (currentRenderingInstance.slots._ === 1 /* SlotFlags.STABLE */) {
8559 children._ = 1 /* SlotFlags.STABLE */;
8560 }
8561 else {
8562 children._ = 2 /* SlotFlags.DYNAMIC */;
8563 vnode.patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */;
8564 }
8565 }
8566 }
8567 }
8568 else if (isFunction(children)) {
8569 children = { default: children, _ctx: currentRenderingInstance };
8570 type = 32 /* ShapeFlags.SLOTS_CHILDREN */;
8571 }
8572 else {
8573 children = String(children);
8574 // force teleport children to array so it can be moved around
8575 if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
8576 type = 16 /* ShapeFlags.ARRAY_CHILDREN */;
8577 children = [createTextVNode(children)];
8578 }
8579 else {
8580 type = 8 /* ShapeFlags.TEXT_CHILDREN */;
8581 }
8582 }
8583 vnode.children = children;
8584 vnode.shapeFlag |= type;
8585 }
8586 function mergeProps(...args) {
8587 const ret = {};
8588 for (let i = 0; i < args.length; i++) {
8589 const toMerge = args[i];
8590 for (const key in toMerge) {
8591 if (key === 'class') {
8592 if (ret.class !== toMerge.class) {
8593 ret.class = normalizeClass([ret.class, toMerge.class]);
8594 }
8595 }
8596 else if (key === 'style') {
8597 ret.style = normalizeStyle([ret.style, toMerge.style]);
8598 }
8599 else if (isOn(key)) {
8600 const existing = ret[key];
8601 const incoming = toMerge[key];
8602 if (incoming &&
8603 existing !== incoming &&
8604 !(isArray(existing) && existing.includes(incoming))) {
8605 ret[key] = existing
8606 ? [].concat(existing, incoming)
8607 : incoming;
8608 }
8609 }
8610 else if (key !== '') {
8611 ret[key] = toMerge[key];
8612 }
8613 }
8614 }
8615 return ret;
8616 }
8617 function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8618 callWithAsyncErrorHandling(hook, instance, 7 /* ErrorCodes.VNODE_HOOK */, [
8619 vnode,
8620 prevVNode
8621 ]);
8622 }
8623
8624 const emptyAppContext = createAppContext();
8625 let uid = 0;
8626 function createComponentInstance(vnode, parent, suspense) {
8627 const type = vnode.type;
8628 // inherit parent app context - or - if root, adopt from root vnode
8629 const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
8630 const instance = {
8631 uid: uid++,
8632 vnode,
8633 type,
8634 parent,
8635 appContext,
8636 root: null,
8637 next: null,
8638 subTree: null,
8639 effect: null,
8640 update: null,
8641 scope: new EffectScope(true /* detached */),
8642 render: null,
8643 proxy: null,
8644 exposed: null,
8645 exposeProxy: null,
8646 withProxy: null,
8647 provides: parent ? parent.provides : Object.create(appContext.provides),
8648 accessCache: null,
8649 renderCache: [],
8650 // local resolved assets
8651 components: null,
8652 directives: null,
8653 // resolved props and emits options
8654 propsOptions: normalizePropsOptions(type, appContext),
8655 emitsOptions: normalizeEmitsOptions(type, appContext),
8656 // emit
8657 emit: null,
8658 emitted: null,
8659 // props default value
8660 propsDefaults: EMPTY_OBJ,
8661 // inheritAttrs
8662 inheritAttrs: type.inheritAttrs,
8663 // state
8664 ctx: EMPTY_OBJ,
8665 data: EMPTY_OBJ,
8666 props: EMPTY_OBJ,
8667 attrs: EMPTY_OBJ,
8668 slots: EMPTY_OBJ,
8669 refs: EMPTY_OBJ,
8670 setupState: EMPTY_OBJ,
8671 setupContext: null,
8672 // suspense related
8673 suspense,
8674 suspenseId: suspense ? suspense.pendingId : 0,
8675 asyncDep: null,
8676 asyncResolved: false,
8677 // lifecycle hooks
8678 // not using enums here because it results in computed properties
8679 isMounted: false,
8680 isUnmounted: false,
8681 isDeactivated: false,
8682 bc: null,
8683 c: null,
8684 bm: null,
8685 m: null,
8686 bu: null,
8687 u: null,
8688 um: null,
8689 bum: null,
8690 da: null,
8691 a: null,
8692 rtg: null,
8693 rtc: null,
8694 ec: null,
8695 sp: null
8696 };
8697 {
8698 instance.ctx = createDevRenderContext(instance);
8699 }
8700 instance.root = parent ? parent.root : instance;
8701 instance.emit = emit.bind(null, instance);
8702 // apply custom element special handling
8703 if (vnode.ce) {
8704 vnode.ce(instance);
8705 }
8706 return instance;
8707 }
8708 let currentInstance = null;
8709 const getCurrentInstance = () => currentInstance || currentRenderingInstance;
8710 const setCurrentInstance = (instance) => {
8711 currentInstance = instance;
8712 instance.scope.on();
8713 };
8714 const unsetCurrentInstance = () => {
8715 currentInstance && currentInstance.scope.off();
8716 currentInstance = null;
8717 };
8718 const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component');
8719 function validateComponentName(name, config) {
8720 const appIsNativeTag = config.isNativeTag || NO;
8721 if (isBuiltInTag(name) || appIsNativeTag(name)) {
8722 warn('Do not use built-in or reserved HTML elements as component id: ' + name);
8723 }
8724 }
8725 function isStatefulComponent(instance) {
8726 return instance.vnode.shapeFlag & 4 /* ShapeFlags.STATEFUL_COMPONENT */;
8727 }
8728 let isInSSRComponentSetup = false;
8729 function setupComponent(instance, isSSR = false) {
8730 isInSSRComponentSetup = isSSR;
8731 const { props, children } = instance.vnode;
8732 const isStateful = isStatefulComponent(instance);
8733 initProps(instance, props, isStateful, isSSR);
8734 initSlots(instance, children);
8735 const setupResult = isStateful
8736 ? setupStatefulComponent(instance, isSSR)
8737 : undefined;
8738 isInSSRComponentSetup = false;
8739 return setupResult;
8740 }
8741 function setupStatefulComponent(instance, isSSR) {
8742 var _a;
8743 const Component = instance.type;
8744 {
8745 if (Component.name) {
8746 validateComponentName(Component.name, instance.appContext.config);
8747 }
8748 if (Component.components) {
8749 const names = Object.keys(Component.components);
8750 for (let i = 0; i < names.length; i++) {
8751 validateComponentName(names[i], instance.appContext.config);
8752 }
8753 }
8754 if (Component.directives) {
8755 const names = Object.keys(Component.directives);
8756 for (let i = 0; i < names.length; i++) {
8757 validateDirectiveName(names[i]);
8758 }
8759 }
8760 if (Component.compilerOptions && isRuntimeOnly()) {
8761 warn(`"compilerOptions" is only supported when using a build of Vue that ` +
8762 `includes the runtime compiler. Since you are using a runtime-only ` +
8763 `build, the options should be passed via your build tool config instead.`);
8764 }
8765 }
8766 // 0. create render proxy property access cache
8767 instance.accessCache = Object.create(null);
8768 // 1. create public instance / render proxy
8769 // also mark it raw so it's never observed
8770 instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
8771 {
8772 exposePropsOnRenderContext(instance);
8773 }
8774 // 2. call setup()
8775 const { setup } = Component;
8776 if (setup) {
8777 const setupContext = (instance.setupContext =
8778 setup.length > 1 ? createSetupContext(instance) : null);
8779 setCurrentInstance(instance);
8780 pauseTracking();
8781 const setupResult = callWithErrorHandling(setup, instance, 0 /* ErrorCodes.SETUP_FUNCTION */, [shallowReadonly(instance.props) , setupContext]);
8782 resetTracking();
8783 unsetCurrentInstance();
8784 if (isPromise(setupResult)) {
8785 setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
8786 if (isSSR) {
8787 // return the promise so server-renderer can wait on it
8788 return setupResult
8789 .then((resolvedResult) => {
8790 handleSetupResult(instance, resolvedResult, isSSR);
8791 })
8792 .catch(e => {
8793 handleError(e, instance, 0 /* ErrorCodes.SETUP_FUNCTION */);
8794 });
8795 }
8796 else {
8797 // async setup returned Promise.
8798 // bail here and wait for re-entry.
8799 instance.asyncDep = setupResult;
8800 if (!instance.suspense) {
8801 const name = (_a = Component.name) !== null && _a !== void 0 ? _a : 'Anonymous';
8802 warn(`Component <${name}>: setup function returned a promise, but no ` +
8803 `<Suspense> boundary was found in the parent component tree. ` +
8804 `A component with async setup() must be nested in a <Suspense> ` +
8805 `in order to be rendered.`);
8806 }
8807 }
8808 }
8809 else {
8810 handleSetupResult(instance, setupResult, isSSR);
8811 }
8812 }
8813 else {
8814 finishComponentSetup(instance, isSSR);
8815 }
8816 }
8817 function handleSetupResult(instance, setupResult, isSSR) {
8818 if (isFunction(setupResult)) {
8819 // setup returned an inline render function
8820 {
8821 instance.render = setupResult;
8822 }
8823 }
8824 else if (isObject(setupResult)) {
8825 if (isVNode(setupResult)) {
8826 warn(`setup() should not return VNodes directly - ` +
8827 `return a render function instead.`);
8828 }
8829 // setup returned bindings.
8830 // assuming a render function compiled from template is present.
8831 {
8832 instance.devtoolsRawSetupState = setupResult;
8833 }
8834 instance.setupState = proxyRefs(setupResult);
8835 {
8836 exposeSetupStateOnRenderContext(instance);
8837 }
8838 }
8839 else if (setupResult !== undefined) {
8840 warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
8841 }
8842 finishComponentSetup(instance, isSSR);
8843 }
8844 let compile$1;
8845 let installWithProxy;
8846 /**
8847 * For runtime-dom to register the compiler.
8848 * Note the exported method uses any to avoid d.ts relying on the compiler types.
8849 */
8850 function registerRuntimeCompiler(_compile) {
8851 compile$1 = _compile;
8852 installWithProxy = i => {
8853 if (i.render._rc) {
8854 i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
8855 }
8856 };
8857 }
8858 // dev only
8859 const isRuntimeOnly = () => !compile$1;
8860 function finishComponentSetup(instance, isSSR, skipOptions) {
8861 const Component = instance.type;
8862 // template / render function normalization
8863 // could be already set when returned from setup()
8864 if (!instance.render) {
8865 // only do on-the-fly compile if not in SSR - SSR on-the-fly compilation
8866 // is done by server-renderer
8867 if (!isSSR && compile$1 && !Component.render) {
8868 const template = Component.template ||
8869 resolveMergedOptions(instance).template;
8870 if (template) {
8871 {
8872 startMeasure(instance, `compile`);
8873 }
8874 const { isCustomElement, compilerOptions } = instance.appContext.config;
8875 const { delimiters, compilerOptions: componentCompilerOptions } = Component;
8876 const finalCompilerOptions = extend(extend({
8877 isCustomElement,
8878 delimiters
8879 }, compilerOptions), componentCompilerOptions);
8880 Component.render = compile$1(template, finalCompilerOptions);
8881 {
8882 endMeasure(instance, `compile`);
8883 }
8884 }
8885 }
8886 instance.render = (Component.render || NOOP);
8887 // for runtime-compiled render functions using `with` blocks, the render
8888 // proxy used needs a different `has` handler which is more performant and
8889 // also only allows a whitelist of globals to fallthrough.
8890 if (installWithProxy) {
8891 installWithProxy(instance);
8892 }
8893 }
8894 // support for 2.x options
8895 {
8896 setCurrentInstance(instance);
8897 pauseTracking();
8898 applyOptions(instance);
8899 resetTracking();
8900 unsetCurrentInstance();
8901 }
8902 // warn missing template/render
8903 // the runtime compilation of template in SSR is done by server-render
8904 if (!Component.render && instance.render === NOOP && !isSSR) {
8905 /* istanbul ignore if */
8906 if (!compile$1 && Component.template) {
8907 warn(`Component provided template option but ` +
8908 `runtime compilation is not supported in this build of Vue.` +
8909 (` Use "vue.global.js" instead.`
8910 ) /* should not happen */);
8911 }
8912 else {
8913 warn(`Component is missing template or render function.`);
8914 }
8915 }
8916 }
8917 function createAttrsProxy(instance) {
8918 return new Proxy(instance.attrs, {
8919 get(target, key) {
8920 markAttrsAccessed();
8921 track(instance, "get" /* TrackOpTypes.GET */, '$attrs');
8922 return target[key];
8923 },
8924 set() {
8925 warn(`setupContext.attrs is readonly.`);
8926 return false;
8927 },
8928 deleteProperty() {
8929 warn(`setupContext.attrs is readonly.`);
8930 return false;
8931 }
8932 }
8933 );
8934 }
8935 function createSetupContext(instance) {
8936 const expose = exposed => {
8937 {
8938 if (instance.exposed) {
8939 warn(`expose() should be called only once per setup().`);
8940 }
8941 if (exposed != null) {
8942 let exposedType = typeof exposed;
8943 if (exposedType === 'object') {
8944 if (isArray(exposed)) {
8945 exposedType = 'array';
8946 }
8947 else if (isRef(exposed)) {
8948 exposedType = 'ref';
8949 }
8950 }
8951 if (exposedType !== 'object') {
8952 warn(`expose() should be passed a plain object, received ${exposedType}.`);
8953 }
8954 }
8955 }
8956 instance.exposed = exposed || {};
8957 };
8958 let attrs;
8959 {
8960 // We use getters in dev in case libs like test-utils overwrite instance
8961 // properties (overwrites should not be done in prod)
8962 return Object.freeze({
8963 get attrs() {
8964 return attrs || (attrs = createAttrsProxy(instance));
8965 },
8966 get slots() {
8967 return shallowReadonly(instance.slots);
8968 },
8969 get emit() {
8970 return (event, ...args) => instance.emit(event, ...args);
8971 },
8972 expose
8973 });
8974 }
8975 }
8976 function getExposeProxy(instance) {
8977 if (instance.exposed) {
8978 return (instance.exposeProxy ||
8979 (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
8980 get(target, key) {
8981 if (key in target) {
8982 return target[key];
8983 }
8984 else if (key in publicPropertiesMap) {
8985 return publicPropertiesMap[key](instance);
8986 }
8987 },
8988 has(target, key) {
8989 return key in target || key in publicPropertiesMap;
8990 }
8991 })));
8992 }
8993 }
8994 const classifyRE = /(?:^|[-_])(\w)/g;
8995 const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
8996 function getComponentName(Component, includeInferred = true) {
8997 return isFunction(Component)
8998 ? Component.displayName || Component.name
8999 : Component.name || (includeInferred && Component.__name);
9000 }
9001 /* istanbul ignore next */
9002 function formatComponentName(instance, Component, isRoot = false) {
9003 let name = getComponentName(Component);
9004 if (!name && Component.__file) {
9005 const match = Component.__file.match(/([^/\\]+)\.\w+$/);
9006 if (match) {
9007 name = match[1];
9008 }
9009 }
9010 if (!name && instance && instance.parent) {
9011 // try to infer the name based on reverse resolution
9012 const inferFromRegistry = (registry) => {
9013 for (const key in registry) {
9014 if (registry[key] === Component) {
9015 return key;
9016 }
9017 }
9018 };
9019 name =
9020 inferFromRegistry(instance.components ||
9021 instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
9022 }
9023 return name ? classify(name) : isRoot ? `App` : `Anonymous`;
9024 }
9025 function isClassComponent(value) {
9026 return isFunction(value) && '__vccOpts' in value;
9027 }
9028
9029 const computed = ((getterOrOptions, debugOptions) => {
9030 // @ts-ignore
9031 return computed$1(getterOrOptions, debugOptions, isInSSRComponentSetup);
9032 });
9033
9034 // dev only
9035 const warnRuntimeUsage = (method) => warn(`${method}() is a compiler-hint helper that is only usable inside ` +
9036 `<script setup> of a single file component. Its arguments should be ` +
9037 `compiled away and passing it at runtime has no effect.`);
9038 // implementation
9039 function defineProps() {
9040 {
9041 warnRuntimeUsage(`defineProps`);
9042 }
9043 return null;
9044 }
9045 // implementation
9046 function defineEmits() {
9047 {
9048 warnRuntimeUsage(`defineEmits`);
9049 }
9050 return null;
9051 }
9052 /**
9053 * Vue `<script setup>` compiler macro for declaring a component's exposed
9054 * instance properties when it is accessed by a parent component via template
9055 * refs.
9056 *
9057 * `<script setup>` components are closed by default - i.e. variables inside
9058 * the `<script setup>` scope is not exposed to parent unless explicitly exposed
9059 * via `defineExpose`.
9060 *
9061 * This is only usable inside `<script setup>`, is compiled away in the
9062 * output and should **not** be actually called at runtime.
9063 */
9064 function defineExpose(exposed) {
9065 {
9066 warnRuntimeUsage(`defineExpose`);
9067 }
9068 }
9069 /**
9070 * Vue `<script setup>` compiler macro for providing props default values when
9071 * using type-based `defineProps` declaration.
9072 *
9073 * Example usage:
9074 * ```ts
9075 * withDefaults(defineProps<{
9076 * size?: number
9077 * labels?: string[]
9078 * }>(), {
9079 * size: 3,
9080 * labels: () => ['default label']
9081 * })
9082 * ```
9083 *
9084 * This is only usable inside `<script setup>`, is compiled away in the output
9085 * and should **not** be actually called at runtime.
9086 */
9087 function withDefaults(props, defaults) {
9088 {
9089 warnRuntimeUsage(`withDefaults`);
9090 }
9091 return null;
9092 }
9093 function useSlots() {
9094 return getContext().slots;
9095 }
9096 function useAttrs() {
9097 return getContext().attrs;
9098 }
9099 function getContext() {
9100 const i = getCurrentInstance();
9101 if (!i) {
9102 warn(`useContext() called without active instance.`);
9103 }
9104 return i.setupContext || (i.setupContext = createSetupContext(i));
9105 }
9106 /**
9107 * Runtime helper for merging default declarations. Imported by compiled code
9108 * only.
9109 * @internal
9110 */
9111 function mergeDefaults(raw, defaults) {
9112 const props = isArray(raw)
9113 ? raw.reduce((normalized, p) => ((normalized[p] = {}), normalized), {})
9114 : raw;
9115 for (const key in defaults) {
9116 const opt = props[key];
9117 if (opt) {
9118 if (isArray(opt) || isFunction(opt)) {
9119 props[key] = { type: opt, default: defaults[key] };
9120 }
9121 else {
9122 opt.default = defaults[key];
9123 }
9124 }
9125 else if (opt === null) {
9126 props[key] = { default: defaults[key] };
9127 }
9128 else {
9129 warn(`props default key "${key}" has no corresponding declaration.`);
9130 }
9131 }
9132 return props;
9133 }
9134 /**
9135 * Used to create a proxy for the rest element when destructuring props with
9136 * defineProps().
9137 * @internal
9138 */
9139 function createPropsRestProxy(props, excludedKeys) {
9140 const ret = {};
9141 for (const key in props) {
9142 if (!excludedKeys.includes(key)) {
9143 Object.defineProperty(ret, key, {
9144 enumerable: true,
9145 get: () => props[key]
9146 });
9147 }
9148 }
9149 return ret;
9150 }
9151 /**
9152 * `<script setup>` helper for persisting the current instance context over
9153 * async/await flows.
9154 *
9155 * `@vue/compiler-sfc` converts the following:
9156 *
9157 * ```ts
9158 * const x = await foo()
9159 * ```
9160 *
9161 * into:
9162 *
9163 * ```ts
9164 * let __temp, __restore
9165 * const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
9166 * ```
9167 * @internal
9168 */
9169 function withAsyncContext(getAwaitable) {
9170 const ctx = getCurrentInstance();
9171 if (!ctx) {
9172 warn(`withAsyncContext called without active current instance. ` +
9173 `This is likely a bug.`);
9174 }
9175 let awaitable = getAwaitable();
9176 unsetCurrentInstance();
9177 if (isPromise(awaitable)) {
9178 awaitable = awaitable.catch(e => {
9179 setCurrentInstance(ctx);
9180 throw e;
9181 });
9182 }
9183 return [awaitable, () => setCurrentInstance(ctx)];
9184 }
9185
9186 // Actual implementation
9187 function h(type, propsOrChildren, children) {
9188 const l = arguments.length;
9189 if (l === 2) {
9190 if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
9191 // single vnode without props
9192 if (isVNode(propsOrChildren)) {
9193 return createVNode(type, null, [propsOrChildren]);
9194 }
9195 // props without children
9196 return createVNode(type, propsOrChildren);
9197 }
9198 else {
9199 // omit props
9200 return createVNode(type, null, propsOrChildren);
9201 }
9202 }
9203 else {
9204 if (l > 3) {
9205 children = Array.prototype.slice.call(arguments, 2);
9206 }
9207 else if (l === 3 && isVNode(children)) {
9208 children = [children];
9209 }
9210 return createVNode(type, propsOrChildren, children);
9211 }
9212 }
9213
9214 const ssrContextKey = Symbol(`ssrContext` );
9215 const useSSRContext = () => {
9216 {
9217 warn(`useSSRContext() is not supported in the global build.`);
9218 }
9219 };
9220
9221 function initCustomFormatter() {
9222 /* eslint-disable no-restricted-globals */
9223 if (typeof window === 'undefined') {
9224 return;
9225 }
9226 const vueStyle = { style: 'color:#3ba776' };
9227 const numberStyle = { style: 'color:#0b1bc9' };
9228 const stringStyle = { style: 'color:#b62e24' };
9229 const keywordStyle = { style: 'color:#9d288c' };
9230 // custom formatter for Chrome
9231 // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
9232 const formatter = {
9233 header(obj) {
9234 // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
9235 if (!isObject(obj)) {
9236 return null;
9237 }
9238 if (obj.__isVue) {
9239 return ['div', vueStyle, `VueInstance`];
9240 }
9241 else if (isRef(obj)) {
9242 return [
9243 'div',
9244 {},
9245 ['span', vueStyle, genRefFlag(obj)],
9246 '<',
9247 formatValue(obj.value),
9248 `>`
9249 ];
9250 }
9251 else if (isReactive(obj)) {
9252 return [
9253 'div',
9254 {},
9255 ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
9256 '<',
9257 formatValue(obj),
9258 `>${isReadonly(obj) ? ` (readonly)` : ``}`
9259 ];
9260 }
9261 else if (isReadonly(obj)) {
9262 return [
9263 'div',
9264 {},
9265 ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
9266 '<',
9267 formatValue(obj),
9268 '>'
9269 ];
9270 }
9271 return null;
9272 },
9273 hasBody(obj) {
9274 return obj && obj.__isVue;
9275 },
9276 body(obj) {
9277 if (obj && obj.__isVue) {
9278 return [
9279 'div',
9280 {},
9281 ...formatInstance(obj.$)
9282 ];
9283 }
9284 }
9285 };
9286 function formatInstance(instance) {
9287 const blocks = [];
9288 if (instance.type.props && instance.props) {
9289 blocks.push(createInstanceBlock('props', toRaw(instance.props)));
9290 }
9291 if (instance.setupState !== EMPTY_OBJ) {
9292 blocks.push(createInstanceBlock('setup', instance.setupState));
9293 }
9294 if (instance.data !== EMPTY_OBJ) {
9295 blocks.push(createInstanceBlock('data', toRaw(instance.data)));
9296 }
9297 const computed = extractKeys(instance, 'computed');
9298 if (computed) {
9299 blocks.push(createInstanceBlock('computed', computed));
9300 }
9301 const injected = extractKeys(instance, 'inject');
9302 if (injected) {
9303 blocks.push(createInstanceBlock('injected', injected));
9304 }
9305 blocks.push([
9306 'div',
9307 {},
9308 [
9309 'span',
9310 {
9311 style: keywordStyle.style + ';opacity:0.66'
9312 },
9313 '$ (internal): '
9314 ],
9315 ['object', { object: instance }]
9316 ]);
9317 return blocks;
9318 }
9319 function createInstanceBlock(type, target) {
9320 target = extend({}, target);
9321 if (!Object.keys(target).length) {
9322 return ['span', {}];
9323 }
9324 return [
9325 'div',
9326 { style: 'line-height:1.25em;margin-bottom:0.6em' },
9327 [
9328 'div',
9329 {
9330 style: 'color:#476582'
9331 },
9332 type
9333 ],
9334 [
9335 'div',
9336 {
9337 style: 'padding-left:1.25em'
9338 },
9339 ...Object.keys(target).map(key => {
9340 return [
9341 'div',
9342 {},
9343 ['span', keywordStyle, key + ': '],
9344 formatValue(target[key], false)
9345 ];
9346 })
9347 ]
9348 ];
9349 }
9350 function formatValue(v, asRaw = true) {
9351 if (typeof v === 'number') {
9352 return ['span', numberStyle, v];
9353 }
9354 else if (typeof v === 'string') {
9355 return ['span', stringStyle, JSON.stringify(v)];
9356 }
9357 else if (typeof v === 'boolean') {
9358 return ['span', keywordStyle, v];
9359 }
9360 else if (isObject(v)) {
9361 return ['object', { object: asRaw ? toRaw(v) : v }];
9362 }
9363 else {
9364 return ['span', stringStyle, String(v)];
9365 }
9366 }
9367 function extractKeys(instance, type) {
9368 const Comp = instance.type;
9369 if (isFunction(Comp)) {
9370 return;
9371 }
9372 const extracted = {};
9373 for (const key in instance.ctx) {
9374 if (isKeyOfType(Comp, key, type)) {
9375 extracted[key] = instance.ctx[key];
9376 }
9377 }
9378 return extracted;
9379 }
9380 function isKeyOfType(Comp, key, type) {
9381 const opts = Comp[type];
9382 if ((isArray(opts) && opts.includes(key)) ||
9383 (isObject(opts) && key in opts)) {
9384 return true;
9385 }
9386 if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
9387 return true;
9388 }
9389 if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
9390 return true;
9391 }
9392 }
9393 function genRefFlag(v) {
9394 if (isShallow(v)) {
9395 return `ShallowRef`;
9396 }
9397 if (v.effect) {
9398 return `ComputedRef`;
9399 }
9400 return `Ref`;
9401 }
9402 if (window.devtoolsFormatters) {
9403 window.devtoolsFormatters.push(formatter);
9404 }
9405 else {
9406 window.devtoolsFormatters = [formatter];
9407 }
9408 }
9409
9410 function withMemo(memo, render, cache, index) {
9411 const cached = cache[index];
9412 if (cached && isMemoSame(cached, memo)) {
9413 return cached;
9414 }
9415 const ret = render();
9416 // shallow clone
9417 ret.memo = memo.slice();
9418 return (cache[index] = ret);
9419 }
9420 function isMemoSame(cached, memo) {
9421 const prev = cached.memo;
9422 if (prev.length != memo.length) {
9423 return false;
9424 }
9425 for (let i = 0; i < prev.length; i++) {
9426 if (hasChanged(prev[i], memo[i])) {
9427 return false;
9428 }
9429 }
9430 // make sure to let parent block track it when returning cached
9431 if (isBlockTreeEnabled > 0 && currentBlock) {
9432 currentBlock.push(cached);
9433 }
9434 return true;
9435 }
9436
9437 // Core API ------------------------------------------------------------------
9438 const version = "3.2.47";
9439 /**
9440 * SSR utils for \@vue/server-renderer. Only exposed in ssr-possible builds.
9441 * @internal
9442 */
9443 const ssrUtils = (null);
9444 /**
9445 * @internal only exposed in compat builds
9446 */
9447 const resolveFilter = null;
9448 /**
9449 * @internal only exposed in compat builds.
9450 */
9451 const compatUtils = (null);
9452
9453 const svgNS = 'http://www.w3.org/2000/svg';
9454 const doc = (typeof document !== 'undefined' ? document : null);
9455 const templateContainer = doc && /*#__PURE__*/ doc.createElement('template');
9456 const nodeOps = {
9457 insert: (child, parent, anchor) => {
9458 parent.insertBefore(child, anchor || null);
9459 },
9460 remove: child => {
9461 const parent = child.parentNode;
9462 if (parent) {
9463 parent.removeChild(child);
9464 }
9465 },
9466 createElement: (tag, isSVG, is, props) => {
9467 const el = isSVG
9468 ? doc.createElementNS(svgNS, tag)
9469 : doc.createElement(tag, is ? { is } : undefined);
9470 if (tag === 'select' && props && props.multiple != null) {
9471 el.setAttribute('multiple', props.multiple);
9472 }
9473 return el;
9474 },
9475 createText: text => doc.createTextNode(text),
9476 createComment: text => doc.createComment(text),
9477 setText: (node, text) => {
9478 node.nodeValue = text;
9479 },
9480 setElementText: (el, text) => {
9481 el.textContent = text;
9482 },
9483 parentNode: node => node.parentNode,
9484 nextSibling: node => node.nextSibling,
9485 querySelector: selector => doc.querySelector(selector),
9486 setScopeId(el, id) {
9487 el.setAttribute(id, '');
9488 },
9489 // __UNSAFE__
9490 // Reason: innerHTML.
9491 // Static content here can only come from compiled templates.
9492 // As long as the user only uses trusted templates, this is safe.
9493 insertStaticContent(content, parent, anchor, isSVG, start, end) {
9494 // <parent> before | first ... last | anchor </parent>
9495 const before = anchor ? anchor.previousSibling : parent.lastChild;
9496 // #5308 can only take cached path if:
9497 // - has a single root node
9498 // - nextSibling info is still available
9499 if (start && (start === end || start.nextSibling)) {
9500 // cached
9501 while (true) {
9502 parent.insertBefore(start.cloneNode(true), anchor);
9503 if (start === end || !(start = start.nextSibling))
9504 break;
9505 }
9506 }
9507 else {
9508 // fresh insert
9509 templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
9510 const template = templateContainer.content;
9511 if (isSVG) {
9512 // remove outer svg wrapper
9513 const wrapper = template.firstChild;
9514 while (wrapper.firstChild) {
9515 template.appendChild(wrapper.firstChild);
9516 }
9517 template.removeChild(wrapper);
9518 }
9519 parent.insertBefore(template, anchor);
9520 }
9521 return [
9522 // first
9523 before ? before.nextSibling : parent.firstChild,
9524 // last
9525 anchor ? anchor.previousSibling : parent.lastChild
9526 ];
9527 }
9528 };
9529
9530 // compiler should normalize class + :class bindings on the same element
9531 // into a single binding ['staticClass', dynamic]
9532 function patchClass(el, value, isSVG) {
9533 // directly setting className should be faster than setAttribute in theory
9534 // if this is an element during a transition, take the temporary transition
9535 // classes into account.
9536 const transitionClasses = el._vtc;
9537 if (transitionClasses) {
9538 value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
9539 }
9540 if (value == null) {
9541 el.removeAttribute('class');
9542 }
9543 else if (isSVG) {
9544 el.setAttribute('class', value);
9545 }
9546 else {
9547 el.className = value;
9548 }
9549 }
9550
9551 function patchStyle(el, prev, next) {
9552 const style = el.style;
9553 const isCssString = isString(next);
9554 if (next && !isCssString) {
9555 if (prev && !isString(prev)) {
9556 for (const key in prev) {
9557 if (next[key] == null) {
9558 setStyle(style, key, '');
9559 }
9560 }
9561 }
9562 for (const key in next) {
9563 setStyle(style, key, next[key]);
9564 }
9565 }
9566 else {
9567 const currentDisplay = style.display;
9568 if (isCssString) {
9569 if (prev !== next) {
9570 style.cssText = next;
9571 }
9572 }
9573 else if (prev) {
9574 el.removeAttribute('style');
9575 }
9576 // indicates that the `display` of the element is controlled by `v-show`,
9577 // so we always keep the current `display` value regardless of the `style`
9578 // value, thus handing over control to `v-show`.
9579 if ('_vod' in el) {
9580 style.display = currentDisplay;
9581 }
9582 }
9583 }
9584 const semicolonRE = /[^\\];\s*$/;
9585 const importantRE = /\s*!important$/;
9586 function setStyle(style, name, val) {
9587 if (isArray(val)) {
9588 val.forEach(v => setStyle(style, name, v));
9589 }
9590 else {
9591 if (val == null)
9592 val = '';
9593 {
9594 if (semicolonRE.test(val)) {
9595 warn(`Unexpected semicolon at the end of '${name}' style value: '${val}'`);
9596 }
9597 }
9598 if (name.startsWith('--')) {
9599 // custom property definition
9600 style.setProperty(name, val);
9601 }
9602 else {
9603 const prefixed = autoPrefix(style, name);
9604 if (importantRE.test(val)) {
9605 // !important
9606 style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
9607 }
9608 else {
9609 style[prefixed] = val;
9610 }
9611 }
9612 }
9613 }
9614 const prefixes = ['Webkit', 'Moz', 'ms'];
9615 const prefixCache = {};
9616 function autoPrefix(style, rawName) {
9617 const cached = prefixCache[rawName];
9618 if (cached) {
9619 return cached;
9620 }
9621 let name = camelize(rawName);
9622 if (name !== 'filter' && name in style) {
9623 return (prefixCache[rawName] = name);
9624 }
9625 name = capitalize(name);
9626 for (let i = 0; i < prefixes.length; i++) {
9627 const prefixed = prefixes[i] + name;
9628 if (prefixed in style) {
9629 return (prefixCache[rawName] = prefixed);
9630 }
9631 }
9632 return rawName;
9633 }
9634
9635 const xlinkNS = 'http://www.w3.org/1999/xlink';
9636 function patchAttr(el, key, value, isSVG, instance) {
9637 if (isSVG && key.startsWith('xlink:')) {
9638 if (value == null) {
9639 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
9640 }
9641 else {
9642 el.setAttributeNS(xlinkNS, key, value);
9643 }
9644 }
9645 else {
9646 // note we are only checking boolean attributes that don't have a
9647 // corresponding dom prop of the same name here.
9648 const isBoolean = isSpecialBooleanAttr(key);
9649 if (value == null || (isBoolean && !includeBooleanAttr(value))) {
9650 el.removeAttribute(key);
9651 }
9652 else {
9653 el.setAttribute(key, isBoolean ? '' : value);
9654 }
9655 }
9656 }
9657
9658 // __UNSAFE__
9659 // functions. The user is responsible for using them with only trusted content.
9660 function patchDOMProp(el, key, value,
9661 // the following args are passed only due to potential innerHTML/textContent
9662 // overriding existing VNodes, in which case the old tree must be properly
9663 // unmounted.
9664 prevChildren, parentComponent, parentSuspense, unmountChildren) {
9665 if (key === 'innerHTML' || key === 'textContent') {
9666 if (prevChildren) {
9667 unmountChildren(prevChildren, parentComponent, parentSuspense);
9668 }
9669 el[key] = value == null ? '' : value;
9670 return;
9671 }
9672 if (key === 'value' &&
9673 el.tagName !== 'PROGRESS' &&
9674 // custom elements may use _value internally
9675 !el.tagName.includes('-')) {
9676 // store value as _value as well since
9677 // non-string values will be stringified.
9678 el._value = value;
9679 const newValue = value == null ? '' : value;
9680 if (el.value !== newValue ||
9681 // #4956: always set for OPTION elements because its value falls back to
9682 // textContent if no value attribute is present. And setting .value for
9683 // OPTION has no side effect
9684 el.tagName === 'OPTION') {
9685 el.value = newValue;
9686 }
9687 if (value == null) {
9688 el.removeAttribute(key);
9689 }
9690 return;
9691 }
9692 let needRemove = false;
9693 if (value === '' || value == null) {
9694 const type = typeof el[key];
9695 if (type === 'boolean') {
9696 // e.g. <select multiple> compiles to { multiple: '' }
9697 value = includeBooleanAttr(value);
9698 }
9699 else if (value == null && type === 'string') {
9700 // e.g. <div :id="null">
9701 value = '';
9702 needRemove = true;
9703 }
9704 else if (type === 'number') {
9705 // e.g. <img :width="null">
9706 value = 0;
9707 needRemove = true;
9708 }
9709 }
9710 // some properties perform value validation and throw,
9711 // some properties has getter, no setter, will error in 'use strict'
9712 // eg. <select :type="null"></select> <select :willValidate="null"></select>
9713 try {
9714 el[key] = value;
9715 }
9716 catch (e) {
9717 // do not warn if value is auto-coerced from nullish values
9718 if (!needRemove) {
9719 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
9720 `value ${value} is invalid.`, e);
9721 }
9722 }
9723 needRemove && el.removeAttribute(key);
9724 }
9725
9726 function addEventListener(el, event, handler, options) {
9727 el.addEventListener(event, handler, options);
9728 }
9729 function removeEventListener(el, event, handler, options) {
9730 el.removeEventListener(event, handler, options);
9731 }
9732 function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
9733 // vei = vue event invokers
9734 const invokers = el._vei || (el._vei = {});
9735 const existingInvoker = invokers[rawName];
9736 if (nextValue && existingInvoker) {
9737 // patch
9738 existingInvoker.value = nextValue;
9739 }
9740 else {
9741 const [name, options] = parseName(rawName);
9742 if (nextValue) {
9743 // add
9744 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
9745 addEventListener(el, name, invoker, options);
9746 }
9747 else if (existingInvoker) {
9748 // remove
9749 removeEventListener(el, name, existingInvoker, options);
9750 invokers[rawName] = undefined;
9751 }
9752 }
9753 }
9754 const optionsModifierRE = /(?:Once|Passive|Capture)$/;
9755 function parseName(name) {
9756 let options;
9757 if (optionsModifierRE.test(name)) {
9758 options = {};
9759 let m;
9760 while ((m = name.match(optionsModifierRE))) {
9761 name = name.slice(0, name.length - m[0].length);
9762 options[m[0].toLowerCase()] = true;
9763 }
9764 }
9765 const event = name[2] === ':' ? name.slice(3) : hyphenate(name.slice(2));
9766 return [event, options];
9767 }
9768 // To avoid the overhead of repeatedly calling Date.now(), we cache
9769 // and use the same timestamp for all event listeners attached in the same tick.
9770 let cachedNow = 0;
9771 const p = /*#__PURE__*/ Promise.resolve();
9772 const getNow = () => cachedNow || (p.then(() => (cachedNow = 0)), (cachedNow = Date.now()));
9773 function createInvoker(initialValue, instance) {
9774 const invoker = (e) => {
9775 // async edge case vuejs/vue#6566
9776 // inner click event triggers patch, event handler
9777 // attached to outer element during patch, and triggered again. This
9778 // happens because browsers fire microtask ticks between event propagation.
9779 // this no longer happens for templates in Vue 3, but could still be
9780 // theoretically possible for hand-written render functions.
9781 // the solution: we save the timestamp when a handler is attached,
9782 // and also attach the timestamp to any event that was handled by vue
9783 // for the first time (to avoid inconsistent event timestamp implementations
9784 // or events fired from iframes, e.g. #2513)
9785 // The handler would only fire if the event passed to it was fired
9786 // AFTER it was attached.
9787 if (!e._vts) {
9788 e._vts = Date.now();
9789 }
9790 else if (e._vts <= invoker.attached) {
9791 return;
9792 }
9793 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* ErrorCodes.NATIVE_EVENT_HANDLER */, [e]);
9794 };
9795 invoker.value = initialValue;
9796 invoker.attached = getNow();
9797 return invoker;
9798 }
9799 function patchStopImmediatePropagation(e, value) {
9800 if (isArray(value)) {
9801 const originalStop = e.stopImmediatePropagation;
9802 e.stopImmediatePropagation = () => {
9803 originalStop.call(e);
9804 e._stopped = true;
9805 };
9806 return value.map(fn => (e) => !e._stopped && fn && fn(e));
9807 }
9808 else {
9809 return value;
9810 }
9811 }
9812
9813 const nativeOnRE = /^on[a-z]/;
9814 const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
9815 if (key === 'class') {
9816 patchClass(el, nextValue, isSVG);
9817 }
9818 else if (key === 'style') {
9819 patchStyle(el, prevValue, nextValue);
9820 }
9821 else if (isOn(key)) {
9822 // ignore v-model listeners
9823 if (!isModelListener(key)) {
9824 patchEvent(el, key, prevValue, nextValue, parentComponent);
9825 }
9826 }
9827 else if (key[0] === '.'
9828 ? ((key = key.slice(1)), true)
9829 : key[0] === '^'
9830 ? ((key = key.slice(1)), false)
9831 : shouldSetAsProp(el, key, nextValue, isSVG)) {
9832 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
9833 }
9834 else {
9835 // special case for <input v-model type="checkbox"> with
9836 // :true-value & :false-value
9837 // store value as dom properties since non-string values will be
9838 // stringified.
9839 if (key === 'true-value') {
9840 el._trueValue = nextValue;
9841 }
9842 else if (key === 'false-value') {
9843 el._falseValue = nextValue;
9844 }
9845 patchAttr(el, key, nextValue, isSVG);
9846 }
9847 };
9848 function shouldSetAsProp(el, key, value, isSVG) {
9849 if (isSVG) {
9850 // most keys must be set as attribute on svg elements to work
9851 // ...except innerHTML & textContent
9852 if (key === 'innerHTML' || key === 'textContent') {
9853 return true;
9854 }
9855 // or native onclick with function values
9856 if (key in el && nativeOnRE.test(key) && isFunction(value)) {
9857 return true;
9858 }
9859 return false;
9860 }
9861 // these are enumerated attrs, however their corresponding DOM properties
9862 // are actually booleans - this leads to setting it with a string "false"
9863 // value leading it to be coerced to `true`, so we need to always treat
9864 // them as attributes.
9865 // Note that `contentEditable` doesn't have this problem: its DOM
9866 // property is also enumerated string values.
9867 if (key === 'spellcheck' || key === 'draggable' || key === 'translate') {
9868 return false;
9869 }
9870 // #1787, #2840 form property on form elements is readonly and must be set as
9871 // attribute.
9872 if (key === 'form') {
9873 return false;
9874 }
9875 // #1526 <input list> must be set as attribute
9876 if (key === 'list' && el.tagName === 'INPUT') {
9877 return false;
9878 }
9879 // #2766 <textarea type> must be set as attribute
9880 if (key === 'type' && el.tagName === 'TEXTAREA') {
9881 return false;
9882 }
9883 // native onclick with string value, must be set as attribute
9884 if (nativeOnRE.test(key) && isString(value)) {
9885 return false;
9886 }
9887 return key in el;
9888 }
9889
9890 function defineCustomElement(options, hydrate) {
9891 const Comp = defineComponent(options);
9892 class VueCustomElement extends VueElement {
9893 constructor(initialProps) {
9894 super(Comp, initialProps, hydrate);
9895 }
9896 }
9897 VueCustomElement.def = Comp;
9898 return VueCustomElement;
9899 }
9900 const defineSSRCustomElement = ((options) => {
9901 // @ts-ignore
9902 return defineCustomElement(options, hydrate);
9903 });
9904 const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
9905 });
9906 class VueElement extends BaseClass {
9907 constructor(_def, _props = {}, hydrate) {
9908 super();
9909 this._def = _def;
9910 this._props = _props;
9911 /**
9912 * @internal
9913 */
9914 this._instance = null;
9915 this._connected = false;
9916 this._resolved = false;
9917 this._numberProps = null;
9918 if (this.shadowRoot && hydrate) {
9919 hydrate(this._createVNode(), this.shadowRoot);
9920 }
9921 else {
9922 if (this.shadowRoot) {
9923 warn(`Custom element has pre-rendered declarative shadow root but is not ` +
9924 `defined as hydratable. Use \`defineSSRCustomElement\`.`);
9925 }
9926 this.attachShadow({ mode: 'open' });
9927 if (!this._def.__asyncLoader) {
9928 // for sync component defs we can immediately resolve props
9929 this._resolveProps(this._def);
9930 }
9931 }
9932 }
9933 connectedCallback() {
9934 this._connected = true;
9935 if (!this._instance) {
9936 if (this._resolved) {
9937 this._update();
9938 }
9939 else {
9940 this._resolveDef();
9941 }
9942 }
9943 }
9944 disconnectedCallback() {
9945 this._connected = false;
9946 nextTick(() => {
9947 if (!this._connected) {
9948 render(null, this.shadowRoot);
9949 this._instance = null;
9950 }
9951 });
9952 }
9953 /**
9954 * resolve inner component definition (handle possible async component)
9955 */
9956 _resolveDef() {
9957 this._resolved = true;
9958 // set initial attrs
9959 for (let i = 0; i < this.attributes.length; i++) {
9960 this._setAttr(this.attributes[i].name);
9961 }
9962 // watch future attr changes
9963 new MutationObserver(mutations => {
9964 for (const m of mutations) {
9965 this._setAttr(m.attributeName);
9966 }
9967 }).observe(this, { attributes: true });
9968 const resolve = (def, isAsync = false) => {
9969 const { props, styles } = def;
9970 // cast Number-type props set before resolve
9971 let numberProps;
9972 if (props && !isArray(props)) {
9973 for (const key in props) {
9974 const opt = props[key];
9975 if (opt === Number || (opt && opt.type === Number)) {
9976 if (key in this._props) {
9977 this._props[key] = toNumber(this._props[key]);
9978 }
9979 (numberProps || (numberProps = Object.create(null)))[camelize(key)] = true;
9980 }
9981 }
9982 }
9983 this._numberProps = numberProps;
9984 if (isAsync) {
9985 // defining getter/setters on prototype
9986 // for sync defs, this already happened in the constructor
9987 this._resolveProps(def);
9988 }
9989 // apply CSS
9990 this._applyStyles(styles);
9991 // initial render
9992 this._update();
9993 };
9994 const asyncDef = this._def.__asyncLoader;
9995 if (asyncDef) {
9996 asyncDef().then(def => resolve(def, true));
9997 }
9998 else {
9999 resolve(this._def);
10000 }
10001 }
10002 _resolveProps(def) {
10003 const { props } = def;
10004 const declaredPropKeys = isArray(props) ? props : Object.keys(props || {});
10005 // check if there are props set pre-upgrade or connect
10006 for (const key of Object.keys(this)) {
10007 if (key[0] !== '_' && declaredPropKeys.includes(key)) {
10008 this._setProp(key, this[key], true, false);
10009 }
10010 }
10011 // defining getter/setters on prototype
10012 for (const key of declaredPropKeys.map(camelize)) {
10013 Object.defineProperty(this, key, {
10014 get() {
10015 return this._getProp(key);
10016 },
10017 set(val) {
10018 this._setProp(key, val);
10019 }
10020 });
10021 }
10022 }
10023 _setAttr(key) {
10024 let value = this.getAttribute(key);
10025 const camelKey = camelize(key);
10026 if (this._numberProps && this._numberProps[camelKey]) {
10027 value = toNumber(value);
10028 }
10029 this._setProp(camelKey, value, false);
10030 }
10031 /**
10032 * @internal
10033 */
10034 _getProp(key) {
10035 return this._props[key];
10036 }
10037 /**
10038 * @internal
10039 */
10040 _setProp(key, val, shouldReflect = true, shouldUpdate = true) {
10041 if (val !== this._props[key]) {
10042 this._props[key] = val;
10043 if (shouldUpdate && this._instance) {
10044 this._update();
10045 }
10046 // reflect
10047 if (shouldReflect) {
10048 if (val === true) {
10049 this.setAttribute(hyphenate(key), '');
10050 }
10051 else if (typeof val === 'string' || typeof val === 'number') {
10052 this.setAttribute(hyphenate(key), val + '');
10053 }
10054 else if (!val) {
10055 this.removeAttribute(hyphenate(key));
10056 }
10057 }
10058 }
10059 }
10060 _update() {
10061 render(this._createVNode(), this.shadowRoot);
10062 }
10063 _createVNode() {
10064 const vnode = createVNode(this._def, extend({}, this._props));
10065 if (!this._instance) {
10066 vnode.ce = instance => {
10067 this._instance = instance;
10068 instance.isCE = true;
10069 // HMR
10070 {
10071 instance.ceReload = newStyles => {
10072 // always reset styles
10073 if (this._styles) {
10074 this._styles.forEach(s => this.shadowRoot.removeChild(s));
10075 this._styles.length = 0;
10076 }
10077 this._applyStyles(newStyles);
10078 this._instance = null;
10079 this._update();
10080 };
10081 }
10082 const dispatch = (event, args) => {
10083 this.dispatchEvent(new CustomEvent(event, {
10084 detail: args
10085 }));
10086 };
10087 // intercept emit
10088 instance.emit = (event, ...args) => {
10089 // dispatch both the raw and hyphenated versions of an event
10090 // to match Vue behavior
10091 dispatch(event, args);
10092 if (hyphenate(event) !== event) {
10093 dispatch(hyphenate(event), args);
10094 }
10095 };
10096 // locate nearest Vue custom element parent for provide/inject
10097 let parent = this;
10098 while ((parent =
10099 parent && (parent.parentNode || parent.host))) {
10100 if (parent instanceof VueElement) {
10101 instance.parent = parent._instance;
10102 instance.provides = parent._instance.provides;
10103 break;
10104 }
10105 }
10106 };
10107 }
10108 return vnode;
10109 }
10110 _applyStyles(styles) {
10111 if (styles) {
10112 styles.forEach(css => {
10113 const s = document.createElement('style');
10114 s.textContent = css;
10115 this.shadowRoot.appendChild(s);
10116 // record for HMR
10117 {
10118 (this._styles || (this._styles = [])).push(s);
10119 }
10120 });
10121 }
10122 }
10123 }
10124
10125 function useCssModule(name = '$style') {
10126 /* istanbul ignore else */
10127 {
10128 {
10129 warn(`useCssModule() is not supported in the global build.`);
10130 }
10131 return EMPTY_OBJ;
10132 }
10133 }
10134
10135 /**
10136 * Runtime helper for SFC's CSS variable injection feature.
10137 * @private
10138 */
10139 function useCssVars(getter) {
10140 const instance = getCurrentInstance();
10141 /* istanbul ignore next */
10142 if (!instance) {
10143 warn(`useCssVars is called without current active component instance.`);
10144 return;
10145 }
10146 const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => {
10147 Array.from(document.querySelectorAll(`[data-v-owner="${instance.uid}"]`)).forEach(node => setVarsOnNode(node, vars));
10148 });
10149 const setVars = () => {
10150 const vars = getter(instance.proxy);
10151 setVarsOnVNode(instance.subTree, vars);
10152 updateTeleports(vars);
10153 };
10154 watchPostEffect(setVars);
10155 onMounted(() => {
10156 const ob = new MutationObserver(setVars);
10157 ob.observe(instance.subTree.el.parentNode, { childList: true });
10158 onUnmounted(() => ob.disconnect());
10159 });
10160 }
10161 function setVarsOnVNode(vnode, vars) {
10162 if (vnode.shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
10163 const suspense = vnode.suspense;
10164 vnode = suspense.activeBranch;
10165 if (suspense.pendingBranch && !suspense.isHydrating) {
10166 suspense.effects.push(() => {
10167 setVarsOnVNode(suspense.activeBranch, vars);
10168 });
10169 }
10170 }
10171 // drill down HOCs until it's a non-component vnode
10172 while (vnode.component) {
10173 vnode = vnode.component.subTree;
10174 }
10175 if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */ && vnode.el) {
10176 setVarsOnNode(vnode.el, vars);
10177 }
10178 else if (vnode.type === Fragment) {
10179 vnode.children.forEach(c => setVarsOnVNode(c, vars));
10180 }
10181 else if (vnode.type === Static) {
10182 let { el, anchor } = vnode;
10183 while (el) {
10184 setVarsOnNode(el, vars);
10185 if (el === anchor)
10186 break;
10187 el = el.nextSibling;
10188 }
10189 }
10190 }
10191 function setVarsOnNode(el, vars) {
10192 if (el.nodeType === 1) {
10193 const style = el.style;
10194 for (const key in vars) {
10195 style.setProperty(`--${key}`, vars[key]);
10196 }
10197 }
10198 }
10199
10200 const TRANSITION$1 = 'transition';
10201 const ANIMATION = 'animation';
10202 // DOM Transition is a higher-order-component based on the platform-agnostic
10203 // base Transition component, with DOM-specific logic.
10204 const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
10205 Transition.displayName = 'Transition';
10206 const DOMTransitionPropsValidators = {
10207 name: String,
10208 type: String,
10209 css: {
10210 type: Boolean,
10211 default: true
10212 },
10213 duration: [String, Number, Object],
10214 enterFromClass: String,
10215 enterActiveClass: String,
10216 enterToClass: String,
10217 appearFromClass: String,
10218 appearActiveClass: String,
10219 appearToClass: String,
10220 leaveFromClass: String,
10221 leaveActiveClass: String,
10222 leaveToClass: String
10223 };
10224 const TransitionPropsValidators = (Transition.props =
10225 /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
10226 /**
10227 * #3227 Incoming hooks may be merged into arrays when wrapping Transition
10228 * with custom HOCs.
10229 */
10230 const callHook = (hook, args = []) => {
10231 if (isArray(hook)) {
10232 hook.forEach(h => h(...args));
10233 }
10234 else if (hook) {
10235 hook(...args);
10236 }
10237 };
10238 /**
10239 * Check if a hook expects a callback (2nd arg), which means the user
10240 * intends to explicitly control the end of the transition.
10241 */
10242 const hasExplicitCallback = (hook) => {
10243 return hook
10244 ? isArray(hook)
10245 ? hook.some(h => h.length > 1)
10246 : hook.length > 1
10247 : false;
10248 };
10249 function resolveTransitionProps(rawProps) {
10250 const baseProps = {};
10251 for (const key in rawProps) {
10252 if (!(key in DOMTransitionPropsValidators)) {
10253 baseProps[key] = rawProps[key];
10254 }
10255 }
10256 if (rawProps.css === false) {
10257 return baseProps;
10258 }
10259 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;
10260 const durations = normalizeDuration(duration);
10261 const enterDuration = durations && durations[0];
10262 const leaveDuration = durations && durations[1];
10263 const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
10264 const finishEnter = (el, isAppear, done) => {
10265 removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
10266 removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
10267 done && done();
10268 };
10269 const finishLeave = (el, done) => {
10270 el._isLeaving = false;
10271 removeTransitionClass(el, leaveFromClass);
10272 removeTransitionClass(el, leaveToClass);
10273 removeTransitionClass(el, leaveActiveClass);
10274 done && done();
10275 };
10276 const makeEnterHook = (isAppear) => {
10277 return (el, done) => {
10278 const hook = isAppear ? onAppear : onEnter;
10279 const resolve = () => finishEnter(el, isAppear, done);
10280 callHook(hook, [el, resolve]);
10281 nextFrame(() => {
10282 removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
10283 addTransitionClass(el, isAppear ? appearToClass : enterToClass);
10284 if (!hasExplicitCallback(hook)) {
10285 whenTransitionEnds(el, type, enterDuration, resolve);
10286 }
10287 });
10288 };
10289 };
10290 return extend(baseProps, {
10291 onBeforeEnter(el) {
10292 callHook(onBeforeEnter, [el]);
10293 addTransitionClass(el, enterFromClass);
10294 addTransitionClass(el, enterActiveClass);
10295 },
10296 onBeforeAppear(el) {
10297 callHook(onBeforeAppear, [el]);
10298 addTransitionClass(el, appearFromClass);
10299 addTransitionClass(el, appearActiveClass);
10300 },
10301 onEnter: makeEnterHook(false),
10302 onAppear: makeEnterHook(true),
10303 onLeave(el, done) {
10304 el._isLeaving = true;
10305 const resolve = () => finishLeave(el, done);
10306 addTransitionClass(el, leaveFromClass);
10307 // force reflow so *-leave-from classes immediately take effect (#2593)
10308 forceReflow();
10309 addTransitionClass(el, leaveActiveClass);
10310 nextFrame(() => {
10311 if (!el._isLeaving) {
10312 // cancelled
10313 return;
10314 }
10315 removeTransitionClass(el, leaveFromClass);
10316 addTransitionClass(el, leaveToClass);
10317 if (!hasExplicitCallback(onLeave)) {
10318 whenTransitionEnds(el, type, leaveDuration, resolve);
10319 }
10320 });
10321 callHook(onLeave, [el, resolve]);
10322 },
10323 onEnterCancelled(el) {
10324 finishEnter(el, false);
10325 callHook(onEnterCancelled, [el]);
10326 },
10327 onAppearCancelled(el) {
10328 finishEnter(el, true);
10329 callHook(onAppearCancelled, [el]);
10330 },
10331 onLeaveCancelled(el) {
10332 finishLeave(el);
10333 callHook(onLeaveCancelled, [el]);
10334 }
10335 });
10336 }
10337 function normalizeDuration(duration) {
10338 if (duration == null) {
10339 return null;
10340 }
10341 else if (isObject(duration)) {
10342 return [NumberOf(duration.enter), NumberOf(duration.leave)];
10343 }
10344 else {
10345 const n = NumberOf(duration);
10346 return [n, n];
10347 }
10348 }
10349 function NumberOf(val) {
10350 const res = toNumber(val);
10351 {
10352 assertNumber(res, '<transition> explicit duration');
10353 }
10354 return res;
10355 }
10356 function addTransitionClass(el, cls) {
10357 cls.split(/\s+/).forEach(c => c && el.classList.add(c));
10358 (el._vtc ||
10359 (el._vtc = new Set())).add(cls);
10360 }
10361 function removeTransitionClass(el, cls) {
10362 cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
10363 const { _vtc } = el;
10364 if (_vtc) {
10365 _vtc.delete(cls);
10366 if (!_vtc.size) {
10367 el._vtc = undefined;
10368 }
10369 }
10370 }
10371 function nextFrame(cb) {
10372 requestAnimationFrame(() => {
10373 requestAnimationFrame(cb);
10374 });
10375 }
10376 let endId = 0;
10377 function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
10378 const id = (el._endId = ++endId);
10379 const resolveIfNotStale = () => {
10380 if (id === el._endId) {
10381 resolve();
10382 }
10383 };
10384 if (explicitTimeout) {
10385 return setTimeout(resolveIfNotStale, explicitTimeout);
10386 }
10387 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
10388 if (!type) {
10389 return resolve();
10390 }
10391 const endEvent = type + 'end';
10392 let ended = 0;
10393 const end = () => {
10394 el.removeEventListener(endEvent, onEnd);
10395 resolveIfNotStale();
10396 };
10397 const onEnd = (e) => {
10398 if (e.target === el && ++ended >= propCount) {
10399 end();
10400 }
10401 };
10402 setTimeout(() => {
10403 if (ended < propCount) {
10404 end();
10405 }
10406 }, timeout + 1);
10407 el.addEventListener(endEvent, onEnd);
10408 }
10409 function getTransitionInfo(el, expectedType) {
10410 const styles = window.getComputedStyle(el);
10411 // JSDOM may return undefined for transition properties
10412 const getStyleProperties = (key) => (styles[key] || '').split(', ');
10413 const transitionDelays = getStyleProperties(`${TRANSITION$1}Delay`);
10414 const transitionDurations = getStyleProperties(`${TRANSITION$1}Duration`);
10415 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
10416 const animationDelays = getStyleProperties(`${ANIMATION}Delay`);
10417 const animationDurations = getStyleProperties(`${ANIMATION}Duration`);
10418 const animationTimeout = getTimeout(animationDelays, animationDurations);
10419 let type = null;
10420 let timeout = 0;
10421 let propCount = 0;
10422 /* istanbul ignore if */
10423 if (expectedType === TRANSITION$1) {
10424 if (transitionTimeout > 0) {
10425 type = TRANSITION$1;
10426 timeout = transitionTimeout;
10427 propCount = transitionDurations.length;
10428 }
10429 }
10430 else if (expectedType === ANIMATION) {
10431 if (animationTimeout > 0) {
10432 type = ANIMATION;
10433 timeout = animationTimeout;
10434 propCount = animationDurations.length;
10435 }
10436 }
10437 else {
10438 timeout = Math.max(transitionTimeout, animationTimeout);
10439 type =
10440 timeout > 0
10441 ? transitionTimeout > animationTimeout
10442 ? TRANSITION$1
10443 : ANIMATION
10444 : null;
10445 propCount = type
10446 ? type === TRANSITION$1
10447 ? transitionDurations.length
10448 : animationDurations.length
10449 : 0;
10450 }
10451 const hasTransform = type === TRANSITION$1 &&
10452 /\b(transform|all)(,|$)/.test(getStyleProperties(`${TRANSITION$1}Property`).toString());
10453 return {
10454 type,
10455 timeout,
10456 propCount,
10457 hasTransform
10458 };
10459 }
10460 function getTimeout(delays, durations) {
10461 while (delays.length < durations.length) {
10462 delays = delays.concat(delays);
10463 }
10464 return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
10465 }
10466 // Old versions of Chromium (below 61.0.3163.100) formats floating pointer
10467 // numbers in a locale-dependent way, using a comma instead of a dot.
10468 // If comma is not replaced with a dot, the input will be rounded down
10469 // (i.e. acting as a floor function) causing unexpected behaviors
10470 function toMs(s) {
10471 return Number(s.slice(0, -1).replace(',', '.')) * 1000;
10472 }
10473 // synchronously force layout to put elements into a certain state
10474 function forceReflow() {
10475 return document.body.offsetHeight;
10476 }
10477
10478 const positionMap = new WeakMap();
10479 const newPositionMap = new WeakMap();
10480 const TransitionGroupImpl = {
10481 name: 'TransitionGroup',
10482 props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
10483 tag: String,
10484 moveClass: String
10485 }),
10486 setup(props, { slots }) {
10487 const instance = getCurrentInstance();
10488 const state = useTransitionState();
10489 let prevChildren;
10490 let children;
10491 onUpdated(() => {
10492 // children is guaranteed to exist after initial render
10493 if (!prevChildren.length) {
10494 return;
10495 }
10496 const moveClass = props.moveClass || `${props.name || 'v'}-move`;
10497 if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
10498 return;
10499 }
10500 // we divide the work into three loops to avoid mixing DOM reads and writes
10501 // in each iteration - which helps prevent layout thrashing.
10502 prevChildren.forEach(callPendingCbs);
10503 prevChildren.forEach(recordPosition);
10504 const movedChildren = prevChildren.filter(applyTranslation);
10505 // force reflow to put everything in position
10506 forceReflow();
10507 movedChildren.forEach(c => {
10508 const el = c.el;
10509 const style = el.style;
10510 addTransitionClass(el, moveClass);
10511 style.transform = style.webkitTransform = style.transitionDuration = '';
10512 const cb = (el._moveCb = (e) => {
10513 if (e && e.target !== el) {
10514 return;
10515 }
10516 if (!e || /transform$/.test(e.propertyName)) {
10517 el.removeEventListener('transitionend', cb);
10518 el._moveCb = null;
10519 removeTransitionClass(el, moveClass);
10520 }
10521 });
10522 el.addEventListener('transitionend', cb);
10523 });
10524 });
10525 return () => {
10526 const rawProps = toRaw(props);
10527 const cssTransitionProps = resolveTransitionProps(rawProps);
10528 let tag = rawProps.tag || Fragment;
10529 prevChildren = children;
10530 children = slots.default ? getTransitionRawChildren(slots.default()) : [];
10531 for (let i = 0; i < children.length; i++) {
10532 const child = children[i];
10533 if (child.key != null) {
10534 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10535 }
10536 else {
10537 warn(`<TransitionGroup> children must be keyed.`);
10538 }
10539 }
10540 if (prevChildren) {
10541 for (let i = 0; i < prevChildren.length; i++) {
10542 const child = prevChildren[i];
10543 setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
10544 positionMap.set(child, child.el.getBoundingClientRect());
10545 }
10546 }
10547 return createVNode(tag, null, children);
10548 };
10549 }
10550 };
10551 /**
10552 * TransitionGroup does not support "mode" so we need to remove it from the
10553 * props declarations, but direct delete operation is considered a side effect
10554 * and will make the entire transition feature non-tree-shakeable, so we do it
10555 * in a function and mark the function's invocation as pure.
10556 */
10557 const removeMode = (props) => delete props.mode;
10558 /*#__PURE__*/ removeMode(TransitionGroupImpl.props);
10559 const TransitionGroup = TransitionGroupImpl;
10560 function callPendingCbs(c) {
10561 const el = c.el;
10562 if (el._moveCb) {
10563 el._moveCb();
10564 }
10565 if (el._enterCb) {
10566 el._enterCb();
10567 }
10568 }
10569 function recordPosition(c) {
10570 newPositionMap.set(c, c.el.getBoundingClientRect());
10571 }
10572 function applyTranslation(c) {
10573 const oldPos = positionMap.get(c);
10574 const newPos = newPositionMap.get(c);
10575 const dx = oldPos.left - newPos.left;
10576 const dy = oldPos.top - newPos.top;
10577 if (dx || dy) {
10578 const s = c.el.style;
10579 s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
10580 s.transitionDuration = '0s';
10581 return c;
10582 }
10583 }
10584 function hasCSSTransform(el, root, moveClass) {
10585 // Detect whether an element with the move class applied has
10586 // CSS transitions. Since the element may be inside an entering
10587 // transition at this very moment, we make a clone of it and remove
10588 // all other transition classes applied to ensure only the move class
10589 // is applied.
10590 const clone = el.cloneNode();
10591 if (el._vtc) {
10592 el._vtc.forEach(cls => {
10593 cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
10594 });
10595 }
10596 moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
10597 clone.style.display = 'none';
10598 const container = (root.nodeType === 1 ? root : root.parentNode);
10599 container.appendChild(clone);
10600 const { hasTransform } = getTransitionInfo(clone);
10601 container.removeChild(clone);
10602 return hasTransform;
10603 }
10604
10605 const getModelAssigner = (vnode) => {
10606 const fn = vnode.props['onUpdate:modelValue'] ||
10607 (false );
10608 return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
10609 };
10610 function onCompositionStart(e) {
10611 e.target.composing = true;
10612 }
10613 function onCompositionEnd(e) {
10614 const target = e.target;
10615 if (target.composing) {
10616 target.composing = false;
10617 target.dispatchEvent(new Event('input'));
10618 }
10619 }
10620 // We are exporting the v-model runtime directly as vnode hooks so that it can
10621 // be tree-shaken in case v-model is never used.
10622 const vModelText = {
10623 created(el, { modifiers: { lazy, trim, number } }, vnode) {
10624 el._assign = getModelAssigner(vnode);
10625 const castToNumber = number || (vnode.props && vnode.props.type === 'number');
10626 addEventListener(el, lazy ? 'change' : 'input', e => {
10627 if (e.target.composing)
10628 return;
10629 let domValue = el.value;
10630 if (trim) {
10631 domValue = domValue.trim();
10632 }
10633 if (castToNumber) {
10634 domValue = looseToNumber(domValue);
10635 }
10636 el._assign(domValue);
10637 });
10638 if (trim) {
10639 addEventListener(el, 'change', () => {
10640 el.value = el.value.trim();
10641 });
10642 }
10643 if (!lazy) {
10644 addEventListener(el, 'compositionstart', onCompositionStart);
10645 addEventListener(el, 'compositionend', onCompositionEnd);
10646 // Safari < 10.2 & UIWebView doesn't fire compositionend when
10647 // switching focus before confirming composition choice
10648 // this also fixes the issue where some browsers e.g. iOS Chrome
10649 // fires "change" instead of "input" on autocomplete.
10650 addEventListener(el, 'change', onCompositionEnd);
10651 }
10652 },
10653 // set value on mounted so it's after min/max for type="range"
10654 mounted(el, { value }) {
10655 el.value = value == null ? '' : value;
10656 },
10657 beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
10658 el._assign = getModelAssigner(vnode);
10659 // avoid clearing unresolved text. #2302
10660 if (el.composing)
10661 return;
10662 if (document.activeElement === el && el.type !== 'range') {
10663 if (lazy) {
10664 return;
10665 }
10666 if (trim && el.value.trim() === value) {
10667 return;
10668 }
10669 if ((number || el.type === 'number') &&
10670 looseToNumber(el.value) === value) {
10671 return;
10672 }
10673 }
10674 const newValue = value == null ? '' : value;
10675 if (el.value !== newValue) {
10676 el.value = newValue;
10677 }
10678 }
10679 };
10680 const vModelCheckbox = {
10681 // #4096 array checkboxes need to be deep traversed
10682 deep: true,
10683 created(el, _, vnode) {
10684 el._assign = getModelAssigner(vnode);
10685 addEventListener(el, 'change', () => {
10686 const modelValue = el._modelValue;
10687 const elementValue = getValue(el);
10688 const checked = el.checked;
10689 const assign = el._assign;
10690 if (isArray(modelValue)) {
10691 const index = looseIndexOf(modelValue, elementValue);
10692 const found = index !== -1;
10693 if (checked && !found) {
10694 assign(modelValue.concat(elementValue));
10695 }
10696 else if (!checked && found) {
10697 const filtered = [...modelValue];
10698 filtered.splice(index, 1);
10699 assign(filtered);
10700 }
10701 }
10702 else if (isSet(modelValue)) {
10703 const cloned = new Set(modelValue);
10704 if (checked) {
10705 cloned.add(elementValue);
10706 }
10707 else {
10708 cloned.delete(elementValue);
10709 }
10710 assign(cloned);
10711 }
10712 else {
10713 assign(getCheckboxValue(el, checked));
10714 }
10715 });
10716 },
10717 // set initial checked on mount to wait for true-value/false-value
10718 mounted: setChecked,
10719 beforeUpdate(el, binding, vnode) {
10720 el._assign = getModelAssigner(vnode);
10721 setChecked(el, binding, vnode);
10722 }
10723 };
10724 function setChecked(el, { value, oldValue }, vnode) {
10725 el._modelValue = value;
10726 if (isArray(value)) {
10727 el.checked = looseIndexOf(value, vnode.props.value) > -1;
10728 }
10729 else if (isSet(value)) {
10730 el.checked = value.has(vnode.props.value);
10731 }
10732 else if (value !== oldValue) {
10733 el.checked = looseEqual(value, getCheckboxValue(el, true));
10734 }
10735 }
10736 const vModelRadio = {
10737 created(el, { value }, vnode) {
10738 el.checked = looseEqual(value, vnode.props.value);
10739 el._assign = getModelAssigner(vnode);
10740 addEventListener(el, 'change', () => {
10741 el._assign(getValue(el));
10742 });
10743 },
10744 beforeUpdate(el, { value, oldValue }, vnode) {
10745 el._assign = getModelAssigner(vnode);
10746 if (value !== oldValue) {
10747 el.checked = looseEqual(value, vnode.props.value);
10748 }
10749 }
10750 };
10751 const vModelSelect = {
10752 // <select multiple> value need to be deep traversed
10753 deep: true,
10754 created(el, { value, modifiers: { number } }, vnode) {
10755 const isSetModel = isSet(value);
10756 addEventListener(el, 'change', () => {
10757 const selectedVal = Array.prototype.filter
10758 .call(el.options, (o) => o.selected)
10759 .map((o) => number ? looseToNumber(getValue(o)) : getValue(o));
10760 el._assign(el.multiple
10761 ? isSetModel
10762 ? new Set(selectedVal)
10763 : selectedVal
10764 : selectedVal[0]);
10765 });
10766 el._assign = getModelAssigner(vnode);
10767 },
10768 // set value in mounted & updated because <select> relies on its children
10769 // <option>s.
10770 mounted(el, { value }) {
10771 setSelected(el, value);
10772 },
10773 beforeUpdate(el, _binding, vnode) {
10774 el._assign = getModelAssigner(vnode);
10775 },
10776 updated(el, { value }) {
10777 setSelected(el, value);
10778 }
10779 };
10780 function setSelected(el, value) {
10781 const isMultiple = el.multiple;
10782 if (isMultiple && !isArray(value) && !isSet(value)) {
10783 warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
10784 `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
10785 return;
10786 }
10787 for (let i = 0, l = el.options.length; i < l; i++) {
10788 const option = el.options[i];
10789 const optionValue = getValue(option);
10790 if (isMultiple) {
10791 if (isArray(value)) {
10792 option.selected = looseIndexOf(value, optionValue) > -1;
10793 }
10794 else {
10795 option.selected = value.has(optionValue);
10796 }
10797 }
10798 else {
10799 if (looseEqual(getValue(option), value)) {
10800 if (el.selectedIndex !== i)
10801 el.selectedIndex = i;
10802 return;
10803 }
10804 }
10805 }
10806 if (!isMultiple && el.selectedIndex !== -1) {
10807 el.selectedIndex = -1;
10808 }
10809 }
10810 // retrieve raw value set via :value bindings
10811 function getValue(el) {
10812 return '_value' in el ? el._value : el.value;
10813 }
10814 // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
10815 function getCheckboxValue(el, checked) {
10816 const key = checked ? '_trueValue' : '_falseValue';
10817 return key in el ? el[key] : checked;
10818 }
10819 const vModelDynamic = {
10820 created(el, binding, vnode) {
10821 callModelHook(el, binding, vnode, null, 'created');
10822 },
10823 mounted(el, binding, vnode) {
10824 callModelHook(el, binding, vnode, null, 'mounted');
10825 },
10826 beforeUpdate(el, binding, vnode, prevVNode) {
10827 callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
10828 },
10829 updated(el, binding, vnode, prevVNode) {
10830 callModelHook(el, binding, vnode, prevVNode, 'updated');
10831 }
10832 };
10833 function resolveDynamicModel(tagName, type) {
10834 switch (tagName) {
10835 case 'SELECT':
10836 return vModelSelect;
10837 case 'TEXTAREA':
10838 return vModelText;
10839 default:
10840 switch (type) {
10841 case 'checkbox':
10842 return vModelCheckbox;
10843 case 'radio':
10844 return vModelRadio;
10845 default:
10846 return vModelText;
10847 }
10848 }
10849 }
10850 function callModelHook(el, binding, vnode, prevVNode, hook) {
10851 const modelToUse = resolveDynamicModel(el.tagName, vnode.props && vnode.props.type);
10852 const fn = modelToUse[hook];
10853 fn && fn(el, binding, vnode, prevVNode);
10854 }
10855
10856 const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
10857 const modifierGuards = {
10858 stop: e => e.stopPropagation(),
10859 prevent: e => e.preventDefault(),
10860 self: e => e.target !== e.currentTarget,
10861 ctrl: e => !e.ctrlKey,
10862 shift: e => !e.shiftKey,
10863 alt: e => !e.altKey,
10864 meta: e => !e.metaKey,
10865 left: e => 'button' in e && e.button !== 0,
10866 middle: e => 'button' in e && e.button !== 1,
10867 right: e => 'button' in e && e.button !== 2,
10868 exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
10869 };
10870 /**
10871 * @private
10872 */
10873 const withModifiers = (fn, modifiers) => {
10874 return (event, ...args) => {
10875 for (let i = 0; i < modifiers.length; i++) {
10876 const guard = modifierGuards[modifiers[i]];
10877 if (guard && guard(event, modifiers))
10878 return;
10879 }
10880 return fn(event, ...args);
10881 };
10882 };
10883 // Kept for 2.x compat.
10884 // Note: IE11 compat for `spacebar` and `del` is removed for now.
10885 const keyNames = {
10886 esc: 'escape',
10887 space: ' ',
10888 up: 'arrow-up',
10889 left: 'arrow-left',
10890 right: 'arrow-right',
10891 down: 'arrow-down',
10892 delete: 'backspace'
10893 };
10894 /**
10895 * @private
10896 */
10897 const withKeys = (fn, modifiers) => {
10898 return (event) => {
10899 if (!('key' in event)) {
10900 return;
10901 }
10902 const eventKey = hyphenate(event.key);
10903 if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
10904 return fn(event);
10905 }
10906 };
10907 };
10908
10909 const vShow = {
10910 beforeMount(el, { value }, { transition }) {
10911 el._vod = el.style.display === 'none' ? '' : el.style.display;
10912 if (transition && value) {
10913 transition.beforeEnter(el);
10914 }
10915 else {
10916 setDisplay(el, value);
10917 }
10918 },
10919 mounted(el, { value }, { transition }) {
10920 if (transition && value) {
10921 transition.enter(el);
10922 }
10923 },
10924 updated(el, { value, oldValue }, { transition }) {
10925 if (!value === !oldValue)
10926 return;
10927 if (transition) {
10928 if (value) {
10929 transition.beforeEnter(el);
10930 setDisplay(el, true);
10931 transition.enter(el);
10932 }
10933 else {
10934 transition.leave(el, () => {
10935 setDisplay(el, false);
10936 });
10937 }
10938 }
10939 else {
10940 setDisplay(el, value);
10941 }
10942 },
10943 beforeUnmount(el, { value }) {
10944 setDisplay(el, value);
10945 }
10946 };
10947 function setDisplay(el, value) {
10948 el.style.display = value ? el._vod : 'none';
10949 }
10950
10951 const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps);
10952 // lazy create the renderer - this makes core renderer logic tree-shakable
10953 // in case the user only imports reactivity utilities from Vue.
10954 let renderer;
10955 let enabledHydration = false;
10956 function ensureRenderer() {
10957 return (renderer ||
10958 (renderer = createRenderer(rendererOptions)));
10959 }
10960 function ensureHydrationRenderer() {
10961 renderer = enabledHydration
10962 ? renderer
10963 : createHydrationRenderer(rendererOptions);
10964 enabledHydration = true;
10965 return renderer;
10966 }
10967 // use explicit type casts here to avoid import() calls in rolled-up d.ts
10968 const render = ((...args) => {
10969 ensureRenderer().render(...args);
10970 });
10971 const hydrate = ((...args) => {
10972 ensureHydrationRenderer().hydrate(...args);
10973 });
10974 const createApp = ((...args) => {
10975 const app = ensureRenderer().createApp(...args);
10976 {
10977 injectNativeTagCheck(app);
10978 injectCompilerOptionsCheck(app);
10979 }
10980 const { mount } = app;
10981 app.mount = (containerOrSelector) => {
10982 const container = normalizeContainer(containerOrSelector);
10983 if (!container)
10984 return;
10985 const component = app._component;
10986 if (!isFunction(component) && !component.render && !component.template) {
10987 // __UNSAFE__
10988 // Reason: potential execution of JS expressions in in-DOM template.
10989 // The user must make sure the in-DOM template is trusted. If it's
10990 // rendered by the server, the template should not contain any user data.
10991 component.template = container.innerHTML;
10992 }
10993 // clear content before mounting
10994 container.innerHTML = '';
10995 const proxy = mount(container, false, container instanceof SVGElement);
10996 if (container instanceof Element) {
10997 container.removeAttribute('v-cloak');
10998 container.setAttribute('data-v-app', '');
10999 }
11000 return proxy;
11001 };
11002 return app;
11003 });
11004 const createSSRApp = ((...args) => {
11005 const app = ensureHydrationRenderer().createApp(...args);
11006 {
11007 injectNativeTagCheck(app);
11008 injectCompilerOptionsCheck(app);
11009 }
11010 const { mount } = app;
11011 app.mount = (containerOrSelector) => {
11012 const container = normalizeContainer(containerOrSelector);
11013 if (container) {
11014 return mount(container, true, container instanceof SVGElement);
11015 }
11016 };
11017 return app;
11018 });
11019 function injectNativeTagCheck(app) {
11020 // Inject `isNativeTag`
11021 // this is used for component name validation (dev only)
11022 Object.defineProperty(app.config, 'isNativeTag', {
11023 value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
11024 writable: false
11025 });
11026 }
11027 // dev only
11028 function injectCompilerOptionsCheck(app) {
11029 if (isRuntimeOnly()) {
11030 const isCustomElement = app.config.isCustomElement;
11031 Object.defineProperty(app.config, 'isCustomElement', {
11032 get() {
11033 return isCustomElement;
11034 },
11035 set() {
11036 warn(`The \`isCustomElement\` config option is deprecated. Use ` +
11037 `\`compilerOptions.isCustomElement\` instead.`);
11038 }
11039 });
11040 const compilerOptions = app.config.compilerOptions;
11041 const msg = `The \`compilerOptions\` config option is only respected when using ` +
11042 `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
11043 `Since you are using the runtime-only build, \`compilerOptions\` ` +
11044 `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
11045 `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
11046 `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
11047 `- 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`;
11048 Object.defineProperty(app.config, 'compilerOptions', {
11049 get() {
11050 warn(msg);
11051 return compilerOptions;
11052 },
11053 set() {
11054 warn(msg);
11055 }
11056 });
11057 }
11058 }
11059 function normalizeContainer(container) {
11060 if (isString(container)) {
11061 const res = document.querySelector(container);
11062 if (!res) {
11063 warn(`Failed to mount app: mount target selector "${container}" returned null.`);
11064 }
11065 return res;
11066 }
11067 if (window.ShadowRoot &&
11068 container instanceof window.ShadowRoot &&
11069 container.mode === 'closed') {
11070 warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
11071 }
11072 return container;
11073 }
11074 /**
11075 * @internal
11076 */
11077 const initDirectivesForSSR = NOOP;
11078
11079 function initDev() {
11080 {
11081 /* istanbul ignore if */
11082 {
11083 console.info(`You are running a development build of Vue.\n` +
11084 `Make sure to use the production build (*.prod.js) when deploying for production.`);
11085 }
11086 initCustomFormatter();
11087 }
11088 }
11089
11090 function defaultOnError(error) {
11091 throw error;
11092 }
11093 function defaultOnWarn(msg) {
11094 console.warn(`[Vue warn] ${msg.message}`);
11095 }
11096 function createCompilerError(code, loc, messages, additionalMessage) {
11097 const msg = (messages || errorMessages)[code] + (additionalMessage || ``)
11098 ;
11099 const error = new SyntaxError(String(msg));
11100 error.code = code;
11101 error.loc = loc;
11102 return error;
11103 }
11104 const errorMessages = {
11105 // parse errors
11106 [0 /* ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
11107 [1 /* ErrorCodes.CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
11108 [2 /* ErrorCodes.DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
11109 [3 /* ErrorCodes.END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
11110 [4 /* ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
11111 [5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
11112 [6 /* ErrorCodes.EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
11113 [7 /* ErrorCodes.EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
11114 [8 /* ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
11115 [9 /* ErrorCodes.EOF_IN_TAG */]: 'Unexpected EOF in tag.',
11116 [10 /* ErrorCodes.INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
11117 [11 /* ErrorCodes.INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
11118 [12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '&lt;' to print '<'.",
11119 [13 /* ErrorCodes.MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
11120 [14 /* ErrorCodes.MISSING_END_TAG_NAME */]: 'End tag name was expected.',
11121 [15 /* ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
11122 [16 /* ErrorCodes.NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
11123 [17 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
11124 [18 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
11125 [19 /* ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
11126 [21 /* ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
11127 [20 /* ErrorCodes.UNEXPECTED_NULL_CHARACTER */]: `Unexpected null character.`,
11128 [22 /* ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
11129 // Vue-specific parse errors
11130 [23 /* ErrorCodes.X_INVALID_END_TAG */]: 'Invalid end tag.',
11131 [24 /* ErrorCodes.X_MISSING_END_TAG */]: 'Element is missing end tag.',
11132 [25 /* ErrorCodes.X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
11133 [27 /* ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
11134 'Note that dynamic directive argument cannot contain spaces.',
11135 [26 /* ErrorCodes.X_MISSING_DIRECTIVE_NAME */]: 'Legal directive name was expected.',
11136 // transform errors
11137 [28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
11138 [29 /* ErrorCodes.X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
11139 [30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
11140 [31 /* ErrorCodes.X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
11141 [32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
11142 [33 /* ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
11143 [34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
11144 [35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
11145 [36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
11146 [37 /* ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>. ` +
11147 `When there are multiple named slots, all slots should use <template> ` +
11148 `syntax to avoid scope ambiguity.`,
11149 [38 /* ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
11150 [39 /* ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
11151 `default slot. These children will be ignored.`,
11152 [40 /* ErrorCodes.X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
11153 [41 /* ErrorCodes.X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
11154 [42 /* ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
11155 [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.`,
11156 [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.`,
11157 [45 /* ErrorCodes.X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
11158 [46 /* ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
11159 // generic errors
11160 [47 /* ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
11161 [48 /* ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
11162 [49 /* ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
11163 [50 /* ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
11164 // just to fulfill types
11165 [51 /* ErrorCodes.__EXTEND_POINT__ */]: ``
11166 };
11167
11168 const FRAGMENT = Symbol(`Fragment` );
11169 const TELEPORT = Symbol(`Teleport` );
11170 const SUSPENSE = Symbol(`Suspense` );
11171 const KEEP_ALIVE = Symbol(`KeepAlive` );
11172 const BASE_TRANSITION = Symbol(`BaseTransition` );
11173 const OPEN_BLOCK = Symbol(`openBlock` );
11174 const CREATE_BLOCK = Symbol(`createBlock` );
11175 const CREATE_ELEMENT_BLOCK = Symbol(`createElementBlock` );
11176 const CREATE_VNODE = Symbol(`createVNode` );
11177 const CREATE_ELEMENT_VNODE = Symbol(`createElementVNode` );
11178 const CREATE_COMMENT = Symbol(`createCommentVNode` );
11179 const CREATE_TEXT = Symbol(`createTextVNode` );
11180 const CREATE_STATIC = Symbol(`createStaticVNode` );
11181 const RESOLVE_COMPONENT = Symbol(`resolveComponent` );
11182 const RESOLVE_DYNAMIC_COMPONENT = Symbol(`resolveDynamicComponent` );
11183 const RESOLVE_DIRECTIVE = Symbol(`resolveDirective` );
11184 const RESOLVE_FILTER = Symbol(`resolveFilter` );
11185 const WITH_DIRECTIVES = Symbol(`withDirectives` );
11186 const RENDER_LIST = Symbol(`renderList` );
11187 const RENDER_SLOT = Symbol(`renderSlot` );
11188 const CREATE_SLOTS = Symbol(`createSlots` );
11189 const TO_DISPLAY_STRING = Symbol(`toDisplayString` );
11190 const MERGE_PROPS = Symbol(`mergeProps` );
11191 const NORMALIZE_CLASS = Symbol(`normalizeClass` );
11192 const NORMALIZE_STYLE = Symbol(`normalizeStyle` );
11193 const NORMALIZE_PROPS = Symbol(`normalizeProps` );
11194 const GUARD_REACTIVE_PROPS = Symbol(`guardReactiveProps` );
11195 const TO_HANDLERS = Symbol(`toHandlers` );
11196 const CAMELIZE = Symbol(`camelize` );
11197 const CAPITALIZE = Symbol(`capitalize` );
11198 const TO_HANDLER_KEY = Symbol(`toHandlerKey` );
11199 const SET_BLOCK_TRACKING = Symbol(`setBlockTracking` );
11200 const PUSH_SCOPE_ID = Symbol(`pushScopeId` );
11201 const POP_SCOPE_ID = Symbol(`popScopeId` );
11202 const WITH_CTX = Symbol(`withCtx` );
11203 const UNREF = Symbol(`unref` );
11204 const IS_REF = Symbol(`isRef` );
11205 const WITH_MEMO = Symbol(`withMemo` );
11206 const IS_MEMO_SAME = Symbol(`isMemoSame` );
11207 // Name mapping for runtime helpers that need to be imported from 'vue' in
11208 // generated code. Make sure these are correctly exported in the runtime!
11209 const helperNameMap = {
11210 [FRAGMENT]: `Fragment`,
11211 [TELEPORT]: `Teleport`,
11212 [SUSPENSE]: `Suspense`,
11213 [KEEP_ALIVE]: `KeepAlive`,
11214 [BASE_TRANSITION]: `BaseTransition`,
11215 [OPEN_BLOCK]: `openBlock`,
11216 [CREATE_BLOCK]: `createBlock`,
11217 [CREATE_ELEMENT_BLOCK]: `createElementBlock`,
11218 [CREATE_VNODE]: `createVNode`,
11219 [CREATE_ELEMENT_VNODE]: `createElementVNode`,
11220 [CREATE_COMMENT]: `createCommentVNode`,
11221 [CREATE_TEXT]: `createTextVNode`,
11222 [CREATE_STATIC]: `createStaticVNode`,
11223 [RESOLVE_COMPONENT]: `resolveComponent`,
11224 [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
11225 [RESOLVE_DIRECTIVE]: `resolveDirective`,
11226 [RESOLVE_FILTER]: `resolveFilter`,
11227 [WITH_DIRECTIVES]: `withDirectives`,
11228 [RENDER_LIST]: `renderList`,
11229 [RENDER_SLOT]: `renderSlot`,
11230 [CREATE_SLOTS]: `createSlots`,
11231 [TO_DISPLAY_STRING]: `toDisplayString`,
11232 [MERGE_PROPS]: `mergeProps`,
11233 [NORMALIZE_CLASS]: `normalizeClass`,
11234 [NORMALIZE_STYLE]: `normalizeStyle`,
11235 [NORMALIZE_PROPS]: `normalizeProps`,
11236 [GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
11237 [TO_HANDLERS]: `toHandlers`,
11238 [CAMELIZE]: `camelize`,
11239 [CAPITALIZE]: `capitalize`,
11240 [TO_HANDLER_KEY]: `toHandlerKey`,
11241 [SET_BLOCK_TRACKING]: `setBlockTracking`,
11242 [PUSH_SCOPE_ID]: `pushScopeId`,
11243 [POP_SCOPE_ID]: `popScopeId`,
11244 [WITH_CTX]: `withCtx`,
11245 [UNREF]: `unref`,
11246 [IS_REF]: `isRef`,
11247 [WITH_MEMO]: `withMemo`,
11248 [IS_MEMO_SAME]: `isMemoSame`
11249 };
11250 function registerRuntimeHelpers(helpers) {
11251 Object.getOwnPropertySymbols(helpers).forEach(s => {
11252 helperNameMap[s] = helpers[s];
11253 });
11254 }
11255
11256 // AST Utilities ---------------------------------------------------------------
11257 // Some expressions, e.g. sequence and conditional expressions, are never
11258 // associated with template nodes, so their source locations are just a stub.
11259 // Container types like CompoundExpression also don't need a real location.
11260 const locStub = {
11261 source: '',
11262 start: { line: 1, column: 1, offset: 0 },
11263 end: { line: 1, column: 1, offset: 0 }
11264 };
11265 function createRoot(children, loc = locStub) {
11266 return {
11267 type: 0 /* NodeTypes.ROOT */,
11268 children,
11269 helpers: new Set(),
11270 components: [],
11271 directives: [],
11272 hoists: [],
11273 imports: [],
11274 cached: 0,
11275 temps: 0,
11276 codegenNode: undefined,
11277 loc
11278 };
11279 }
11280 function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
11281 if (context) {
11282 if (isBlock) {
11283 context.helper(OPEN_BLOCK);
11284 context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
11285 }
11286 else {
11287 context.helper(getVNodeHelper(context.inSSR, isComponent));
11288 }
11289 if (directives) {
11290 context.helper(WITH_DIRECTIVES);
11291 }
11292 }
11293 return {
11294 type: 13 /* NodeTypes.VNODE_CALL */,
11295 tag,
11296 props,
11297 children,
11298 patchFlag,
11299 dynamicProps,
11300 directives,
11301 isBlock,
11302 disableTracking,
11303 isComponent,
11304 loc
11305 };
11306 }
11307 function createArrayExpression(elements, loc = locStub) {
11308 return {
11309 type: 17 /* NodeTypes.JS_ARRAY_EXPRESSION */,
11310 loc,
11311 elements
11312 };
11313 }
11314 function createObjectExpression(properties, loc = locStub) {
11315 return {
11316 type: 15 /* NodeTypes.JS_OBJECT_EXPRESSION */,
11317 loc,
11318 properties
11319 };
11320 }
11321 function createObjectProperty(key, value) {
11322 return {
11323 type: 16 /* NodeTypes.JS_PROPERTY */,
11324 loc: locStub,
11325 key: isString(key) ? createSimpleExpression(key, true) : key,
11326 value
11327 };
11328 }
11329 function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* ConstantTypes.NOT_CONSTANT */) {
11330 return {
11331 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
11332 loc,
11333 content,
11334 isStatic,
11335 constType: isStatic ? 3 /* ConstantTypes.CAN_STRINGIFY */ : constType
11336 };
11337 }
11338 function createCompoundExpression(children, loc = locStub) {
11339 return {
11340 type: 8 /* NodeTypes.COMPOUND_EXPRESSION */,
11341 loc,
11342 children
11343 };
11344 }
11345 function createCallExpression(callee, args = [], loc = locStub) {
11346 return {
11347 type: 14 /* NodeTypes.JS_CALL_EXPRESSION */,
11348 loc,
11349 callee,
11350 arguments: args
11351 };
11352 }
11353 function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
11354 return {
11355 type: 18 /* NodeTypes.JS_FUNCTION_EXPRESSION */,
11356 params,
11357 returns,
11358 newline,
11359 isSlot,
11360 loc
11361 };
11362 }
11363 function createConditionalExpression(test, consequent, alternate, newline = true) {
11364 return {
11365 type: 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */,
11366 test,
11367 consequent,
11368 alternate,
11369 newline,
11370 loc: locStub
11371 };
11372 }
11373 function createCacheExpression(index, value, isVNode = false) {
11374 return {
11375 type: 20 /* NodeTypes.JS_CACHE_EXPRESSION */,
11376 index,
11377 value,
11378 isVNode,
11379 loc: locStub
11380 };
11381 }
11382 function createBlockStatement(body) {
11383 return {
11384 type: 21 /* NodeTypes.JS_BLOCK_STATEMENT */,
11385 body,
11386 loc: locStub
11387 };
11388 }
11389
11390 const isStaticExp = (p) => p.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && p.isStatic;
11391 const isBuiltInType = (tag, expected) => tag === expected || tag === hyphenate(expected);
11392 function isCoreComponent(tag) {
11393 if (isBuiltInType(tag, 'Teleport')) {
11394 return TELEPORT;
11395 }
11396 else if (isBuiltInType(tag, 'Suspense')) {
11397 return SUSPENSE;
11398 }
11399 else if (isBuiltInType(tag, 'KeepAlive')) {
11400 return KEEP_ALIVE;
11401 }
11402 else if (isBuiltInType(tag, 'BaseTransition')) {
11403 return BASE_TRANSITION;
11404 }
11405 }
11406 const nonIdentifierRE = /^\d|[^\$\w]/;
11407 const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
11408 const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
11409 const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
11410 const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
11411 /**
11412 * Simple lexer to check if an expression is a member expression. This is
11413 * lax and only checks validity at the root level (i.e. does not validate exps
11414 * inside square brackets), but it's ok since these are only used on template
11415 * expressions and false positives are invalid expressions in the first place.
11416 */
11417 const isMemberExpressionBrowser = (path) => {
11418 // remove whitespaces around . or [ first
11419 path = path.trim().replace(whitespaceRE, s => s.trim());
11420 let state = 0 /* MemberExpLexState.inMemberExp */;
11421 let stateStack = [];
11422 let currentOpenBracketCount = 0;
11423 let currentOpenParensCount = 0;
11424 let currentStringType = null;
11425 for (let i = 0; i < path.length; i++) {
11426 const char = path.charAt(i);
11427 switch (state) {
11428 case 0 /* MemberExpLexState.inMemberExp */:
11429 if (char === '[') {
11430 stateStack.push(state);
11431 state = 1 /* MemberExpLexState.inBrackets */;
11432 currentOpenBracketCount++;
11433 }
11434 else if (char === '(') {
11435 stateStack.push(state);
11436 state = 2 /* MemberExpLexState.inParens */;
11437 currentOpenParensCount++;
11438 }
11439 else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
11440 return false;
11441 }
11442 break;
11443 case 1 /* MemberExpLexState.inBrackets */:
11444 if (char === `'` || char === `"` || char === '`') {
11445 stateStack.push(state);
11446 state = 3 /* MemberExpLexState.inString */;
11447 currentStringType = char;
11448 }
11449 else if (char === `[`) {
11450 currentOpenBracketCount++;
11451 }
11452 else if (char === `]`) {
11453 if (!--currentOpenBracketCount) {
11454 state = stateStack.pop();
11455 }
11456 }
11457 break;
11458 case 2 /* MemberExpLexState.inParens */:
11459 if (char === `'` || char === `"` || char === '`') {
11460 stateStack.push(state);
11461 state = 3 /* MemberExpLexState.inString */;
11462 currentStringType = char;
11463 }
11464 else if (char === `(`) {
11465 currentOpenParensCount++;
11466 }
11467 else if (char === `)`) {
11468 // if the exp ends as a call then it should not be considered valid
11469 if (i === path.length - 1) {
11470 return false;
11471 }
11472 if (!--currentOpenParensCount) {
11473 state = stateStack.pop();
11474 }
11475 }
11476 break;
11477 case 3 /* MemberExpLexState.inString */:
11478 if (char === currentStringType) {
11479 state = stateStack.pop();
11480 currentStringType = null;
11481 }
11482 break;
11483 }
11484 }
11485 return !currentOpenBracketCount && !currentOpenParensCount;
11486 };
11487 const isMemberExpression = isMemberExpressionBrowser
11488 ;
11489 function getInnerRange(loc, offset, length) {
11490 const source = loc.source.slice(offset, offset + length);
11491 const newLoc = {
11492 source,
11493 start: advancePositionWithClone(loc.start, loc.source, offset),
11494 end: loc.end
11495 };
11496 if (length != null) {
11497 newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
11498 }
11499 return newLoc;
11500 }
11501 function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
11502 return advancePositionWithMutation(extend({}, pos), source, numberOfCharacters);
11503 }
11504 // advance by mutation without cloning (for performance reasons), since this
11505 // gets called a lot in the parser
11506 function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
11507 let linesCount = 0;
11508 let lastNewLinePos = -1;
11509 for (let i = 0; i < numberOfCharacters; i++) {
11510 if (source.charCodeAt(i) === 10 /* newline char code */) {
11511 linesCount++;
11512 lastNewLinePos = i;
11513 }
11514 }
11515 pos.offset += numberOfCharacters;
11516 pos.line += linesCount;
11517 pos.column =
11518 lastNewLinePos === -1
11519 ? pos.column + numberOfCharacters
11520 : numberOfCharacters - lastNewLinePos;
11521 return pos;
11522 }
11523 function assert(condition, msg) {
11524 /* istanbul ignore if */
11525 if (!condition) {
11526 throw new Error(msg || `unexpected compiler condition`);
11527 }
11528 }
11529 function findDir(node, name, allowEmpty = false) {
11530 for (let i = 0; i < node.props.length; i++) {
11531 const p = node.props[i];
11532 if (p.type === 7 /* NodeTypes.DIRECTIVE */ &&
11533 (allowEmpty || p.exp) &&
11534 (isString(name) ? p.name === name : name.test(p.name))) {
11535 return p;
11536 }
11537 }
11538 }
11539 function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11540 for (let i = 0; i < node.props.length; i++) {
11541 const p = node.props[i];
11542 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
11543 if (dynamicOnly)
11544 continue;
11545 if (p.name === name && (p.value || allowEmpty)) {
11546 return p;
11547 }
11548 }
11549 else if (p.name === 'bind' &&
11550 (p.exp || allowEmpty) &&
11551 isStaticArgOf(p.arg, name)) {
11552 return p;
11553 }
11554 }
11555 }
11556 function isStaticArgOf(arg, name) {
11557 return !!(arg && isStaticExp(arg) && arg.content === name);
11558 }
11559 function hasDynamicKeyVBind(node) {
11560 return node.props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ &&
11561 p.name === 'bind' &&
11562 (!p.arg || // v-bind="obj"
11563 p.arg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
11564 !p.arg.isStatic) // v-bind:[foo]
11565 );
11566 }
11567 function isText$1(node) {
11568 return node.type === 5 /* NodeTypes.INTERPOLATION */ || node.type === 2 /* NodeTypes.TEXT */;
11569 }
11570 function isVSlot(p) {
11571 return p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'slot';
11572 }
11573 function isTemplateNode(node) {
11574 return (node.type === 1 /* NodeTypes.ELEMENT */ && node.tagType === 3 /* ElementTypes.TEMPLATE */);
11575 }
11576 function isSlotOutlet(node) {
11577 return node.type === 1 /* NodeTypes.ELEMENT */ && node.tagType === 2 /* ElementTypes.SLOT */;
11578 }
11579 function getVNodeHelper(ssr, isComponent) {
11580 return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
11581 }
11582 function getVNodeBlockHelper(ssr, isComponent) {
11583 return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
11584 }
11585 const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
11586 function getUnnormalizedProps(props, callPath = []) {
11587 if (props &&
11588 !isString(props) &&
11589 props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
11590 const callee = props.callee;
11591 if (!isString(callee) && propsHelperSet.has(callee)) {
11592 return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
11593 }
11594 }
11595 return [props, callPath];
11596 }
11597 function injectProp(node, prop, context) {
11598 let propsWithInjection;
11599 /**
11600 * 1. mergeProps(...)
11601 * 2. toHandlers(...)
11602 * 3. normalizeProps(...)
11603 * 4. normalizeProps(guardReactiveProps(...))
11604 *
11605 * we need to get the real props before normalization
11606 */
11607 let props = node.type === 13 /* NodeTypes.VNODE_CALL */ ? node.props : node.arguments[2];
11608 let callPath = [];
11609 let parentCall;
11610 if (props &&
11611 !isString(props) &&
11612 props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
11613 const ret = getUnnormalizedProps(props);
11614 props = ret[0];
11615 callPath = ret[1];
11616 parentCall = callPath[callPath.length - 1];
11617 }
11618 if (props == null || isString(props)) {
11619 propsWithInjection = createObjectExpression([prop]);
11620 }
11621 else if (props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
11622 // merged props... add ours
11623 // only inject key to object literal if it's the first argument so that
11624 // if doesn't override user provided keys
11625 const first = props.arguments[0];
11626 if (!isString(first) && first.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) {
11627 // #6631
11628 if (!hasProp(prop, first)) {
11629 first.properties.unshift(prop);
11630 }
11631 }
11632 else {
11633 if (props.callee === TO_HANDLERS) {
11634 // #2366
11635 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11636 createObjectExpression([prop]),
11637 props
11638 ]);
11639 }
11640 else {
11641 props.arguments.unshift(createObjectExpression([prop]));
11642 }
11643 }
11644 !propsWithInjection && (propsWithInjection = props);
11645 }
11646 else if (props.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) {
11647 if (!hasProp(prop, props)) {
11648 props.properties.unshift(prop);
11649 }
11650 propsWithInjection = props;
11651 }
11652 else {
11653 // single v-bind with expression, return a merged replacement
11654 propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
11655 createObjectExpression([prop]),
11656 props
11657 ]);
11658 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
11659 // it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
11660 // the `guardReactiveProps` will no longer be needed
11661 if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
11662 parentCall = callPath[callPath.length - 2];
11663 }
11664 }
11665 if (node.type === 13 /* NodeTypes.VNODE_CALL */) {
11666 if (parentCall) {
11667 parentCall.arguments[0] = propsWithInjection;
11668 }
11669 else {
11670 node.props = propsWithInjection;
11671 }
11672 }
11673 else {
11674 if (parentCall) {
11675 parentCall.arguments[0] = propsWithInjection;
11676 }
11677 else {
11678 node.arguments[2] = propsWithInjection;
11679 }
11680 }
11681 }
11682 // check existing key to avoid overriding user provided keys
11683 function hasProp(prop, props) {
11684 let result = false;
11685 if (prop.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
11686 const propKeyName = prop.key.content;
11687 result = props.properties.some(p => p.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
11688 p.key.content === propKeyName);
11689 }
11690 return result;
11691 }
11692 function toValidAssetId(name, type) {
11693 // see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
11694 return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
11695 return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
11696 })}`;
11697 }
11698 function getMemoedVNodeCall(node) {
11699 if (node.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
11700 return node.arguments[1].returns;
11701 }
11702 else {
11703 return node;
11704 }
11705 }
11706 function makeBlock(node, { helper, removeHelper, inSSR }) {
11707 if (!node.isBlock) {
11708 node.isBlock = true;
11709 removeHelper(getVNodeHelper(inSSR, node.isComponent));
11710 helper(OPEN_BLOCK);
11711 helper(getVNodeBlockHelper(inSSR, node.isComponent));
11712 }
11713 }
11714
11715 const deprecationData = {
11716 ["COMPILER_IS_ON_ELEMENT" /* CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT */]: {
11717 message: `Platform-native elements with "is" prop will no longer be ` +
11718 `treated as components in Vue 3 unless the "is" value is explicitly ` +
11719 `prefixed with "vue:".`,
11720 link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
11721 },
11722 ["COMPILER_V_BIND_SYNC" /* CompilerDeprecationTypes.COMPILER_V_BIND_SYNC */]: {
11723 message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
11724 `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
11725 `\`v-model:${key}\`.`,
11726 link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
11727 },
11728 ["COMPILER_V_BIND_PROP" /* CompilerDeprecationTypes.COMPILER_V_BIND_PROP */]: {
11729 message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
11730 `Vue 3 will automatically set a binding as DOM property when appropriate.`
11731 },
11732 ["COMPILER_V_BIND_OBJECT_ORDER" /* CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER */]: {
11733 message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
11734 `object spread: it will now overwrite an existing non-mergeable attribute ` +
11735 `that appears before v-bind in the case of conflict. ` +
11736 `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
11737 `You can also suppress this warning if the usage is intended.`,
11738 link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
11739 },
11740 ["COMPILER_V_ON_NATIVE" /* CompilerDeprecationTypes.COMPILER_V_ON_NATIVE */]: {
11741 message: `.native modifier for v-on has been removed as is no longer necessary.`,
11742 link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
11743 },
11744 ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* CompilerDeprecationTypes.COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
11745 message: `v-if / v-for precedence when used on the same element has changed ` +
11746 `in Vue 3: v-if now takes higher precedence and will no longer have ` +
11747 `access to v-for scope variables. It is best to avoid the ambiguity ` +
11748 `with <template> tags or use a computed property that filters v-for ` +
11749 `data source.`,
11750 link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
11751 },
11752 ["COMPILER_NATIVE_TEMPLATE" /* CompilerDeprecationTypes.COMPILER_NATIVE_TEMPLATE */]: {
11753 message: `<template> with no special directives will render as a native template ` +
11754 `element instead of its inner content in Vue 3.`
11755 },
11756 ["COMPILER_INLINE_TEMPLATE" /* CompilerDeprecationTypes.COMPILER_INLINE_TEMPLATE */]: {
11757 message: `"inline-template" has been removed in Vue 3.`,
11758 link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
11759 },
11760 ["COMPILER_FILTER" /* CompilerDeprecationTypes.COMPILER_FILTERS */]: {
11761 message: `filters have been removed in Vue 3. ` +
11762 `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
11763 `Use method calls or computed properties instead.`,
11764 link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
11765 }
11766 };
11767 function getCompatValue(key, context) {
11768 const config = context.options
11769 ? context.options.compatConfig
11770 : context.compatConfig;
11771 const value = config && config[key];
11772 if (key === 'MODE') {
11773 return value || 3; // compiler defaults to v3 behavior
11774 }
11775 else {
11776 return value;
11777 }
11778 }
11779 function isCompatEnabled(key, context) {
11780 const mode = getCompatValue('MODE', context);
11781 const value = getCompatValue(key, context);
11782 // in v3 mode, only enable if explicitly set to true
11783 // otherwise enable for any non-false value
11784 return mode === 3 ? value === true : value !== false;
11785 }
11786 function checkCompatEnabled(key, context, loc, ...args) {
11787 const enabled = isCompatEnabled(key, context);
11788 if (enabled) {
11789 warnDeprecation(key, context, loc, ...args);
11790 }
11791 return enabled;
11792 }
11793 function warnDeprecation(key, context, loc, ...args) {
11794 const val = getCompatValue(key, context);
11795 if (val === 'suppress-warning') {
11796 return;
11797 }
11798 const { message, link } = deprecationData[key];
11799 const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
11800 const err = new SyntaxError(msg);
11801 err.code = key;
11802 if (loc)
11803 err.loc = loc;
11804 context.onWarn(err);
11805 }
11806
11807 // The default decoder only provides escapes for characters reserved as part of
11808 // the template syntax, and is only used if the custom renderer did not provide
11809 // a platform-specific decoder.
11810 const decodeRE = /&(gt|lt|amp|apos|quot);/g;
11811 const decodeMap = {
11812 gt: '>',
11813 lt: '<',
11814 amp: '&',
11815 apos: "'",
11816 quot: '"'
11817 };
11818 const defaultParserOptions = {
11819 delimiters: [`{{`, `}}`],
11820 getNamespace: () => 0 /* Namespaces.HTML */,
11821 getTextMode: () => 0 /* TextModes.DATA */,
11822 isVoidTag: NO,
11823 isPreTag: NO,
11824 isCustomElement: NO,
11825 decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
11826 onError: defaultOnError,
11827 onWarn: defaultOnWarn,
11828 comments: true
11829 };
11830 function baseParse(content, options = {}) {
11831 const context = createParserContext(content, options);
11832 const start = getCursor(context);
11833 return createRoot(parseChildren(context, 0 /* TextModes.DATA */, []), getSelection(context, start));
11834 }
11835 function createParserContext(content, rawOptions) {
11836 const options = extend({}, defaultParserOptions);
11837 let key;
11838 for (key in rawOptions) {
11839 // @ts-ignore
11840 options[key] =
11841 rawOptions[key] === undefined
11842 ? defaultParserOptions[key]
11843 : rawOptions[key];
11844 }
11845 return {
11846 options,
11847 column: 1,
11848 line: 1,
11849 offset: 0,
11850 originalSource: content,
11851 source: content,
11852 inPre: false,
11853 inVPre: false,
11854 onWarn: options.onWarn
11855 };
11856 }
11857 function parseChildren(context, mode, ancestors) {
11858 const parent = last(ancestors);
11859 const ns = parent ? parent.ns : 0 /* Namespaces.HTML */;
11860 const nodes = [];
11861 while (!isEnd(context, mode, ancestors)) {
11862 const s = context.source;
11863 let node = undefined;
11864 if (mode === 0 /* TextModes.DATA */ || mode === 1 /* TextModes.RCDATA */) {
11865 if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
11866 // '{{'
11867 node = parseInterpolation(context, mode);
11868 }
11869 else if (mode === 0 /* TextModes.DATA */ && s[0] === '<') {
11870 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
11871 if (s.length === 1) {
11872 emitError(context, 5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */, 1);
11873 }
11874 else if (s[1] === '!') {
11875 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
11876 if (startsWith(s, '<!--')) {
11877 node = parseComment(context);
11878 }
11879 else if (startsWith(s, '<!DOCTYPE')) {
11880 // Ignore DOCTYPE by a limitation.
11881 node = parseBogusComment(context);
11882 }
11883 else if (startsWith(s, '<![CDATA[')) {
11884 if (ns !== 0 /* Namespaces.HTML */) {
11885 node = parseCDATA(context, ancestors);
11886 }
11887 else {
11888 emitError(context, 1 /* ErrorCodes.CDATA_IN_HTML_CONTENT */);
11889 node = parseBogusComment(context);
11890 }
11891 }
11892 else {
11893 emitError(context, 11 /* ErrorCodes.INCORRECTLY_OPENED_COMMENT */);
11894 node = parseBogusComment(context);
11895 }
11896 }
11897 else if (s[1] === '/') {
11898 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
11899 if (s.length === 2) {
11900 emitError(context, 5 /* ErrorCodes.EOF_BEFORE_TAG_NAME */, 2);
11901 }
11902 else if (s[2] === '>') {
11903 emitError(context, 14 /* ErrorCodes.MISSING_END_TAG_NAME */, 2);
11904 advanceBy(context, 3);
11905 continue;
11906 }
11907 else if (/[a-z]/i.test(s[2])) {
11908 emitError(context, 23 /* ErrorCodes.X_INVALID_END_TAG */);
11909 parseTag(context, 1 /* TagType.End */, parent);
11910 continue;
11911 }
11912 else {
11913 emitError(context, 12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
11914 node = parseBogusComment(context);
11915 }
11916 }
11917 else if (/[a-z]/i.test(s[1])) {
11918 node = parseElement(context, ancestors);
11919 }
11920 else if (s[1] === '?') {
11921 emitError(context, 21 /* ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
11922 node = parseBogusComment(context);
11923 }
11924 else {
11925 emitError(context, 12 /* ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
11926 }
11927 }
11928 }
11929 if (!node) {
11930 node = parseText(context, mode);
11931 }
11932 if (isArray(node)) {
11933 for (let i = 0; i < node.length; i++) {
11934 pushNode(nodes, node[i]);
11935 }
11936 }
11937 else {
11938 pushNode(nodes, node);
11939 }
11940 }
11941 // Whitespace handling strategy like v2
11942 let removedWhitespace = false;
11943 if (mode !== 2 /* TextModes.RAWTEXT */ && mode !== 1 /* TextModes.RCDATA */) {
11944 const shouldCondense = context.options.whitespace !== 'preserve';
11945 for (let i = 0; i < nodes.length; i++) {
11946 const node = nodes[i];
11947 if (node.type === 2 /* NodeTypes.TEXT */) {
11948 if (!context.inPre) {
11949 if (!/[^\t\r\n\f ]/.test(node.content)) {
11950 const prev = nodes[i - 1];
11951 const next = nodes[i + 1];
11952 // Remove if:
11953 // - the whitespace is the first or last node, or:
11954 // - (condense mode) the whitespace is between twos comments, or:
11955 // - (condense mode) the whitespace is between comment and element, or:
11956 // - (condense mode) the whitespace is between two elements AND contains newline
11957 if (!prev ||
11958 !next ||
11959 (shouldCondense &&
11960 ((prev.type === 3 /* NodeTypes.COMMENT */ &&
11961 next.type === 3 /* NodeTypes.COMMENT */) ||
11962 (prev.type === 3 /* NodeTypes.COMMENT */ &&
11963 next.type === 1 /* NodeTypes.ELEMENT */) ||
11964 (prev.type === 1 /* NodeTypes.ELEMENT */ &&
11965 next.type === 3 /* NodeTypes.COMMENT */) ||
11966 (prev.type === 1 /* NodeTypes.ELEMENT */ &&
11967 next.type === 1 /* NodeTypes.ELEMENT */ &&
11968 /[\r\n]/.test(node.content))))) {
11969 removedWhitespace = true;
11970 nodes[i] = null;
11971 }
11972 else {
11973 // Otherwise, the whitespace is condensed into a single space
11974 node.content = ' ';
11975 }
11976 }
11977 else if (shouldCondense) {
11978 // in condense mode, consecutive whitespaces in text are condensed
11979 // down to a single space.
11980 node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11981 }
11982 }
11983 else {
11984 // #6410 normalize windows newlines in <pre>:
11985 // in SSR, browsers normalize server-rendered \r\n into a single \n
11986 // in the DOM
11987 node.content = node.content.replace(/\r\n/g, '\n');
11988 }
11989 }
11990 // Remove comment nodes if desired by configuration.
11991 else if (node.type === 3 /* NodeTypes.COMMENT */ && !context.options.comments) {
11992 removedWhitespace = true;
11993 nodes[i] = null;
11994 }
11995 }
11996 if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
11997 // remove leading newline per html spec
11998 // https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
11999 const first = nodes[0];
12000 if (first && first.type === 2 /* NodeTypes.TEXT */) {
12001 first.content = first.content.replace(/^\r?\n/, '');
12002 }
12003 }
12004 }
12005 return removedWhitespace ? nodes.filter(Boolean) : nodes;
12006 }
12007 function pushNode(nodes, node) {
12008 if (node.type === 2 /* NodeTypes.TEXT */) {
12009 const prev = last(nodes);
12010 // Merge if both this and the previous node are text and those are
12011 // consecutive. This happens for cases like "a < b".
12012 if (prev &&
12013 prev.type === 2 /* NodeTypes.TEXT */ &&
12014 prev.loc.end.offset === node.loc.start.offset) {
12015 prev.content += node.content;
12016 prev.loc.end = node.loc.end;
12017 prev.loc.source += node.loc.source;
12018 return;
12019 }
12020 }
12021 nodes.push(node);
12022 }
12023 function parseCDATA(context, ancestors) {
12024 advanceBy(context, 9);
12025 const nodes = parseChildren(context, 3 /* TextModes.CDATA */, ancestors);
12026 if (context.source.length === 0) {
12027 emitError(context, 6 /* ErrorCodes.EOF_IN_CDATA */);
12028 }
12029 else {
12030 advanceBy(context, 3);
12031 }
12032 return nodes;
12033 }
12034 function parseComment(context) {
12035 const start = getCursor(context);
12036 let content;
12037 // Regular comment.
12038 const match = /--(\!)?>/.exec(context.source);
12039 if (!match) {
12040 content = context.source.slice(4);
12041 advanceBy(context, context.source.length);
12042 emitError(context, 7 /* ErrorCodes.EOF_IN_COMMENT */);
12043 }
12044 else {
12045 if (match.index <= 3) {
12046 emitError(context, 0 /* ErrorCodes.ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
12047 }
12048 if (match[1]) {
12049 emitError(context, 10 /* ErrorCodes.INCORRECTLY_CLOSED_COMMENT */);
12050 }
12051 content = context.source.slice(4, match.index);
12052 // Advancing with reporting nested comments.
12053 const s = context.source.slice(0, match.index);
12054 let prevIndex = 1, nestedIndex = 0;
12055 while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
12056 advanceBy(context, nestedIndex - prevIndex + 1);
12057 if (nestedIndex + 4 < s.length) {
12058 emitError(context, 16 /* ErrorCodes.NESTED_COMMENT */);
12059 }
12060 prevIndex = nestedIndex + 1;
12061 }
12062 advanceBy(context, match.index + match[0].length - prevIndex + 1);
12063 }
12064 return {
12065 type: 3 /* NodeTypes.COMMENT */,
12066 content,
12067 loc: getSelection(context, start)
12068 };
12069 }
12070 function parseBogusComment(context) {
12071 const start = getCursor(context);
12072 const contentStart = context.source[1] === '?' ? 1 : 2;
12073 let content;
12074 const closeIndex = context.source.indexOf('>');
12075 if (closeIndex === -1) {
12076 content = context.source.slice(contentStart);
12077 advanceBy(context, context.source.length);
12078 }
12079 else {
12080 content = context.source.slice(contentStart, closeIndex);
12081 advanceBy(context, closeIndex + 1);
12082 }
12083 return {
12084 type: 3 /* NodeTypes.COMMENT */,
12085 content,
12086 loc: getSelection(context, start)
12087 };
12088 }
12089 function parseElement(context, ancestors) {
12090 // Start tag.
12091 const wasInPre = context.inPre;
12092 const wasInVPre = context.inVPre;
12093 const parent = last(ancestors);
12094 const element = parseTag(context, 0 /* TagType.Start */, parent);
12095 const isPreBoundary = context.inPre && !wasInPre;
12096 const isVPreBoundary = context.inVPre && !wasInVPre;
12097 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
12098 // #4030 self-closing <pre> tag
12099 if (isPreBoundary) {
12100 context.inPre = false;
12101 }
12102 if (isVPreBoundary) {
12103 context.inVPre = false;
12104 }
12105 return element;
12106 }
12107 // Children.
12108 ancestors.push(element);
12109 const mode = context.options.getTextMode(element, parent);
12110 const children = parseChildren(context, mode, ancestors);
12111 ancestors.pop();
12112 element.children = children;
12113 // End tag.
12114 if (startsWithEndTagOpen(context.source, element.tag)) {
12115 parseTag(context, 1 /* TagType.End */, parent);
12116 }
12117 else {
12118 emitError(context, 24 /* ErrorCodes.X_MISSING_END_TAG */, 0, element.loc.start);
12119 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
12120 const first = children[0];
12121 if (first && startsWith(first.loc.source, '<!--')) {
12122 emitError(context, 8 /* ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
12123 }
12124 }
12125 }
12126 element.loc = getSelection(context, element.loc.start);
12127 if (isPreBoundary) {
12128 context.inPre = false;
12129 }
12130 if (isVPreBoundary) {
12131 context.inVPre = false;
12132 }
12133 return element;
12134 }
12135 const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(`if,else,else-if,for,slot`);
12136 function parseTag(context, type, parent) {
12137 // Tag open.
12138 const start = getCursor(context);
12139 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
12140 const tag = match[1];
12141 const ns = context.options.getNamespace(tag, parent);
12142 advanceBy(context, match[0].length);
12143 advanceSpaces(context);
12144 // save current state in case we need to re-parse attributes with v-pre
12145 const cursor = getCursor(context);
12146 const currentSource = context.source;
12147 // check <pre> tag
12148 if (context.options.isPreTag(tag)) {
12149 context.inPre = true;
12150 }
12151 // Attributes.
12152 let props = parseAttributes(context, type);
12153 // check v-pre
12154 if (type === 0 /* TagType.Start */ &&
12155 !context.inVPre &&
12156 props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'pre')) {
12157 context.inVPre = true;
12158 // reset context
12159 extend(context, cursor);
12160 context.source = currentSource;
12161 // re-parse attrs and filter out v-pre itself
12162 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
12163 }
12164 // Tag close.
12165 let isSelfClosing = false;
12166 if (context.source.length === 0) {
12167 emitError(context, 9 /* ErrorCodes.EOF_IN_TAG */);
12168 }
12169 else {
12170 isSelfClosing = startsWith(context.source, '/>');
12171 if (type === 1 /* TagType.End */ && isSelfClosing) {
12172 emitError(context, 4 /* ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS */);
12173 }
12174 advanceBy(context, isSelfClosing ? 2 : 1);
12175 }
12176 if (type === 1 /* TagType.End */) {
12177 return;
12178 }
12179 let tagType = 0 /* ElementTypes.ELEMENT */;
12180 if (!context.inVPre) {
12181 if (tag === 'slot') {
12182 tagType = 2 /* ElementTypes.SLOT */;
12183 }
12184 else if (tag === 'template') {
12185 if (props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
12186 tagType = 3 /* ElementTypes.TEMPLATE */;
12187 }
12188 }
12189 else if (isComponent(tag, props, context)) {
12190 tagType = 1 /* ElementTypes.COMPONENT */;
12191 }
12192 }
12193 return {
12194 type: 1 /* NodeTypes.ELEMENT */,
12195 ns,
12196 tag,
12197 tagType,
12198 props,
12199 isSelfClosing,
12200 children: [],
12201 loc: getSelection(context, start),
12202 codegenNode: undefined // to be created during transform phase
12203 };
12204 }
12205 function isComponent(tag, props, context) {
12206 const options = context.options;
12207 if (options.isCustomElement(tag)) {
12208 return false;
12209 }
12210 if (tag === 'component' ||
12211 /^[A-Z]/.test(tag) ||
12212 isCoreComponent(tag) ||
12213 (options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
12214 (options.isNativeTag && !options.isNativeTag(tag))) {
12215 return true;
12216 }
12217 // at this point the tag should be a native tag, but check for potential "is"
12218 // casting
12219 for (let i = 0; i < props.length; i++) {
12220 const p = props[i];
12221 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
12222 if (p.name === 'is' && p.value) {
12223 if (p.value.content.startsWith('vue:')) {
12224 return true;
12225 }
12226 }
12227 }
12228 else {
12229 // directive
12230 // v-is (TODO Deprecate)
12231 if (p.name === 'is') {
12232 return true;
12233 }
12234 else if (
12235 // :is on plain element - only treat as component in compat mode
12236 p.name === 'bind' &&
12237 isStaticArgOf(p.arg, 'is') &&
12238 false &&
12239 checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
12240 return true;
12241 }
12242 }
12243 }
12244 }
12245 function parseAttributes(context, type) {
12246 const props = [];
12247 const attributeNames = new Set();
12248 while (context.source.length > 0 &&
12249 !startsWith(context.source, '>') &&
12250 !startsWith(context.source, '/>')) {
12251 if (startsWith(context.source, '/')) {
12252 emitError(context, 22 /* ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG */);
12253 advanceBy(context, 1);
12254 advanceSpaces(context);
12255 continue;
12256 }
12257 if (type === 1 /* TagType.End */) {
12258 emitError(context, 3 /* ErrorCodes.END_TAG_WITH_ATTRIBUTES */);
12259 }
12260 const attr = parseAttribute(context, attributeNames);
12261 // Trim whitespace between class
12262 // https://github.com/vuejs/core/issues/4251
12263 if (attr.type === 6 /* NodeTypes.ATTRIBUTE */ &&
12264 attr.value &&
12265 attr.name === 'class') {
12266 attr.value.content = attr.value.content.replace(/\s+/g, ' ').trim();
12267 }
12268 if (type === 0 /* TagType.Start */) {
12269 props.push(attr);
12270 }
12271 if (/^[^\t\r\n\f />]/.test(context.source)) {
12272 emitError(context, 15 /* ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
12273 }
12274 advanceSpaces(context);
12275 }
12276 return props;
12277 }
12278 function parseAttribute(context, nameSet) {
12279 // Name.
12280 const start = getCursor(context);
12281 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
12282 const name = match[0];
12283 if (nameSet.has(name)) {
12284 emitError(context, 2 /* ErrorCodes.DUPLICATE_ATTRIBUTE */);
12285 }
12286 nameSet.add(name);
12287 if (name[0] === '=') {
12288 emitError(context, 19 /* ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
12289 }
12290 {
12291 const pattern = /["'<]/g;
12292 let m;
12293 while ((m = pattern.exec(name))) {
12294 emitError(context, 17 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
12295 }
12296 }
12297 advanceBy(context, name.length);
12298 // Value
12299 let value = undefined;
12300 if (/^[\t\r\n\f ]*=/.test(context.source)) {
12301 advanceSpaces(context);
12302 advanceBy(context, 1);
12303 advanceSpaces(context);
12304 value = parseAttributeValue(context);
12305 if (!value) {
12306 emitError(context, 13 /* ErrorCodes.MISSING_ATTRIBUTE_VALUE */);
12307 }
12308 }
12309 const loc = getSelection(context, start);
12310 if (!context.inVPre && /^(v-[A-Za-z0-9-]|:|\.|@|#)/.test(name)) {
12311 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
12312 let isPropShorthand = startsWith(name, '.');
12313 let dirName = match[1] ||
12314 (isPropShorthand || startsWith(name, ':')
12315 ? 'bind'
12316 : startsWith(name, '@')
12317 ? 'on'
12318 : 'slot');
12319 let arg;
12320 if (match[2]) {
12321 const isSlot = dirName === 'slot';
12322 const startOffset = name.lastIndexOf(match[2]);
12323 const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
12324 let content = match[2];
12325 let isStatic = true;
12326 if (content.startsWith('[')) {
12327 isStatic = false;
12328 if (!content.endsWith(']')) {
12329 emitError(context, 27 /* ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
12330 content = content.slice(1);
12331 }
12332 else {
12333 content = content.slice(1, content.length - 1);
12334 }
12335 }
12336 else if (isSlot) {
12337 // #1241 special case for v-slot: vuetify relies extensively on slot
12338 // names containing dots. v-slot doesn't have any modifiers and Vue 2.x
12339 // supports such usage so we are keeping it consistent with 2.x.
12340 content += match[3] || '';
12341 }
12342 arg = {
12343 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
12344 content,
12345 isStatic,
12346 constType: isStatic
12347 ? 3 /* ConstantTypes.CAN_STRINGIFY */
12348 : 0 /* ConstantTypes.NOT_CONSTANT */,
12349 loc
12350 };
12351 }
12352 if (value && value.isQuoted) {
12353 const valueLoc = value.loc;
12354 valueLoc.start.offset++;
12355 valueLoc.start.column++;
12356 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
12357 valueLoc.source = valueLoc.source.slice(1, -1);
12358 }
12359 const modifiers = match[3] ? match[3].slice(1).split('.') : [];
12360 if (isPropShorthand)
12361 modifiers.push('prop');
12362 return {
12363 type: 7 /* NodeTypes.DIRECTIVE */,
12364 name: dirName,
12365 exp: value && {
12366 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
12367 content: value.content,
12368 isStatic: false,
12369 // Treat as non-constant by default. This can be potentially set to
12370 // other values by `transformExpression` to make it eligible for hoisting.
12371 constType: 0 /* ConstantTypes.NOT_CONSTANT */,
12372 loc: value.loc
12373 },
12374 arg,
12375 modifiers,
12376 loc
12377 };
12378 }
12379 // missing directive name or illegal directive name
12380 if (!context.inVPre && startsWith(name, 'v-')) {
12381 emitError(context, 26 /* ErrorCodes.X_MISSING_DIRECTIVE_NAME */);
12382 }
12383 return {
12384 type: 6 /* NodeTypes.ATTRIBUTE */,
12385 name,
12386 value: value && {
12387 type: 2 /* NodeTypes.TEXT */,
12388 content: value.content,
12389 loc: value.loc
12390 },
12391 loc
12392 };
12393 }
12394 function parseAttributeValue(context) {
12395 const start = getCursor(context);
12396 let content;
12397 const quote = context.source[0];
12398 const isQuoted = quote === `"` || quote === `'`;
12399 if (isQuoted) {
12400 // Quoted value.
12401 advanceBy(context, 1);
12402 const endIndex = context.source.indexOf(quote);
12403 if (endIndex === -1) {
12404 content = parseTextData(context, context.source.length, 4 /* TextModes.ATTRIBUTE_VALUE */);
12405 }
12406 else {
12407 content = parseTextData(context, endIndex, 4 /* TextModes.ATTRIBUTE_VALUE */);
12408 advanceBy(context, 1);
12409 }
12410 }
12411 else {
12412 // Unquoted
12413 const match = /^[^\t\r\n\f >]+/.exec(context.source);
12414 if (!match) {
12415 return undefined;
12416 }
12417 const unexpectedChars = /["'<=`]/g;
12418 let m;
12419 while ((m = unexpectedChars.exec(match[0]))) {
12420 emitError(context, 18 /* ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
12421 }
12422 content = parseTextData(context, match[0].length, 4 /* TextModes.ATTRIBUTE_VALUE */);
12423 }
12424 return { content, isQuoted, loc: getSelection(context, start) };
12425 }
12426 function parseInterpolation(context, mode) {
12427 const [open, close] = context.options.delimiters;
12428 const closeIndex = context.source.indexOf(close, open.length);
12429 if (closeIndex === -1) {
12430 emitError(context, 25 /* ErrorCodes.X_MISSING_INTERPOLATION_END */);
12431 return undefined;
12432 }
12433 const start = getCursor(context);
12434 advanceBy(context, open.length);
12435 const innerStart = getCursor(context);
12436 const innerEnd = getCursor(context);
12437 const rawContentLength = closeIndex - open.length;
12438 const rawContent = context.source.slice(0, rawContentLength);
12439 const preTrimContent = parseTextData(context, rawContentLength, mode);
12440 const content = preTrimContent.trim();
12441 const startOffset = preTrimContent.indexOf(content);
12442 if (startOffset > 0) {
12443 advancePositionWithMutation(innerStart, rawContent, startOffset);
12444 }
12445 const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
12446 advancePositionWithMutation(innerEnd, rawContent, endOffset);
12447 advanceBy(context, close.length);
12448 return {
12449 type: 5 /* NodeTypes.INTERPOLATION */,
12450 content: {
12451 type: 4 /* NodeTypes.SIMPLE_EXPRESSION */,
12452 isStatic: false,
12453 // Set `isConstant` to false by default and will decide in transformExpression
12454 constType: 0 /* ConstantTypes.NOT_CONSTANT */,
12455 content,
12456 loc: getSelection(context, innerStart, innerEnd)
12457 },
12458 loc: getSelection(context, start)
12459 };
12460 }
12461 function parseText(context, mode) {
12462 const endTokens = mode === 3 /* TextModes.CDATA */ ? [']]>'] : ['<', context.options.delimiters[0]];
12463 let endIndex = context.source.length;
12464 for (let i = 0; i < endTokens.length; i++) {
12465 const index = context.source.indexOf(endTokens[i], 1);
12466 if (index !== -1 && endIndex > index) {
12467 endIndex = index;
12468 }
12469 }
12470 const start = getCursor(context);
12471 const content = parseTextData(context, endIndex, mode);
12472 return {
12473 type: 2 /* NodeTypes.TEXT */,
12474 content,
12475 loc: getSelection(context, start)
12476 };
12477 }
12478 /**
12479 * Get text data with a given length from the current location.
12480 * This translates HTML entities in the text data.
12481 */
12482 function parseTextData(context, length, mode) {
12483 const rawText = context.source.slice(0, length);
12484 advanceBy(context, length);
12485 if (mode === 2 /* TextModes.RAWTEXT */ ||
12486 mode === 3 /* TextModes.CDATA */ ||
12487 !rawText.includes('&')) {
12488 return rawText;
12489 }
12490 else {
12491 // DATA or RCDATA containing "&"". Entity decoding required.
12492 return context.options.decodeEntities(rawText, mode === 4 /* TextModes.ATTRIBUTE_VALUE */);
12493 }
12494 }
12495 function getCursor(context) {
12496 const { column, line, offset } = context;
12497 return { column, line, offset };
12498 }
12499 function getSelection(context, start, end) {
12500 end = end || getCursor(context);
12501 return {
12502 start,
12503 end,
12504 source: context.originalSource.slice(start.offset, end.offset)
12505 };
12506 }
12507 function last(xs) {
12508 return xs[xs.length - 1];
12509 }
12510 function startsWith(source, searchString) {
12511 return source.startsWith(searchString);
12512 }
12513 function advanceBy(context, numberOfCharacters) {
12514 const { source } = context;
12515 advancePositionWithMutation(context, source, numberOfCharacters);
12516 context.source = source.slice(numberOfCharacters);
12517 }
12518 function advanceSpaces(context) {
12519 const match = /^[\t\r\n\f ]+/.exec(context.source);
12520 if (match) {
12521 advanceBy(context, match[0].length);
12522 }
12523 }
12524 function getNewPosition(context, start, numberOfCharacters) {
12525 return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
12526 }
12527 function emitError(context, code, offset, loc = getCursor(context)) {
12528 if (offset) {
12529 loc.offset += offset;
12530 loc.column += offset;
12531 }
12532 context.options.onError(createCompilerError(code, {
12533 start: loc,
12534 end: loc,
12535 source: ''
12536 }));
12537 }
12538 function isEnd(context, mode, ancestors) {
12539 const s = context.source;
12540 switch (mode) {
12541 case 0 /* TextModes.DATA */:
12542 if (startsWith(s, '</')) {
12543 // TODO: probably bad performance
12544 for (let i = ancestors.length - 1; i >= 0; --i) {
12545 if (startsWithEndTagOpen(s, ancestors[i].tag)) {
12546 return true;
12547 }
12548 }
12549 }
12550 break;
12551 case 1 /* TextModes.RCDATA */:
12552 case 2 /* TextModes.RAWTEXT */: {
12553 const parent = last(ancestors);
12554 if (parent && startsWithEndTagOpen(s, parent.tag)) {
12555 return true;
12556 }
12557 break;
12558 }
12559 case 3 /* TextModes.CDATA */:
12560 if (startsWith(s, ']]>')) {
12561 return true;
12562 }
12563 break;
12564 }
12565 return !s;
12566 }
12567 function startsWithEndTagOpen(source, tag) {
12568 return (startsWith(source, '</') &&
12569 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase() &&
12570 /[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
12571 }
12572
12573 function hoistStatic(root, context) {
12574 walk(root, context,
12575 // Root node is unfortunately non-hoistable due to potential parent
12576 // fallthrough attributes.
12577 isSingleElementRoot(root, root.children[0]));
12578 }
12579 function isSingleElementRoot(root, child) {
12580 const { children } = root;
12581 return (children.length === 1 &&
12582 child.type === 1 /* NodeTypes.ELEMENT */ &&
12583 !isSlotOutlet(child));
12584 }
12585 function walk(node, context, doNotHoistNode = false) {
12586 const { children } = node;
12587 const originalCount = children.length;
12588 let hoistedCount = 0;
12589 for (let i = 0; i < children.length; i++) {
12590 const child = children[i];
12591 // only plain elements & text calls are eligible for hoisting.
12592 if (child.type === 1 /* NodeTypes.ELEMENT */ &&
12593 child.tagType === 0 /* ElementTypes.ELEMENT */) {
12594 const constantType = doNotHoistNode
12595 ? 0 /* ConstantTypes.NOT_CONSTANT */
12596 : getConstantType(child, context);
12597 if (constantType > 0 /* ConstantTypes.NOT_CONSTANT */) {
12598 if (constantType >= 2 /* ConstantTypes.CAN_HOIST */) {
12599 child.codegenNode.patchFlag =
12600 -1 /* PatchFlags.HOISTED */ + (` /* HOISTED */` );
12601 child.codegenNode = context.hoist(child.codegenNode);
12602 hoistedCount++;
12603 continue;
12604 }
12605 }
12606 else {
12607 // node may contain dynamic children, but its props may be eligible for
12608 // hoisting.
12609 const codegenNode = child.codegenNode;
12610 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
12611 const flag = getPatchFlag(codegenNode);
12612 if ((!flag ||
12613 flag === 512 /* PatchFlags.NEED_PATCH */ ||
12614 flag === 1 /* PatchFlags.TEXT */) &&
12615 getGeneratedPropsConstantType(child, context) >=
12616 2 /* ConstantTypes.CAN_HOIST */) {
12617 const props = getNodeProps(child);
12618 if (props) {
12619 codegenNode.props = context.hoist(props);
12620 }
12621 }
12622 if (codegenNode.dynamicProps) {
12623 codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
12624 }
12625 }
12626 }
12627 }
12628 // walk further
12629 if (child.type === 1 /* NodeTypes.ELEMENT */) {
12630 const isComponent = child.tagType === 1 /* ElementTypes.COMPONENT */;
12631 if (isComponent) {
12632 context.scopes.vSlot++;
12633 }
12634 walk(child, context);
12635 if (isComponent) {
12636 context.scopes.vSlot--;
12637 }
12638 }
12639 else if (child.type === 11 /* NodeTypes.FOR */) {
12640 // Do not hoist v-for single child because it has to be a block
12641 walk(child, context, child.children.length === 1);
12642 }
12643 else if (child.type === 9 /* NodeTypes.IF */) {
12644 for (let i = 0; i < child.branches.length; i++) {
12645 // Do not hoist v-if single child because it has to be a block
12646 walk(child.branches[i], context, child.branches[i].children.length === 1);
12647 }
12648 }
12649 }
12650 if (hoistedCount && context.transformHoist) {
12651 context.transformHoist(children, context, node);
12652 }
12653 // all children were hoisted - the entire children array is hoistable.
12654 if (hoistedCount &&
12655 hoistedCount === originalCount &&
12656 node.type === 1 /* NodeTypes.ELEMENT */ &&
12657 node.tagType === 0 /* ElementTypes.ELEMENT */ &&
12658 node.codegenNode &&
12659 node.codegenNode.type === 13 /* NodeTypes.VNODE_CALL */ &&
12660 isArray(node.codegenNode.children)) {
12661 node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
12662 }
12663 }
12664 function getConstantType(node, context) {
12665 const { constantCache } = context;
12666 switch (node.type) {
12667 case 1 /* NodeTypes.ELEMENT */:
12668 if (node.tagType !== 0 /* ElementTypes.ELEMENT */) {
12669 return 0 /* ConstantTypes.NOT_CONSTANT */;
12670 }
12671 const cached = constantCache.get(node);
12672 if (cached !== undefined) {
12673 return cached;
12674 }
12675 const codegenNode = node.codegenNode;
12676 if (codegenNode.type !== 13 /* NodeTypes.VNODE_CALL */) {
12677 return 0 /* ConstantTypes.NOT_CONSTANT */;
12678 }
12679 if (codegenNode.isBlock &&
12680 node.tag !== 'svg' &&
12681 node.tag !== 'foreignObject') {
12682 return 0 /* ConstantTypes.NOT_CONSTANT */;
12683 }
12684 const flag = getPatchFlag(codegenNode);
12685 if (!flag) {
12686 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */;
12687 // Element itself has no patch flag. However we still need to check:
12688 // 1. Even for a node with no patch flag, it is possible for it to contain
12689 // non-hoistable expressions that refers to scope variables, e.g. compiler
12690 // injected keys or cached event handlers. Therefore we need to always
12691 // check the codegenNode's props to be sure.
12692 const generatedPropsType = getGeneratedPropsConstantType(node, context);
12693 if (generatedPropsType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12694 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12695 return 0 /* ConstantTypes.NOT_CONSTANT */;
12696 }
12697 if (generatedPropsType < returnType) {
12698 returnType = generatedPropsType;
12699 }
12700 // 2. its children.
12701 for (let i = 0; i < node.children.length; i++) {
12702 const childType = getConstantType(node.children[i], context);
12703 if (childType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12704 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12705 return 0 /* ConstantTypes.NOT_CONSTANT */;
12706 }
12707 if (childType < returnType) {
12708 returnType = childType;
12709 }
12710 }
12711 // 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
12712 // type, check if any of the props can cause the type to be lowered
12713 // we can skip can_patch because it's guaranteed by the absence of a
12714 // patchFlag.
12715 if (returnType > 1 /* ConstantTypes.CAN_SKIP_PATCH */) {
12716 for (let i = 0; i < node.props.length; i++) {
12717 const p = node.props[i];
12718 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'bind' && p.exp) {
12719 const expType = getConstantType(p.exp, context);
12720 if (expType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12721 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12722 return 0 /* ConstantTypes.NOT_CONSTANT */;
12723 }
12724 if (expType < returnType) {
12725 returnType = expType;
12726 }
12727 }
12728 }
12729 }
12730 // only svg/foreignObject could be block here, however if they are
12731 // static then they don't need to be blocks since there will be no
12732 // nested updates.
12733 if (codegenNode.isBlock) {
12734 // except set custom directives.
12735 for (let i = 0; i < node.props.length; i++) {
12736 const p = node.props[i];
12737 if (p.type === 7 /* NodeTypes.DIRECTIVE */) {
12738 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12739 return 0 /* ConstantTypes.NOT_CONSTANT */;
12740 }
12741 }
12742 context.removeHelper(OPEN_BLOCK);
12743 context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
12744 codegenNode.isBlock = false;
12745 context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
12746 }
12747 constantCache.set(node, returnType);
12748 return returnType;
12749 }
12750 else {
12751 constantCache.set(node, 0 /* ConstantTypes.NOT_CONSTANT */);
12752 return 0 /* ConstantTypes.NOT_CONSTANT */;
12753 }
12754 case 2 /* NodeTypes.TEXT */:
12755 case 3 /* NodeTypes.COMMENT */:
12756 return 3 /* ConstantTypes.CAN_STRINGIFY */;
12757 case 9 /* NodeTypes.IF */:
12758 case 11 /* NodeTypes.FOR */:
12759 case 10 /* NodeTypes.IF_BRANCH */:
12760 return 0 /* ConstantTypes.NOT_CONSTANT */;
12761 case 5 /* NodeTypes.INTERPOLATION */:
12762 case 12 /* NodeTypes.TEXT_CALL */:
12763 return getConstantType(node.content, context);
12764 case 4 /* NodeTypes.SIMPLE_EXPRESSION */:
12765 return node.constType;
12766 case 8 /* NodeTypes.COMPOUND_EXPRESSION */:
12767 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */;
12768 for (let i = 0; i < node.children.length; i++) {
12769 const child = node.children[i];
12770 if (isString(child) || isSymbol(child)) {
12771 continue;
12772 }
12773 const childType = getConstantType(child, context);
12774 if (childType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12775 return 0 /* ConstantTypes.NOT_CONSTANT */;
12776 }
12777 else if (childType < returnType) {
12778 returnType = childType;
12779 }
12780 }
12781 return returnType;
12782 default:
12783 return 0 /* ConstantTypes.NOT_CONSTANT */;
12784 }
12785 }
12786 const allowHoistedHelperSet = new Set([
12787 NORMALIZE_CLASS,
12788 NORMALIZE_STYLE,
12789 NORMALIZE_PROPS,
12790 GUARD_REACTIVE_PROPS
12791 ]);
12792 function getConstantTypeOfHelperCall(value, context) {
12793 if (value.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */ &&
12794 !isString(value.callee) &&
12795 allowHoistedHelperSet.has(value.callee)) {
12796 const arg = value.arguments[0];
12797 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
12798 return getConstantType(arg, context);
12799 }
12800 else if (arg.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
12801 // in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
12802 return getConstantTypeOfHelperCall(arg, context);
12803 }
12804 }
12805 return 0 /* ConstantTypes.NOT_CONSTANT */;
12806 }
12807 function getGeneratedPropsConstantType(node, context) {
12808 let returnType = 3 /* ConstantTypes.CAN_STRINGIFY */;
12809 const props = getNodeProps(node);
12810 if (props && props.type === 15 /* NodeTypes.JS_OBJECT_EXPRESSION */) {
12811 const { properties } = props;
12812 for (let i = 0; i < properties.length; i++) {
12813 const { key, value } = properties[i];
12814 const keyType = getConstantType(key, context);
12815 if (keyType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12816 return keyType;
12817 }
12818 if (keyType < returnType) {
12819 returnType = keyType;
12820 }
12821 let valueType;
12822 if (value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
12823 valueType = getConstantType(value, context);
12824 }
12825 else if (value.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
12826 // some helper calls can be hoisted,
12827 // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12828 // in this case we need to respect the ConstantType of the helper's arguments
12829 valueType = getConstantTypeOfHelperCall(value, context);
12830 }
12831 else {
12832 valueType = 0 /* ConstantTypes.NOT_CONSTANT */;
12833 }
12834 if (valueType === 0 /* ConstantTypes.NOT_CONSTANT */) {
12835 return valueType;
12836 }
12837 if (valueType < returnType) {
12838 returnType = valueType;
12839 }
12840 }
12841 }
12842 return returnType;
12843 }
12844 function getNodeProps(node) {
12845 const codegenNode = node.codegenNode;
12846 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
12847 return codegenNode.props;
12848 }
12849 }
12850 function getPatchFlag(node) {
12851 const flag = node.patchFlag;
12852 return flag ? parseInt(flag, 10) : undefined;
12853 }
12854
12855 function 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 }) {
12856 const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
12857 const context = {
12858 // options
12859 selfName: nameMatch && capitalize(camelize(nameMatch[1])),
12860 prefixIdentifiers,
12861 hoistStatic,
12862 cacheHandlers,
12863 nodeTransforms,
12864 directiveTransforms,
12865 transformHoist,
12866 isBuiltInComponent,
12867 isCustomElement,
12868 expressionPlugins,
12869 scopeId,
12870 slotted,
12871 ssr,
12872 inSSR,
12873 ssrCssVars,
12874 bindingMetadata,
12875 inline,
12876 isTS,
12877 onError,
12878 onWarn,
12879 compatConfig,
12880 // state
12881 root,
12882 helpers: new Map(),
12883 components: new Set(),
12884 directives: new Set(),
12885 hoists: [],
12886 imports: [],
12887 constantCache: new Map(),
12888 temps: 0,
12889 cached: 0,
12890 identifiers: Object.create(null),
12891 scopes: {
12892 vFor: 0,
12893 vSlot: 0,
12894 vPre: 0,
12895 vOnce: 0
12896 },
12897 parent: null,
12898 currentNode: root,
12899 childIndex: 0,
12900 inVOnce: false,
12901 // methods
12902 helper(name) {
12903 const count = context.helpers.get(name) || 0;
12904 context.helpers.set(name, count + 1);
12905 return name;
12906 },
12907 removeHelper(name) {
12908 const count = context.helpers.get(name);
12909 if (count) {
12910 const currentCount = count - 1;
12911 if (!currentCount) {
12912 context.helpers.delete(name);
12913 }
12914 else {
12915 context.helpers.set(name, currentCount);
12916 }
12917 }
12918 },
12919 helperString(name) {
12920 return `_${helperNameMap[context.helper(name)]}`;
12921 },
12922 replaceNode(node) {
12923 /* istanbul ignore if */
12924 {
12925 if (!context.currentNode) {
12926 throw new Error(`Node being replaced is already removed.`);
12927 }
12928 if (!context.parent) {
12929 throw new Error(`Cannot replace root node.`);
12930 }
12931 }
12932 context.parent.children[context.childIndex] = context.currentNode = node;
12933 },
12934 removeNode(node) {
12935 if (!context.parent) {
12936 throw new Error(`Cannot remove root node.`);
12937 }
12938 const list = context.parent.children;
12939 const removalIndex = node
12940 ? list.indexOf(node)
12941 : context.currentNode
12942 ? context.childIndex
12943 : -1;
12944 /* istanbul ignore if */
12945 if (removalIndex < 0) {
12946 throw new Error(`node being removed is not a child of current parent`);
12947 }
12948 if (!node || node === context.currentNode) {
12949 // current node removed
12950 context.currentNode = null;
12951 context.onNodeRemoved();
12952 }
12953 else {
12954 // sibling node removed
12955 if (context.childIndex > removalIndex) {
12956 context.childIndex--;
12957 context.onNodeRemoved();
12958 }
12959 }
12960 context.parent.children.splice(removalIndex, 1);
12961 },
12962 onNodeRemoved: () => { },
12963 addIdentifiers(exp) {
12964 },
12965 removeIdentifiers(exp) {
12966 },
12967 hoist(exp) {
12968 if (isString(exp))
12969 exp = createSimpleExpression(exp);
12970 context.hoists.push(exp);
12971 const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* ConstantTypes.CAN_HOIST */);
12972 identifier.hoisted = exp;
12973 return identifier;
12974 },
12975 cache(exp, isVNode = false) {
12976 return createCacheExpression(context.cached++, exp, isVNode);
12977 }
12978 };
12979 return context;
12980 }
12981 function transform(root, options) {
12982 const context = createTransformContext(root, options);
12983 traverseNode(root, context);
12984 if (options.hoistStatic) {
12985 hoistStatic(root, context);
12986 }
12987 if (!options.ssr) {
12988 createRootCodegen(root, context);
12989 }
12990 // finalize meta information
12991 root.helpers = new Set([...context.helpers.keys()]);
12992 root.components = [...context.components];
12993 root.directives = [...context.directives];
12994 root.imports = context.imports;
12995 root.hoists = context.hoists;
12996 root.temps = context.temps;
12997 root.cached = context.cached;
12998 }
12999 function createRootCodegen(root, context) {
13000 const { helper } = context;
13001 const { children } = root;
13002 if (children.length === 1) {
13003 const child = children[0];
13004 // if the single child is an element, turn it into a block.
13005 if (isSingleElementRoot(root, child) && child.codegenNode) {
13006 // single element root is never hoisted so codegenNode will never be
13007 // SimpleExpressionNode
13008 const codegenNode = child.codegenNode;
13009 if (codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
13010 makeBlock(codegenNode, context);
13011 }
13012 root.codegenNode = codegenNode;
13013 }
13014 else {
13015 // - single <slot/>, IfNode, ForNode: already blocks.
13016 // - single text node: always patched.
13017 // root codegen falls through via genNode()
13018 root.codegenNode = child;
13019 }
13020 }
13021 else if (children.length > 1) {
13022 // root has multiple nodes - return a fragment block.
13023 let patchFlag = 64 /* PatchFlags.STABLE_FRAGMENT */;
13024 let patchFlagText = PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */];
13025 // check if the fragment actually contains a single valid child with
13026 // the rest being comments
13027 if (children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */).length === 1) {
13028 patchFlag |= 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */;
13029 patchFlagText += `, ${PatchFlagNames[2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]}`;
13030 }
13031 root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, undefined, false /* isComponent */);
13032 }
13033 else ;
13034 }
13035 function traverseChildren(parent, context) {
13036 let i = 0;
13037 const nodeRemoved = () => {
13038 i--;
13039 };
13040 for (; i < parent.children.length; i++) {
13041 const child = parent.children[i];
13042 if (isString(child))
13043 continue;
13044 context.parent = parent;
13045 context.childIndex = i;
13046 context.onNodeRemoved = nodeRemoved;
13047 traverseNode(child, context);
13048 }
13049 }
13050 function traverseNode(node, context) {
13051 context.currentNode = node;
13052 // apply transform plugins
13053 const { nodeTransforms } = context;
13054 const exitFns = [];
13055 for (let i = 0; i < nodeTransforms.length; i++) {
13056 const onExit = nodeTransforms[i](node, context);
13057 if (onExit) {
13058 if (isArray(onExit)) {
13059 exitFns.push(...onExit);
13060 }
13061 else {
13062 exitFns.push(onExit);
13063 }
13064 }
13065 if (!context.currentNode) {
13066 // node was removed
13067 return;
13068 }
13069 else {
13070 // node may have been replaced
13071 node = context.currentNode;
13072 }
13073 }
13074 switch (node.type) {
13075 case 3 /* NodeTypes.COMMENT */:
13076 if (!context.ssr) {
13077 // inject import for the Comment symbol, which is needed for creating
13078 // comment nodes with `createVNode`
13079 context.helper(CREATE_COMMENT);
13080 }
13081 break;
13082 case 5 /* NodeTypes.INTERPOLATION */:
13083 // no need to traverse, but we need to inject toString helper
13084 if (!context.ssr) {
13085 context.helper(TO_DISPLAY_STRING);
13086 }
13087 break;
13088 // for container types, further traverse downwards
13089 case 9 /* NodeTypes.IF */:
13090 for (let i = 0; i < node.branches.length; i++) {
13091 traverseNode(node.branches[i], context);
13092 }
13093 break;
13094 case 10 /* NodeTypes.IF_BRANCH */:
13095 case 11 /* NodeTypes.FOR */:
13096 case 1 /* NodeTypes.ELEMENT */:
13097 case 0 /* NodeTypes.ROOT */:
13098 traverseChildren(node, context);
13099 break;
13100 }
13101 // exit transforms
13102 context.currentNode = node;
13103 let i = exitFns.length;
13104 while (i--) {
13105 exitFns[i]();
13106 }
13107 }
13108 function createStructuralDirectiveTransform(name, fn) {
13109 const matches = isString(name)
13110 ? (n) => n === name
13111 : (n) => name.test(n);
13112 return (node, context) => {
13113 if (node.type === 1 /* NodeTypes.ELEMENT */) {
13114 const { props } = node;
13115 // structural directive transforms are not concerned with slots
13116 // as they are handled separately in vSlot.ts
13117 if (node.tagType === 3 /* ElementTypes.TEMPLATE */ && props.some(isVSlot)) {
13118 return;
13119 }
13120 const exitFns = [];
13121 for (let i = 0; i < props.length; i++) {
13122 const prop = props[i];
13123 if (prop.type === 7 /* NodeTypes.DIRECTIVE */ && matches(prop.name)) {
13124 // structural directives are removed to avoid infinite recursion
13125 // also we remove them *before* applying so that it can further
13126 // traverse itself in case it moves the node around
13127 props.splice(i, 1);
13128 i--;
13129 const onExit = fn(node, prop, context);
13130 if (onExit)
13131 exitFns.push(onExit);
13132 }
13133 }
13134 return exitFns;
13135 }
13136 };
13137 }
13138
13139 const PURE_ANNOTATION = `/*#__PURE__*/`;
13140 const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
13141 function 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 }) {
13142 const context = {
13143 mode,
13144 prefixIdentifiers,
13145 sourceMap,
13146 filename,
13147 scopeId,
13148 optimizeImports,
13149 runtimeGlobalName,
13150 runtimeModuleName,
13151 ssrRuntimeModuleName,
13152 ssr,
13153 isTS,
13154 inSSR,
13155 source: ast.loc.source,
13156 code: ``,
13157 column: 1,
13158 line: 1,
13159 offset: 0,
13160 indentLevel: 0,
13161 pure: false,
13162 map: undefined,
13163 helper(key) {
13164 return `_${helperNameMap[key]}`;
13165 },
13166 push(code, node) {
13167 context.code += code;
13168 },
13169 indent() {
13170 newline(++context.indentLevel);
13171 },
13172 deindent(withoutNewLine = false) {
13173 if (withoutNewLine) {
13174 --context.indentLevel;
13175 }
13176 else {
13177 newline(--context.indentLevel);
13178 }
13179 },
13180 newline() {
13181 newline(context.indentLevel);
13182 }
13183 };
13184 function newline(n) {
13185 context.push('\n' + ` `.repeat(n));
13186 }
13187 return context;
13188 }
13189 function generate(ast, options = {}) {
13190 const context = createCodegenContext(ast, options);
13191 if (options.onContextCreated)
13192 options.onContextCreated(context);
13193 const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
13194 const helpers = Array.from(ast.helpers);
13195 const hasHelpers = helpers.length > 0;
13196 const useWithBlock = !prefixIdentifiers && mode !== 'module';
13197 const isSetupInlined = !true ;
13198 // preambles
13199 // in setup() inline mode, the preamble is generated in a sub context
13200 // and returned separately.
13201 const preambleContext = isSetupInlined
13202 ? createCodegenContext(ast, options)
13203 : context;
13204 {
13205 genFunctionPreamble(ast, preambleContext);
13206 }
13207 // enter render function
13208 const functionName = ssr ? `ssrRender` : `render`;
13209 const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
13210 const signature = args.join(', ');
13211 {
13212 push(`function ${functionName}(${signature}) {`);
13213 }
13214 indent();
13215 if (useWithBlock) {
13216 push(`with (_ctx) {`);
13217 indent();
13218 // function mode const declarations should be inside with block
13219 // also they should be renamed to avoid collision with user properties
13220 if (hasHelpers) {
13221 push(`const { ${helpers.map(aliasHelper).join(', ')} } = _Vue`);
13222 push(`\n`);
13223 newline();
13224 }
13225 }
13226 // generate asset resolution statements
13227 if (ast.components.length) {
13228 genAssets(ast.components, 'component', context);
13229 if (ast.directives.length || ast.temps > 0) {
13230 newline();
13231 }
13232 }
13233 if (ast.directives.length) {
13234 genAssets(ast.directives, 'directive', context);
13235 if (ast.temps > 0) {
13236 newline();
13237 }
13238 }
13239 if (ast.temps > 0) {
13240 push(`let `);
13241 for (let i = 0; i < ast.temps; i++) {
13242 push(`${i > 0 ? `, ` : ``}_temp${i}`);
13243 }
13244 }
13245 if (ast.components.length || ast.directives.length || ast.temps) {
13246 push(`\n`);
13247 newline();
13248 }
13249 // generate the VNode tree expression
13250 if (!ssr) {
13251 push(`return `);
13252 }
13253 if (ast.codegenNode) {
13254 genNode(ast.codegenNode, context);
13255 }
13256 else {
13257 push(`null`);
13258 }
13259 if (useWithBlock) {
13260 deindent();
13261 push(`}`);
13262 }
13263 deindent();
13264 push(`}`);
13265 return {
13266 ast,
13267 code: context.code,
13268 preamble: isSetupInlined ? preambleContext.code : ``,
13269 // SourceMapGenerator does have toJSON() method but it's not in the types
13270 map: context.map ? context.map.toJSON() : undefined
13271 };
13272 }
13273 function genFunctionPreamble(ast, context) {
13274 const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName, ssrRuntimeModuleName } = context;
13275 const VueBinding = runtimeGlobalName;
13276 // Generate const declaration for helpers
13277 // In prefix mode, we place the const declaration at top so it's done
13278 // only once; But if we not prefixing, we place the declaration inside the
13279 // with block so it doesn't incur the `in` check cost for every helper access.
13280 const helpers = Array.from(ast.helpers);
13281 if (helpers.length > 0) {
13282 {
13283 // "with" mode.
13284 // save Vue in a separate variable to avoid collision
13285 push(`const _Vue = ${VueBinding}\n`);
13286 // in "with" mode, helpers are declared inside the with block to avoid
13287 // has check cost, but hoists are lifted out of the function - we need
13288 // to provide the helper here.
13289 if (ast.hoists.length) {
13290 const staticHelpers = [
13291 CREATE_VNODE,
13292 CREATE_ELEMENT_VNODE,
13293 CREATE_COMMENT,
13294 CREATE_TEXT,
13295 CREATE_STATIC
13296 ]
13297 .filter(helper => helpers.includes(helper))
13298 .map(aliasHelper)
13299 .join(', ');
13300 push(`const { ${staticHelpers} } = _Vue\n`);
13301 }
13302 }
13303 }
13304 genHoists(ast.hoists, context);
13305 newline();
13306 push(`return `);
13307 }
13308 function genAssets(assets, type, { helper, push, newline, isTS }) {
13309 const resolver = helper(type === 'component'
13310 ? RESOLVE_COMPONENT
13311 : RESOLVE_DIRECTIVE);
13312 for (let i = 0; i < assets.length; i++) {
13313 let id = assets[i];
13314 // potential component implicit self-reference inferred from SFC filename
13315 const maybeSelfReference = id.endsWith('__self');
13316 if (maybeSelfReference) {
13317 id = id.slice(0, -6);
13318 }
13319 push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
13320 if (i < assets.length - 1) {
13321 newline();
13322 }
13323 }
13324 }
13325 function genHoists(hoists, context) {
13326 if (!hoists.length) {
13327 return;
13328 }
13329 context.pure = true;
13330 const { push, newline, helper, scopeId, mode } = context;
13331 newline();
13332 for (let i = 0; i < hoists.length; i++) {
13333 const exp = hoists[i];
13334 if (exp) {
13335 push(`const _hoisted_${i + 1} = ${``}`);
13336 genNode(exp, context);
13337 newline();
13338 }
13339 }
13340 context.pure = false;
13341 }
13342 function isText(n) {
13343 return (isString(n) ||
13344 n.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
13345 n.type === 2 /* NodeTypes.TEXT */ ||
13346 n.type === 5 /* NodeTypes.INTERPOLATION */ ||
13347 n.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */);
13348 }
13349 function genNodeListAsArray(nodes, context) {
13350 const multilines = nodes.length > 3 ||
13351 (nodes.some(n => isArray(n) || !isText(n)));
13352 context.push(`[`);
13353 multilines && context.indent();
13354 genNodeList(nodes, context, multilines);
13355 multilines && context.deindent();
13356 context.push(`]`);
13357 }
13358 function genNodeList(nodes, context, multilines = false, comma = true) {
13359 const { push, newline } = context;
13360 for (let i = 0; i < nodes.length; i++) {
13361 const node = nodes[i];
13362 if (isString(node)) {
13363 push(node);
13364 }
13365 else if (isArray(node)) {
13366 genNodeListAsArray(node, context);
13367 }
13368 else {
13369 genNode(node, context);
13370 }
13371 if (i < nodes.length - 1) {
13372 if (multilines) {
13373 comma && push(',');
13374 newline();
13375 }
13376 else {
13377 comma && push(', ');
13378 }
13379 }
13380 }
13381 }
13382 function genNode(node, context) {
13383 if (isString(node)) {
13384 context.push(node);
13385 return;
13386 }
13387 if (isSymbol(node)) {
13388 context.push(context.helper(node));
13389 return;
13390 }
13391 switch (node.type) {
13392 case 1 /* NodeTypes.ELEMENT */:
13393 case 9 /* NodeTypes.IF */:
13394 case 11 /* NodeTypes.FOR */:
13395 assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
13396 `Apply appropriate transforms first.`);
13397 genNode(node.codegenNode, context);
13398 break;
13399 case 2 /* NodeTypes.TEXT */:
13400 genText(node, context);
13401 break;
13402 case 4 /* NodeTypes.SIMPLE_EXPRESSION */:
13403 genExpression(node, context);
13404 break;
13405 case 5 /* NodeTypes.INTERPOLATION */:
13406 genInterpolation(node, context);
13407 break;
13408 case 12 /* NodeTypes.TEXT_CALL */:
13409 genNode(node.codegenNode, context);
13410 break;
13411 case 8 /* NodeTypes.COMPOUND_EXPRESSION */:
13412 genCompoundExpression(node, context);
13413 break;
13414 case 3 /* NodeTypes.COMMENT */:
13415 genComment(node, context);
13416 break;
13417 case 13 /* NodeTypes.VNODE_CALL */:
13418 genVNodeCall(node, context);
13419 break;
13420 case 14 /* NodeTypes.JS_CALL_EXPRESSION */:
13421 genCallExpression(node, context);
13422 break;
13423 case 15 /* NodeTypes.JS_OBJECT_EXPRESSION */:
13424 genObjectExpression(node, context);
13425 break;
13426 case 17 /* NodeTypes.JS_ARRAY_EXPRESSION */:
13427 genArrayExpression(node, context);
13428 break;
13429 case 18 /* NodeTypes.JS_FUNCTION_EXPRESSION */:
13430 genFunctionExpression(node, context);
13431 break;
13432 case 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */:
13433 genConditionalExpression(node, context);
13434 break;
13435 case 20 /* NodeTypes.JS_CACHE_EXPRESSION */:
13436 genCacheExpression(node, context);
13437 break;
13438 case 21 /* NodeTypes.JS_BLOCK_STATEMENT */:
13439 genNodeList(node.body, context, true, false);
13440 break;
13441 // SSR only types
13442 case 22 /* NodeTypes.JS_TEMPLATE_LITERAL */:
13443 break;
13444 case 23 /* NodeTypes.JS_IF_STATEMENT */:
13445 break;
13446 case 24 /* NodeTypes.JS_ASSIGNMENT_EXPRESSION */:
13447 break;
13448 case 25 /* NodeTypes.JS_SEQUENCE_EXPRESSION */:
13449 break;
13450 case 26 /* NodeTypes.JS_RETURN_STATEMENT */:
13451 break;
13452 /* istanbul ignore next */
13453 case 10 /* NodeTypes.IF_BRANCH */:
13454 // noop
13455 break;
13456 default:
13457 {
13458 assert(false, `unhandled codegen node type: ${node.type}`);
13459 // make sure we exhaust all possible types
13460 const exhaustiveCheck = node;
13461 return exhaustiveCheck;
13462 }
13463 }
13464 }
13465 function genText(node, context) {
13466 context.push(JSON.stringify(node.content), node);
13467 }
13468 function genExpression(node, context) {
13469 const { content, isStatic } = node;
13470 context.push(isStatic ? JSON.stringify(content) : content, node);
13471 }
13472 function genInterpolation(node, context) {
13473 const { push, helper, pure } = context;
13474 if (pure)
13475 push(PURE_ANNOTATION);
13476 push(`${helper(TO_DISPLAY_STRING)}(`);
13477 genNode(node.content, context);
13478 push(`)`);
13479 }
13480 function genCompoundExpression(node, context) {
13481 for (let i = 0; i < node.children.length; i++) {
13482 const child = node.children[i];
13483 if (isString(child)) {
13484 context.push(child);
13485 }
13486 else {
13487 genNode(child, context);
13488 }
13489 }
13490 }
13491 function genExpressionAsPropertyKey(node, context) {
13492 const { push } = context;
13493 if (node.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
13494 push(`[`);
13495 genCompoundExpression(node, context);
13496 push(`]`);
13497 }
13498 else if (node.isStatic) {
13499 // only quote keys if necessary
13500 const text = isSimpleIdentifier(node.content)
13501 ? node.content
13502 : JSON.stringify(node.content);
13503 push(text, node);
13504 }
13505 else {
13506 push(`[${node.content}]`, node);
13507 }
13508 }
13509 function genComment(node, context) {
13510 const { push, helper, pure } = context;
13511 if (pure) {
13512 push(PURE_ANNOTATION);
13513 }
13514 push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
13515 }
13516 function genVNodeCall(node, context) {
13517 const { push, helper, pure } = context;
13518 const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
13519 if (directives) {
13520 push(helper(WITH_DIRECTIVES) + `(`);
13521 }
13522 if (isBlock) {
13523 push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
13524 }
13525 if (pure) {
13526 push(PURE_ANNOTATION);
13527 }
13528 const callHelper = isBlock
13529 ? getVNodeBlockHelper(context.inSSR, isComponent)
13530 : getVNodeHelper(context.inSSR, isComponent);
13531 push(helper(callHelper) + `(`, node);
13532 genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
13533 push(`)`);
13534 if (isBlock) {
13535 push(`)`);
13536 }
13537 if (directives) {
13538 push(`, `);
13539 genNode(directives, context);
13540 push(`)`);
13541 }
13542 }
13543 function genNullableArgs(args) {
13544 let i = args.length;
13545 while (i--) {
13546 if (args[i] != null)
13547 break;
13548 }
13549 return args.slice(0, i + 1).map(arg => arg || `null`);
13550 }
13551 // JavaScript
13552 function genCallExpression(node, context) {
13553 const { push, helper, pure } = context;
13554 const callee = isString(node.callee) ? node.callee : helper(node.callee);
13555 if (pure) {
13556 push(PURE_ANNOTATION);
13557 }
13558 push(callee + `(`, node);
13559 genNodeList(node.arguments, context);
13560 push(`)`);
13561 }
13562 function genObjectExpression(node, context) {
13563 const { push, indent, deindent, newline } = context;
13564 const { properties } = node;
13565 if (!properties.length) {
13566 push(`{}`, node);
13567 return;
13568 }
13569 const multilines = properties.length > 1 ||
13570 (properties.some(p => p.value.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */));
13571 push(multilines ? `{` : `{ `);
13572 multilines && indent();
13573 for (let i = 0; i < properties.length; i++) {
13574 const { key, value } = properties[i];
13575 // key
13576 genExpressionAsPropertyKey(key, context);
13577 push(`: `);
13578 // value
13579 genNode(value, context);
13580 if (i < properties.length - 1) {
13581 // will only reach this if it's multilines
13582 push(`,`);
13583 newline();
13584 }
13585 }
13586 multilines && deindent();
13587 push(multilines ? `}` : ` }`);
13588 }
13589 function genArrayExpression(node, context) {
13590 genNodeListAsArray(node.elements, context);
13591 }
13592 function genFunctionExpression(node, context) {
13593 const { push, indent, deindent } = context;
13594 const { params, returns, body, newline, isSlot } = node;
13595 if (isSlot) {
13596 // wrap slot functions with owner context
13597 push(`_${helperNameMap[WITH_CTX]}(`);
13598 }
13599 push(`(`, node);
13600 if (isArray(params)) {
13601 genNodeList(params, context);
13602 }
13603 else if (params) {
13604 genNode(params, context);
13605 }
13606 push(`) => `);
13607 if (newline || body) {
13608 push(`{`);
13609 indent();
13610 }
13611 if (returns) {
13612 if (newline) {
13613 push(`return `);
13614 }
13615 if (isArray(returns)) {
13616 genNodeListAsArray(returns, context);
13617 }
13618 else {
13619 genNode(returns, context);
13620 }
13621 }
13622 else if (body) {
13623 genNode(body, context);
13624 }
13625 if (newline || body) {
13626 deindent();
13627 push(`}`);
13628 }
13629 if (isSlot) {
13630 push(`)`);
13631 }
13632 }
13633 function genConditionalExpression(node, context) {
13634 const { test, consequent, alternate, newline: needNewline } = node;
13635 const { push, indent, deindent, newline } = context;
13636 if (test.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
13637 const needsParens = !isSimpleIdentifier(test.content);
13638 needsParens && push(`(`);
13639 genExpression(test, context);
13640 needsParens && push(`)`);
13641 }
13642 else {
13643 push(`(`);
13644 genNode(test, context);
13645 push(`)`);
13646 }
13647 needNewline && indent();
13648 context.indentLevel++;
13649 needNewline || push(` `);
13650 push(`? `);
13651 genNode(consequent, context);
13652 context.indentLevel--;
13653 needNewline && newline();
13654 needNewline || push(` `);
13655 push(`: `);
13656 const isNested = alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */;
13657 if (!isNested) {
13658 context.indentLevel++;
13659 }
13660 genNode(alternate, context);
13661 if (!isNested) {
13662 context.indentLevel--;
13663 }
13664 needNewline && deindent(true /* without newline */);
13665 }
13666 function genCacheExpression(node, context) {
13667 const { push, helper, indent, deindent, newline } = context;
13668 push(`_cache[${node.index}] || (`);
13669 if (node.isVNode) {
13670 indent();
13671 push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
13672 newline();
13673 }
13674 push(`_cache[${node.index}] = `);
13675 genNode(node.value, context);
13676 if (node.isVNode) {
13677 push(`,`);
13678 newline();
13679 push(`${helper(SET_BLOCK_TRACKING)}(1),`);
13680 newline();
13681 push(`_cache[${node.index}]`);
13682 deindent();
13683 }
13684 push(`)`);
13685 }
13686
13687 // these keywords should not appear inside expressions, but operators like
13688 // 'typeof', 'instanceof', and 'in' are allowed
13689 const prohibitedKeywordRE = new RegExp('\\b' +
13690 ('arguments,await,break,case,catch,class,const,continue,debugger,default,' +
13691 'delete,do,else,export,extends,finally,for,function,if,import,let,new,' +
13692 'return,super,switch,throw,try,var,void,while,with,yield')
13693 .split(',')
13694 .join('\\b|\\b') +
13695 '\\b');
13696 // strip strings in expressions
13697 const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
13698 /**
13699 * Validate a non-prefixed expression.
13700 * This is only called when using the in-browser runtime compiler since it
13701 * doesn't prefix expressions.
13702 */
13703 function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
13704 const exp = node.content;
13705 // empty expressions are validated per-directive since some directives
13706 // do allow empty expressions.
13707 if (!exp.trim()) {
13708 return;
13709 }
13710 try {
13711 new Function(asRawStatements
13712 ? ` ${exp} `
13713 : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
13714 }
13715 catch (e) {
13716 let message = e.message;
13717 const keywordMatch = exp
13718 .replace(stripStringRE, '')
13719 .match(prohibitedKeywordRE);
13720 if (keywordMatch) {
13721 message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
13722 }
13723 context.onError(createCompilerError(45 /* ErrorCodes.X_INVALID_EXPRESSION */, node.loc, undefined, message));
13724 }
13725 }
13726
13727 const transformExpression = (node, context) => {
13728 if (node.type === 5 /* NodeTypes.INTERPOLATION */) {
13729 node.content = processExpression(node.content, context);
13730 }
13731 else if (node.type === 1 /* NodeTypes.ELEMENT */) {
13732 // handle directives on element
13733 for (let i = 0; i < node.props.length; i++) {
13734 const dir = node.props[i];
13735 // do not process for v-on & v-for since they are special handled
13736 if (dir.type === 7 /* NodeTypes.DIRECTIVE */ && dir.name !== 'for') {
13737 const exp = dir.exp;
13738 const arg = dir.arg;
13739 // do not process exp if this is v-on:arg - we need special handling
13740 // for wrapping inline statements.
13741 if (exp &&
13742 exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
13743 !(dir.name === 'on' && arg)) {
13744 dir.exp = processExpression(exp, context,
13745 // slot args must be processed as function params
13746 dir.name === 'slot');
13747 }
13748 if (arg && arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && !arg.isStatic) {
13749 dir.arg = processExpression(arg, context);
13750 }
13751 }
13752 }
13753 }
13754 };
13755 // Important: since this function uses Node.js only dependencies, it should
13756 // always be used with a leading !true check so that it can be
13757 // tree-shaken from the browser build.
13758 function processExpression(node, context,
13759 // some expressions like v-slot props & v-for aliases should be parsed as
13760 // function params
13761 asParams = false,
13762 // v-on handler values may contain multiple statements
13763 asRawStatements = false, localVars = Object.create(context.identifiers)) {
13764 {
13765 {
13766 // simple in-browser validation (same logic in 2.x)
13767 validateBrowserExpression(node, context, asParams, asRawStatements);
13768 }
13769 return node;
13770 }
13771 }
13772
13773 const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
13774 return processIf(node, dir, context, (ifNode, branch, isRoot) => {
13775 // #1587: We need to dynamically increment the key based on the current
13776 // node's sibling nodes, since chained v-if/else branches are
13777 // rendered at the same depth
13778 const siblings = context.parent.children;
13779 let i = siblings.indexOf(ifNode);
13780 let key = 0;
13781 while (i-- >= 0) {
13782 const sibling = siblings[i];
13783 if (sibling && sibling.type === 9 /* NodeTypes.IF */) {
13784 key += sibling.branches.length;
13785 }
13786 }
13787 // Exit callback. Complete the codegenNode when all children have been
13788 // transformed.
13789 return () => {
13790 if (isRoot) {
13791 ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
13792 }
13793 else {
13794 // attach this branch's codegen node to the v-if root.
13795 const parentCondition = getParentCondition(ifNode.codegenNode);
13796 parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
13797 }
13798 };
13799 });
13800 });
13801 // target-agnostic transform used for both Client and SSR
13802 function processIf(node, dir, context, processCodegen) {
13803 if (dir.name !== 'else' &&
13804 (!dir.exp || !dir.exp.content.trim())) {
13805 const loc = dir.exp ? dir.exp.loc : node.loc;
13806 context.onError(createCompilerError(28 /* ErrorCodes.X_V_IF_NO_EXPRESSION */, dir.loc));
13807 dir.exp = createSimpleExpression(`true`, false, loc);
13808 }
13809 if (dir.exp) {
13810 validateBrowserExpression(dir.exp, context);
13811 }
13812 if (dir.name === 'if') {
13813 const branch = createIfBranch(node, dir);
13814 const ifNode = {
13815 type: 9 /* NodeTypes.IF */,
13816 loc: node.loc,
13817 branches: [branch]
13818 };
13819 context.replaceNode(ifNode);
13820 if (processCodegen) {
13821 return processCodegen(ifNode, branch, true);
13822 }
13823 }
13824 else {
13825 // locate the adjacent v-if
13826 const siblings = context.parent.children;
13827 const comments = [];
13828 let i = siblings.indexOf(node);
13829 while (i-- >= -1) {
13830 const sibling = siblings[i];
13831 if (sibling && sibling.type === 3 /* NodeTypes.COMMENT */) {
13832 context.removeNode(sibling);
13833 comments.unshift(sibling);
13834 continue;
13835 }
13836 if (sibling &&
13837 sibling.type === 2 /* NodeTypes.TEXT */ &&
13838 !sibling.content.trim().length) {
13839 context.removeNode(sibling);
13840 continue;
13841 }
13842 if (sibling && sibling.type === 9 /* NodeTypes.IF */) {
13843 // Check if v-else was followed by v-else-if
13844 if (dir.name === 'else-if' &&
13845 sibling.branches[sibling.branches.length - 1].condition === undefined) {
13846 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13847 }
13848 // move the node to the if node's branches
13849 context.removeNode();
13850 const branch = createIfBranch(node, dir);
13851 if (comments.length &&
13852 // #3619 ignore comments if the v-if is direct child of <transition>
13853 !(context.parent &&
13854 context.parent.type === 1 /* NodeTypes.ELEMENT */ &&
13855 isBuiltInType(context.parent.tag, 'transition'))) {
13856 branch.children = [...comments, ...branch.children];
13857 }
13858 // check if user is forcing same key on different branches
13859 {
13860 const key = branch.userKey;
13861 if (key) {
13862 sibling.branches.forEach(({ userKey }) => {
13863 if (isSameKey(userKey, key)) {
13864 context.onError(createCompilerError(29 /* ErrorCodes.X_V_IF_SAME_KEY */, branch.userKey.loc));
13865 }
13866 });
13867 }
13868 }
13869 sibling.branches.push(branch);
13870 const onExit = processCodegen && processCodegen(sibling, branch, false);
13871 // since the branch was removed, it will not be traversed.
13872 // make sure to traverse here.
13873 traverseNode(branch, context);
13874 // call on exit
13875 if (onExit)
13876 onExit();
13877 // make sure to reset currentNode after traversal to indicate this
13878 // node has been removed.
13879 context.currentNode = null;
13880 }
13881 else {
13882 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, node.loc));
13883 }
13884 break;
13885 }
13886 }
13887 }
13888 function createIfBranch(node, dir) {
13889 const isTemplateIf = node.tagType === 3 /* ElementTypes.TEMPLATE */;
13890 return {
13891 type: 10 /* NodeTypes.IF_BRANCH */,
13892 loc: node.loc,
13893 condition: dir.name === 'else' ? undefined : dir.exp,
13894 children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
13895 userKey: findProp(node, `key`),
13896 isTemplateIf
13897 };
13898 }
13899 function createCodegenNodeForBranch(branch, keyIndex, context) {
13900 if (branch.condition) {
13901 return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
13902 // make sure to pass in asBlock: true so that the comment node call
13903 // closes the current block.
13904 createCallExpression(context.helper(CREATE_COMMENT), [
13905 '"v-if"' ,
13906 'true'
13907 ]));
13908 }
13909 else {
13910 return createChildrenCodegenNode(branch, keyIndex, context);
13911 }
13912 }
13913 function createChildrenCodegenNode(branch, keyIndex, context) {
13914 const { helper } = context;
13915 const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* ConstantTypes.CAN_HOIST */));
13916 const { children } = branch;
13917 const firstChild = children[0];
13918 const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* NodeTypes.ELEMENT */;
13919 if (needFragmentWrapper) {
13920 if (children.length === 1 && firstChild.type === 11 /* NodeTypes.FOR */) {
13921 // optimize away nested fragments when child is a ForNode
13922 const vnodeCall = firstChild.codegenNode;
13923 injectProp(vnodeCall, keyProperty, context);
13924 return vnodeCall;
13925 }
13926 else {
13927 let patchFlag = 64 /* PatchFlags.STABLE_FRAGMENT */;
13928 let patchFlagText = PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */];
13929 // check if the fragment actually contains a single valid child with
13930 // the rest being comments
13931 if (!branch.isTemplateIf &&
13932 children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */).length === 1) {
13933 patchFlag |= 2048 /* PatchFlags.DEV_ROOT_FRAGMENT */;
13934 patchFlagText += `, ${PatchFlagNames[2048 /* PatchFlags.DEV_ROOT_FRAGMENT */]}`;
13935 }
13936 return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (` /* ${patchFlagText} */` ), undefined, undefined, true, false, false /* isComponent */, branch.loc);
13937 }
13938 }
13939 else {
13940 const ret = firstChild.codegenNode;
13941 const vnodeCall = getMemoedVNodeCall(ret);
13942 // Change createVNode to createBlock.
13943 if (vnodeCall.type === 13 /* NodeTypes.VNODE_CALL */) {
13944 makeBlock(vnodeCall, context);
13945 }
13946 // inject branch key
13947 injectProp(vnodeCall, keyProperty, context);
13948 return ret;
13949 }
13950 }
13951 function isSameKey(a, b) {
13952 if (!a || a.type !== b.type) {
13953 return false;
13954 }
13955 if (a.type === 6 /* NodeTypes.ATTRIBUTE */) {
13956 if (a.value.content !== b.value.content) {
13957 return false;
13958 }
13959 }
13960 else {
13961 // directive
13962 const exp = a.exp;
13963 const branchExp = b.exp;
13964 if (exp.type !== branchExp.type) {
13965 return false;
13966 }
13967 if (exp.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
13968 exp.isStatic !== branchExp.isStatic ||
13969 exp.content !== branchExp.content) {
13970 return false;
13971 }
13972 }
13973 return true;
13974 }
13975 function getParentCondition(node) {
13976 while (true) {
13977 if (node.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) {
13978 if (node.alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) {
13979 node = node.alternate;
13980 }
13981 else {
13982 return node;
13983 }
13984 }
13985 else if (node.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */) {
13986 node = node.value;
13987 }
13988 }
13989 }
13990
13991 const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
13992 const { helper, removeHelper } = context;
13993 return processFor(node, dir, context, forNode => {
13994 // create the loop render function expression now, and add the
13995 // iterator on exit after all children have been traversed
13996 const renderExp = createCallExpression(helper(RENDER_LIST), [
13997 forNode.source
13998 ]);
13999 const isTemplate = isTemplateNode(node);
14000 const memo = findDir(node, 'memo');
14001 const keyProp = findProp(node, `key`);
14002 const keyExp = keyProp &&
14003 (keyProp.type === 6 /* NodeTypes.ATTRIBUTE */
14004 ? createSimpleExpression(keyProp.value.content, true)
14005 : keyProp.exp);
14006 const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
14007 const isStableFragment = forNode.source.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
14008 forNode.source.constType > 0 /* ConstantTypes.NOT_CONSTANT */;
14009 const fragmentFlag = isStableFragment
14010 ? 64 /* PatchFlags.STABLE_FRAGMENT */
14011 : keyProp
14012 ? 128 /* PatchFlags.KEYED_FRAGMENT */
14013 : 256 /* PatchFlags.UNKEYED_FRAGMENT */;
14014 forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
14015 (` /* ${PatchFlagNames[fragmentFlag]} */` ), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
14016 return () => {
14017 // finish the codegen now that all children have been traversed
14018 let childBlock;
14019 const { children } = forNode;
14020 // check <template v-for> key placement
14021 if (isTemplate) {
14022 node.children.some(c => {
14023 if (c.type === 1 /* NodeTypes.ELEMENT */) {
14024 const key = findProp(c, 'key');
14025 if (key) {
14026 context.onError(createCompilerError(33 /* ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
14027 return true;
14028 }
14029 }
14030 });
14031 }
14032 const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* NodeTypes.ELEMENT */;
14033 const slotOutlet = isSlotOutlet(node)
14034 ? node
14035 : isTemplate &&
14036 node.children.length === 1 &&
14037 isSlotOutlet(node.children[0])
14038 ? node.children[0] // api-extractor somehow fails to infer this
14039 : null;
14040 if (slotOutlet) {
14041 // <slot v-for="..."> or <template v-for="..."><slot/></template>
14042 childBlock = slotOutlet.codegenNode;
14043 if (isTemplate && keyProperty) {
14044 // <template v-for="..." :key="..."><slot/></template>
14045 // we need to inject the key to the renderSlot() call.
14046 // the props for renderSlot is passed as the 3rd argument.
14047 injectProp(childBlock, keyProperty, context);
14048 }
14049 }
14050 else if (needFragmentWrapper) {
14051 // <template v-for="..."> with text or multi-elements
14052 // should generate a fragment block for each loop
14053 childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* PatchFlags.STABLE_FRAGMENT */ +
14054 (` /* ${PatchFlagNames[64 /* PatchFlags.STABLE_FRAGMENT */]} */`
14055 ), undefined, undefined, true, undefined, false /* isComponent */);
14056 }
14057 else {
14058 // Normal element v-for. Directly use the child's codegenNode
14059 // but mark it as a block.
14060 childBlock = children[0]
14061 .codegenNode;
14062 if (isTemplate && keyProperty) {
14063 injectProp(childBlock, keyProperty, context);
14064 }
14065 if (childBlock.isBlock !== !isStableFragment) {
14066 if (childBlock.isBlock) {
14067 // switch from block to vnode
14068 removeHelper(OPEN_BLOCK);
14069 removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14070 }
14071 else {
14072 // switch from vnode to block
14073 removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14074 }
14075 }
14076 childBlock.isBlock = !isStableFragment;
14077 if (childBlock.isBlock) {
14078 helper(OPEN_BLOCK);
14079 helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
14080 }
14081 else {
14082 helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
14083 }
14084 }
14085 if (memo) {
14086 const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
14087 createSimpleExpression(`_cached`)
14088 ]));
14089 loop.body = createBlockStatement([
14090 createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
14091 createCompoundExpression([
14092 `if (_cached`,
14093 ...(keyExp ? [` && _cached.key === `, keyExp] : []),
14094 ` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
14095 ]),
14096 createCompoundExpression([`const _item = `, childBlock]),
14097 createSimpleExpression(`_item.memo = _memo`),
14098 createSimpleExpression(`return _item`)
14099 ]);
14100 renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
14101 }
14102 else {
14103 renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
14104 }
14105 };
14106 });
14107 });
14108 // target-agnostic transform used for both Client and SSR
14109 function processFor(node, dir, context, processCodegen) {
14110 if (!dir.exp) {
14111 context.onError(createCompilerError(31 /* ErrorCodes.X_V_FOR_NO_EXPRESSION */, dir.loc));
14112 return;
14113 }
14114 const parseResult = parseForExpression(
14115 // can only be simple expression because vFor transform is applied
14116 // before expression transform.
14117 dir.exp, context);
14118 if (!parseResult) {
14119 context.onError(createCompilerError(32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
14120 return;
14121 }
14122 const { addIdentifiers, removeIdentifiers, scopes } = context;
14123 const { source, value, key, index } = parseResult;
14124 const forNode = {
14125 type: 11 /* NodeTypes.FOR */,
14126 loc: dir.loc,
14127 source,
14128 valueAlias: value,
14129 keyAlias: key,
14130 objectIndexAlias: index,
14131 parseResult,
14132 children: isTemplateNode(node) ? node.children : [node]
14133 };
14134 context.replaceNode(forNode);
14135 // bookkeeping
14136 scopes.vFor++;
14137 const onExit = processCodegen && processCodegen(forNode);
14138 return () => {
14139 scopes.vFor--;
14140 if (onExit)
14141 onExit();
14142 };
14143 }
14144 const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
14145 // This regex doesn't cover the case if key or index aliases have destructuring,
14146 // but those do not make sense in the first place, so this works in practice.
14147 const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
14148 const stripParensRE = /^\(|\)$/g;
14149 function parseForExpression(input, context) {
14150 const loc = input.loc;
14151 const exp = input.content;
14152 const inMatch = exp.match(forAliasRE);
14153 if (!inMatch)
14154 return;
14155 const [, LHS, RHS] = inMatch;
14156 const result = {
14157 source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
14158 value: undefined,
14159 key: undefined,
14160 index: undefined
14161 };
14162 {
14163 validateBrowserExpression(result.source, context);
14164 }
14165 let valueContent = LHS.trim().replace(stripParensRE, '').trim();
14166 const trimmedOffset = LHS.indexOf(valueContent);
14167 const iteratorMatch = valueContent.match(forIteratorRE);
14168 if (iteratorMatch) {
14169 valueContent = valueContent.replace(forIteratorRE, '').trim();
14170 const keyContent = iteratorMatch[1].trim();
14171 let keyOffset;
14172 if (keyContent) {
14173 keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
14174 result.key = createAliasExpression(loc, keyContent, keyOffset);
14175 {
14176 validateBrowserExpression(result.key, context, true);
14177 }
14178 }
14179 if (iteratorMatch[2]) {
14180 const indexContent = iteratorMatch[2].trim();
14181 if (indexContent) {
14182 result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
14183 ? keyOffset + keyContent.length
14184 : trimmedOffset + valueContent.length));
14185 {
14186 validateBrowserExpression(result.index, context, true);
14187 }
14188 }
14189 }
14190 }
14191 if (valueContent) {
14192 result.value = createAliasExpression(loc, valueContent, trimmedOffset);
14193 {
14194 validateBrowserExpression(result.value, context, true);
14195 }
14196 }
14197 return result;
14198 }
14199 function createAliasExpression(range, content, offset) {
14200 return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
14201 }
14202 function createForLoopParams({ value, key, index }, memoArgs = []) {
14203 return createParamsList([value, key, index, ...memoArgs]);
14204 }
14205 function createParamsList(args) {
14206 let i = args.length;
14207 while (i--) {
14208 if (args[i])
14209 break;
14210 }
14211 return args
14212 .slice(0, i + 1)
14213 .map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
14214 }
14215
14216 const defaultFallback = createSimpleExpression(`undefined`, false);
14217 // A NodeTransform that:
14218 // 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
14219 // by transformExpression. This is only applied in non-browser builds with
14220 // { prefixIdentifiers: true }.
14221 // 2. Track v-slot depths so that we know a slot is inside another slot.
14222 // Note the exit callback is executed before buildSlots() on the same node,
14223 // so only nested slots see positive numbers.
14224 const trackSlotScopes = (node, context) => {
14225 if (node.type === 1 /* NodeTypes.ELEMENT */ &&
14226 (node.tagType === 1 /* ElementTypes.COMPONENT */ ||
14227 node.tagType === 3 /* ElementTypes.TEMPLATE */)) {
14228 // We are only checking non-empty v-slot here
14229 // since we only care about slots that introduce scope variables.
14230 const vSlot = findDir(node, 'slot');
14231 if (vSlot) {
14232 vSlot.exp;
14233 context.scopes.vSlot++;
14234 return () => {
14235 context.scopes.vSlot--;
14236 };
14237 }
14238 }
14239 };
14240 const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
14241 // Instead of being a DirectiveTransform, v-slot processing is called during
14242 // transformElement to build the slots object for a component.
14243 function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
14244 context.helper(WITH_CTX);
14245 const { children, loc } = node;
14246 const slotsProperties = [];
14247 const dynamicSlots = [];
14248 // If the slot is inside a v-for or another v-slot, force it to be dynamic
14249 // since it likely uses a scope variable.
14250 let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
14251 // 1. Check for slot with slotProps on component itself.
14252 // <Comp v-slot="{ prop }"/>
14253 const onComponentSlot = findDir(node, 'slot', true);
14254 if (onComponentSlot) {
14255 const { arg, exp } = onComponentSlot;
14256 if (arg && !isStaticExp(arg)) {
14257 hasDynamicSlots = true;
14258 }
14259 slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
14260 }
14261 // 2. Iterate through children and check for template slots
14262 // <template v-slot:foo="{ prop }">
14263 let hasTemplateSlots = false;
14264 let hasNamedDefaultSlot = false;
14265 const implicitDefaultChildren = [];
14266 const seenSlotNames = new Set();
14267 let conditionalBranchIndex = 0;
14268 for (let i = 0; i < children.length; i++) {
14269 const slotElement = children[i];
14270 let slotDir;
14271 if (!isTemplateNode(slotElement) ||
14272 !(slotDir = findDir(slotElement, 'slot', true))) {
14273 // not a <template v-slot>, skip.
14274 if (slotElement.type !== 3 /* NodeTypes.COMMENT */) {
14275 implicitDefaultChildren.push(slotElement);
14276 }
14277 continue;
14278 }
14279 if (onComponentSlot) {
14280 // already has on-component slot - this is incorrect usage.
14281 context.onError(createCompilerError(37 /* ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
14282 break;
14283 }
14284 hasTemplateSlots = true;
14285 const { children: slotChildren, loc: slotLoc } = slotElement;
14286 const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
14287 // check if name is dynamic.
14288 let staticSlotName;
14289 if (isStaticExp(slotName)) {
14290 staticSlotName = slotName ? slotName.content : `default`;
14291 }
14292 else {
14293 hasDynamicSlots = true;
14294 }
14295 const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
14296 // check if this slot is conditional (v-if/v-for)
14297 let vIf;
14298 let vElse;
14299 let vFor;
14300 if ((vIf = findDir(slotElement, 'if'))) {
14301 hasDynamicSlots = true;
14302 dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++), defaultFallback));
14303 }
14304 else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
14305 // find adjacent v-if
14306 let j = i;
14307 let prev;
14308 while (j--) {
14309 prev = children[j];
14310 if (prev.type !== 3 /* NodeTypes.COMMENT */) {
14311 break;
14312 }
14313 }
14314 if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
14315 // remove node
14316 children.splice(i, 1);
14317 i--;
14318 // attach this slot to previous conditional
14319 let conditional = dynamicSlots[dynamicSlots.length - 1];
14320 while (conditional.alternate.type === 19 /* NodeTypes.JS_CONDITIONAL_EXPRESSION */) {
14321 conditional = conditional.alternate;
14322 }
14323 conditional.alternate = vElse.exp
14324 ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++), defaultFallback)
14325 : buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++);
14326 }
14327 else {
14328 context.onError(createCompilerError(30 /* ErrorCodes.X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
14329 }
14330 }
14331 else if ((vFor = findDir(slotElement, 'for'))) {
14332 hasDynamicSlots = true;
14333 const parseResult = vFor.parseResult ||
14334 parseForExpression(vFor.exp, context);
14335 if (parseResult) {
14336 // Render the dynamic slots as an array and add it to the createSlot()
14337 // args. The runtime knows how to handle it appropriately.
14338 dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
14339 parseResult.source,
14340 createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
14341 ]));
14342 }
14343 else {
14344 context.onError(createCompilerError(32 /* ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
14345 }
14346 }
14347 else {
14348 // check duplicate static names
14349 if (staticSlotName) {
14350 if (seenSlotNames.has(staticSlotName)) {
14351 context.onError(createCompilerError(38 /* ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
14352 continue;
14353 }
14354 seenSlotNames.add(staticSlotName);
14355 if (staticSlotName === 'default') {
14356 hasNamedDefaultSlot = true;
14357 }
14358 }
14359 slotsProperties.push(createObjectProperty(slotName, slotFunction));
14360 }
14361 }
14362 if (!onComponentSlot) {
14363 const buildDefaultSlotProperty = (props, children) => {
14364 const fn = buildSlotFn(props, children, loc);
14365 return createObjectProperty(`default`, fn);
14366 };
14367 if (!hasTemplateSlots) {
14368 // implicit default slot (on component)
14369 slotsProperties.push(buildDefaultSlotProperty(undefined, children));
14370 }
14371 else if (implicitDefaultChildren.length &&
14372 // #3766
14373 // with whitespace: 'preserve', whitespaces between slots will end up in
14374 // implicitDefaultChildren. Ignore if all implicit children are whitespaces.
14375 implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
14376 // implicit default slot (mixed with named slots)
14377 if (hasNamedDefaultSlot) {
14378 context.onError(createCompilerError(39 /* ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
14379 }
14380 else {
14381 slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
14382 }
14383 }
14384 }
14385 const slotFlag = hasDynamicSlots
14386 ? 2 /* SlotFlags.DYNAMIC */
14387 : hasForwardedSlots(node.children)
14388 ? 3 /* SlotFlags.FORWARDED */
14389 : 1 /* SlotFlags.STABLE */;
14390 let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
14391 // 2 = compiled but dynamic = can skip normalization, but must run diff
14392 // 1 = compiled and static = can skip normalization AND diff as optimized
14393 createSimpleExpression(slotFlag + (` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
14394 if (dynamicSlots.length) {
14395 slots = createCallExpression(context.helper(CREATE_SLOTS), [
14396 slots,
14397 createArrayExpression(dynamicSlots)
14398 ]);
14399 }
14400 return {
14401 slots,
14402 hasDynamicSlots
14403 };
14404 }
14405 function buildDynamicSlot(name, fn, index) {
14406 const props = [
14407 createObjectProperty(`name`, name),
14408 createObjectProperty(`fn`, fn)
14409 ];
14410 if (index != null) {
14411 props.push(createObjectProperty(`key`, createSimpleExpression(String(index), true)));
14412 }
14413 return createObjectExpression(props);
14414 }
14415 function hasForwardedSlots(children) {
14416 for (let i = 0; i < children.length; i++) {
14417 const child = children[i];
14418 switch (child.type) {
14419 case 1 /* NodeTypes.ELEMENT */:
14420 if (child.tagType === 2 /* ElementTypes.SLOT */ ||
14421 hasForwardedSlots(child.children)) {
14422 return true;
14423 }
14424 break;
14425 case 9 /* NodeTypes.IF */:
14426 if (hasForwardedSlots(child.branches))
14427 return true;
14428 break;
14429 case 10 /* NodeTypes.IF_BRANCH */:
14430 case 11 /* NodeTypes.FOR */:
14431 if (hasForwardedSlots(child.children))
14432 return true;
14433 break;
14434 }
14435 }
14436 return false;
14437 }
14438 function isNonWhitespaceContent(node) {
14439 if (node.type !== 2 /* NodeTypes.TEXT */ && node.type !== 12 /* NodeTypes.TEXT_CALL */)
14440 return true;
14441 return node.type === 2 /* NodeTypes.TEXT */
14442 ? !!node.content.trim()
14443 : isNonWhitespaceContent(node.content);
14444 }
14445
14446 // some directive transforms (e.g. v-model) may return a symbol for runtime
14447 // import, which should be used instead of a resolveDirective call.
14448 const directiveImportMap = new WeakMap();
14449 // generate a JavaScript AST for this element's codegen
14450 const transformElement = (node, context) => {
14451 // perform the work on exit, after all child expressions have been
14452 // processed and merged.
14453 return function postTransformElement() {
14454 node = context.currentNode;
14455 if (!(node.type === 1 /* NodeTypes.ELEMENT */ &&
14456 (node.tagType === 0 /* ElementTypes.ELEMENT */ ||
14457 node.tagType === 1 /* ElementTypes.COMPONENT */))) {
14458 return;
14459 }
14460 const { tag, props } = node;
14461 const isComponent = node.tagType === 1 /* ElementTypes.COMPONENT */;
14462 // The goal of the transform is to create a codegenNode implementing the
14463 // VNodeCall interface.
14464 let vnodeTag = isComponent
14465 ? resolveComponentType(node, context)
14466 : `"${tag}"`;
14467 const isDynamicComponent = isObject(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
14468 let vnodeProps;
14469 let vnodeChildren;
14470 let vnodePatchFlag;
14471 let patchFlag = 0;
14472 let vnodeDynamicProps;
14473 let dynamicPropNames;
14474 let vnodeDirectives;
14475 let shouldUseBlock =
14476 // dynamic component may resolve to plain elements
14477 isDynamicComponent ||
14478 vnodeTag === TELEPORT ||
14479 vnodeTag === SUSPENSE ||
14480 (!isComponent &&
14481 // <svg> and <foreignObject> must be forced into blocks so that block
14482 // updates inside get proper isSVG flag at runtime. (#639, #643)
14483 // This is technically web-specific, but splitting the logic out of core
14484 // leads to too much unnecessary complexity.
14485 (tag === 'svg' || tag === 'foreignObject'));
14486 // props
14487 if (props.length > 0) {
14488 const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
14489 vnodeProps = propsBuildResult.props;
14490 patchFlag = propsBuildResult.patchFlag;
14491 dynamicPropNames = propsBuildResult.dynamicPropNames;
14492 const directives = propsBuildResult.directives;
14493 vnodeDirectives =
14494 directives && directives.length
14495 ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14496 : undefined;
14497 if (propsBuildResult.shouldUseBlock) {
14498 shouldUseBlock = true;
14499 }
14500 }
14501 // children
14502 if (node.children.length > 0) {
14503 if (vnodeTag === KEEP_ALIVE) {
14504 // Although a built-in component, we compile KeepAlive with raw children
14505 // instead of slot functions so that it can be used inside Transition
14506 // or other Transition-wrapping HOCs.
14507 // To ensure correct updates with block optimizations, we need to:
14508 // 1. Force keep-alive into a block. This avoids its children being
14509 // collected by a parent block.
14510 shouldUseBlock = true;
14511 // 2. Force keep-alive to always be updated, since it uses raw children.
14512 patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */;
14513 if (node.children.length > 1) {
14514 context.onError(createCompilerError(46 /* ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN */, {
14515 start: node.children[0].loc.start,
14516 end: node.children[node.children.length - 1].loc.end,
14517 source: ''
14518 }));
14519 }
14520 }
14521 const shouldBuildAsSlots = isComponent &&
14522 // Teleport is not a real component and has dedicated runtime handling
14523 vnodeTag !== TELEPORT &&
14524 // explained above.
14525 vnodeTag !== KEEP_ALIVE;
14526 if (shouldBuildAsSlots) {
14527 const { slots, hasDynamicSlots } = buildSlots(node, context);
14528 vnodeChildren = slots;
14529 if (hasDynamicSlots) {
14530 patchFlag |= 1024 /* PatchFlags.DYNAMIC_SLOTS */;
14531 }
14532 }
14533 else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
14534 const child = node.children[0];
14535 const type = child.type;
14536 // check for dynamic text children
14537 const hasDynamicTextChild = type === 5 /* NodeTypes.INTERPOLATION */ ||
14538 type === 8 /* NodeTypes.COMPOUND_EXPRESSION */;
14539 if (hasDynamicTextChild &&
14540 getConstantType(child, context) === 0 /* ConstantTypes.NOT_CONSTANT */) {
14541 patchFlag |= 1 /* PatchFlags.TEXT */;
14542 }
14543 // pass directly if the only child is a text node
14544 // (plain / interpolation / expression)
14545 if (hasDynamicTextChild || type === 2 /* NodeTypes.TEXT */) {
14546 vnodeChildren = child;
14547 }
14548 else {
14549 vnodeChildren = node.children;
14550 }
14551 }
14552 else {
14553 vnodeChildren = node.children;
14554 }
14555 }
14556 // patchFlag & dynamicPropNames
14557 if (patchFlag !== 0) {
14558 {
14559 if (patchFlag < 0) {
14560 // special flags (negative and mutually exclusive)
14561 vnodePatchFlag = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`;
14562 }
14563 else {
14564 // bitwise flags
14565 const flagNames = Object.keys(PatchFlagNames)
14566 .map(Number)
14567 .filter(n => n > 0 && patchFlag & n)
14568 .map(n => PatchFlagNames[n])
14569 .join(`, `);
14570 vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
14571 }
14572 }
14573 if (dynamicPropNames && dynamicPropNames.length) {
14574 vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
14575 }
14576 }
14577 node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
14578 };
14579 };
14580 function resolveComponentType(node, context, ssr = false) {
14581 let { tag } = node;
14582 // 1. dynamic component
14583 const isExplicitDynamic = isComponentTag(tag);
14584 const isProp = findProp(node, 'is');
14585 if (isProp) {
14586 if (isExplicitDynamic ||
14587 (false )) {
14588 const exp = isProp.type === 6 /* NodeTypes.ATTRIBUTE */
14589 ? isProp.value && createSimpleExpression(isProp.value.content, true)
14590 : isProp.exp;
14591 if (exp) {
14592 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14593 exp
14594 ]);
14595 }
14596 }
14597 else if (isProp.type === 6 /* NodeTypes.ATTRIBUTE */ &&
14598 isProp.value.content.startsWith('vue:')) {
14599 // <button is="vue:xxx">
14600 // if not <component>, only is value that starts with "vue:" will be
14601 // treated as component by the parse phase and reach here, unless it's
14602 // compat mode where all is values are considered components
14603 tag = isProp.value.content.slice(4);
14604 }
14605 }
14606 // 1.5 v-is (TODO: Deprecate)
14607 const isDir = !isExplicitDynamic && findDir(node, 'is');
14608 if (isDir && isDir.exp) {
14609 return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
14610 isDir.exp
14611 ]);
14612 }
14613 // 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
14614 const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
14615 if (builtIn) {
14616 // built-ins are simply fallthroughs / have special handling during ssr
14617 // so we don't need to import their runtime equivalents
14618 if (!ssr)
14619 context.helper(builtIn);
14620 return builtIn;
14621 }
14622 // 5. user component (resolve)
14623 context.helper(RESOLVE_COMPONENT);
14624 context.components.add(tag);
14625 return toValidAssetId(tag, `component`);
14626 }
14627 function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
14628 const { tag, loc: elementLoc, children } = node;
14629 let properties = [];
14630 const mergeArgs = [];
14631 const runtimeDirectives = [];
14632 const hasChildren = children.length > 0;
14633 let shouldUseBlock = false;
14634 // patchFlag analysis
14635 let patchFlag = 0;
14636 let hasRef = false;
14637 let hasClassBinding = false;
14638 let hasStyleBinding = false;
14639 let hasHydrationEventBinding = false;
14640 let hasDynamicKeys = false;
14641 let hasVnodeHook = false;
14642 const dynamicPropNames = [];
14643 const pushMergeArg = (arg) => {
14644 if (properties.length) {
14645 mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
14646 properties = [];
14647 }
14648 if (arg)
14649 mergeArgs.push(arg);
14650 };
14651 const analyzePatchFlag = ({ key, value }) => {
14652 if (isStaticExp(key)) {
14653 const name = key.content;
14654 const isEventHandler = isOn(name);
14655 if (isEventHandler &&
14656 (!isComponent || isDynamicComponent) &&
14657 // omit the flag for click handlers because hydration gives click
14658 // dedicated fast path.
14659 name.toLowerCase() !== 'onclick' &&
14660 // omit v-model handlers
14661 name !== 'onUpdate:modelValue' &&
14662 // omit onVnodeXXX hooks
14663 !isReservedProp(name)) {
14664 hasHydrationEventBinding = true;
14665 }
14666 if (isEventHandler && isReservedProp(name)) {
14667 hasVnodeHook = true;
14668 }
14669 if (value.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */ ||
14670 ((value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
14671 value.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) &&
14672 getConstantType(value, context) > 0)) {
14673 // skip if the prop is a cached handler or has constant value
14674 return;
14675 }
14676 if (name === 'ref') {
14677 hasRef = true;
14678 }
14679 else if (name === 'class') {
14680 hasClassBinding = true;
14681 }
14682 else if (name === 'style') {
14683 hasStyleBinding = true;
14684 }
14685 else if (name !== 'key' && !dynamicPropNames.includes(name)) {
14686 dynamicPropNames.push(name);
14687 }
14688 // treat the dynamic class and style binding of the component as dynamic props
14689 if (isComponent &&
14690 (name === 'class' || name === 'style') &&
14691 !dynamicPropNames.includes(name)) {
14692 dynamicPropNames.push(name);
14693 }
14694 }
14695 else {
14696 hasDynamicKeys = true;
14697 }
14698 };
14699 for (let i = 0; i < props.length; i++) {
14700 // static attribute
14701 const prop = props[i];
14702 if (prop.type === 6 /* NodeTypes.ATTRIBUTE */) {
14703 const { loc, name, value } = prop;
14704 let isStatic = true;
14705 if (name === 'ref') {
14706 hasRef = true;
14707 if (context.scopes.vFor > 0) {
14708 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14709 }
14710 }
14711 // skip is on <component>, or is="vue:xxx"
14712 if (name === 'is' &&
14713 (isComponentTag(tag) ||
14714 (value && value.content.startsWith('vue:')) ||
14715 (false ))) {
14716 continue;
14717 }
14718 properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14719 }
14720 else {
14721 // directives
14722 const { name, arg, exp, loc } = prop;
14723 const isVBind = name === 'bind';
14724 const isVOn = name === 'on';
14725 // skip v-slot - it is handled by its dedicated transform.
14726 if (name === 'slot') {
14727 if (!isComponent) {
14728 context.onError(createCompilerError(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, loc));
14729 }
14730 continue;
14731 }
14732 // skip v-once/v-memo - they are handled by dedicated transforms.
14733 if (name === 'once' || name === 'memo') {
14734 continue;
14735 }
14736 // skip v-is and :is on <component>
14737 if (name === 'is' ||
14738 (isVBind &&
14739 isStaticArgOf(arg, 'is') &&
14740 (isComponentTag(tag) ||
14741 (false )))) {
14742 continue;
14743 }
14744 // skip v-on in SSR compilation
14745 if (isVOn && ssr) {
14746 continue;
14747 }
14748 if (
14749 // #938: elements with dynamic keys should be forced into blocks
14750 (isVBind && isStaticArgOf(arg, 'key')) ||
14751 // inline before-update hooks need to force block so that it is invoked
14752 // before children
14753 (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14754 shouldUseBlock = true;
14755 }
14756 if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14757 properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14758 }
14759 // special case for v-bind and v-on with no argument
14760 if (!arg && (isVBind || isVOn)) {
14761 hasDynamicKeys = true;
14762 if (exp) {
14763 if (isVBind) {
14764 // have to merge early for compat build check
14765 pushMergeArg();
14766 mergeArgs.push(exp);
14767 }
14768 else {
14769 // v-on="obj" -> toHandlers(obj)
14770 pushMergeArg({
14771 type: 14 /* NodeTypes.JS_CALL_EXPRESSION */,
14772 loc,
14773 callee: context.helper(TO_HANDLERS),
14774 arguments: isComponent ? [exp] : [exp, `true`]
14775 });
14776 }
14777 }
14778 else {
14779 context.onError(createCompilerError(isVBind
14780 ? 34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */
14781 : 35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */, loc));
14782 }
14783 continue;
14784 }
14785 const directiveTransform = context.directiveTransforms[name];
14786 if (directiveTransform) {
14787 // has built-in directive transform.
14788 const { props, needRuntime } = directiveTransform(prop, node, context);
14789 !ssr && props.forEach(analyzePatchFlag);
14790 if (isVOn && arg && !isStaticExp(arg)) {
14791 pushMergeArg(createObjectExpression(props, elementLoc));
14792 }
14793 else {
14794 properties.push(...props);
14795 }
14796 if (needRuntime) {
14797 runtimeDirectives.push(prop);
14798 if (isSymbol(needRuntime)) {
14799 directiveImportMap.set(prop, needRuntime);
14800 }
14801 }
14802 }
14803 else if (!isBuiltInDirective(name)) {
14804 // no built-in transform, this is a user custom directive.
14805 runtimeDirectives.push(prop);
14806 // custom dirs may use beforeUpdate so they need to force blocks
14807 // to ensure before-update gets called before children update
14808 if (hasChildren) {
14809 shouldUseBlock = true;
14810 }
14811 }
14812 }
14813 }
14814 let propsExpression = undefined;
14815 // has v-bind="object" or v-on="object", wrap with mergeProps
14816 if (mergeArgs.length) {
14817 // close up any not-yet-merged props
14818 pushMergeArg();
14819 if (mergeArgs.length > 1) {
14820 propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
14821 }
14822 else {
14823 // single v-bind with nothing else - no need for a mergeProps call
14824 propsExpression = mergeArgs[0];
14825 }
14826 }
14827 else if (properties.length) {
14828 propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
14829 }
14830 // patchFlag analysis
14831 if (hasDynamicKeys) {
14832 patchFlag |= 16 /* PatchFlags.FULL_PROPS */;
14833 }
14834 else {
14835 if (hasClassBinding && !isComponent) {
14836 patchFlag |= 2 /* PatchFlags.CLASS */;
14837 }
14838 if (hasStyleBinding && !isComponent) {
14839 patchFlag |= 4 /* PatchFlags.STYLE */;
14840 }
14841 if (dynamicPropNames.length) {
14842 patchFlag |= 8 /* PatchFlags.PROPS */;
14843 }
14844 if (hasHydrationEventBinding) {
14845 patchFlag |= 32 /* PatchFlags.HYDRATE_EVENTS */;
14846 }
14847 }
14848 if (!shouldUseBlock &&
14849 (patchFlag === 0 || patchFlag === 32 /* PatchFlags.HYDRATE_EVENTS */) &&
14850 (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14851 patchFlag |= 512 /* PatchFlags.NEED_PATCH */;
14852 }
14853 // pre-normalize props, SSR is skipped for now
14854 if (!context.inSSR && propsExpression) {
14855 switch (propsExpression.type) {
14856 case 15 /* NodeTypes.JS_OBJECT_EXPRESSION */:
14857 // means that there is no v-bind,
14858 // but still need to deal with dynamic key binding
14859 let classKeyIndex = -1;
14860 let styleKeyIndex = -1;
14861 let hasDynamicKey = false;
14862 for (let i = 0; i < propsExpression.properties.length; i++) {
14863 const key = propsExpression.properties[i].key;
14864 if (isStaticExp(key)) {
14865 if (key.content === 'class') {
14866 classKeyIndex = i;
14867 }
14868 else if (key.content === 'style') {
14869 styleKeyIndex = i;
14870 }
14871 }
14872 else if (!key.isHandlerKey) {
14873 hasDynamicKey = true;
14874 }
14875 }
14876 const classProp = propsExpression.properties[classKeyIndex];
14877 const styleProp = propsExpression.properties[styleKeyIndex];
14878 // no dynamic key
14879 if (!hasDynamicKey) {
14880 if (classProp && !isStaticExp(classProp.value)) {
14881 classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
14882 }
14883 if (styleProp &&
14884 // the static style is compiled into an object,
14885 // so use `hasStyleBinding` to ensure that it is a dynamic style binding
14886 (hasStyleBinding ||
14887 (styleProp.value.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
14888 styleProp.value.content.trim()[0] === `[`) ||
14889 // v-bind:style and style both exist,
14890 // v-bind:style with static literal object
14891 styleProp.value.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */)) {
14892 styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
14893 }
14894 }
14895 else {
14896 // dynamic key binding, wrap with `normalizeProps`
14897 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
14898 }
14899 break;
14900 case 14 /* NodeTypes.JS_CALL_EXPRESSION */:
14901 // mergeProps call, do nothing
14902 break;
14903 default:
14904 // single v-bind
14905 propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
14906 createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
14907 propsExpression
14908 ])
14909 ]);
14910 break;
14911 }
14912 }
14913 return {
14914 props: propsExpression,
14915 directives: runtimeDirectives,
14916 patchFlag,
14917 dynamicPropNames,
14918 shouldUseBlock
14919 };
14920 }
14921 // Dedupe props in an object literal.
14922 // Literal duplicated attributes would have been warned during the parse phase,
14923 // however, it's possible to encounter duplicated `onXXX` handlers with different
14924 // modifiers. We also need to merge static and dynamic class / style attributes.
14925 // - onXXX handlers / style: merge into array
14926 // - class: merge into single expression with concatenation
14927 function dedupeProperties(properties) {
14928 const knownProps = new Map();
14929 const deduped = [];
14930 for (let i = 0; i < properties.length; i++) {
14931 const prop = properties[i];
14932 // dynamic keys are always allowed
14933 if (prop.key.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
14934 deduped.push(prop);
14935 continue;
14936 }
14937 const name = prop.key.content;
14938 const existing = knownProps.get(name);
14939 if (existing) {
14940 if (name === 'style' || name === 'class' || isOn(name)) {
14941 mergeAsArray(existing, prop);
14942 }
14943 // unexpected duplicate, should have emitted error during parse
14944 }
14945 else {
14946 knownProps.set(name, prop);
14947 deduped.push(prop);
14948 }
14949 }
14950 return deduped;
14951 }
14952 function mergeAsArray(existing, incoming) {
14953 if (existing.value.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */) {
14954 existing.value.elements.push(incoming.value);
14955 }
14956 else {
14957 existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
14958 }
14959 }
14960 function buildDirectiveArgs(dir, context) {
14961 const dirArgs = [];
14962 const runtime = directiveImportMap.get(dir);
14963 if (runtime) {
14964 // built-in directive with runtime
14965 dirArgs.push(context.helperString(runtime));
14966 }
14967 else {
14968 {
14969 // inject statement for resolving directive
14970 context.helper(RESOLVE_DIRECTIVE);
14971 context.directives.add(dir.name);
14972 dirArgs.push(toValidAssetId(dir.name, `directive`));
14973 }
14974 }
14975 const { loc } = dir;
14976 if (dir.exp)
14977 dirArgs.push(dir.exp);
14978 if (dir.arg) {
14979 if (!dir.exp) {
14980 dirArgs.push(`void 0`);
14981 }
14982 dirArgs.push(dir.arg);
14983 }
14984 if (Object.keys(dir.modifiers).length) {
14985 if (!dir.arg) {
14986 if (!dir.exp) {
14987 dirArgs.push(`void 0`);
14988 }
14989 dirArgs.push(`void 0`);
14990 }
14991 const trueExpression = createSimpleExpression(`true`, false, loc);
14992 dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
14993 }
14994 return createArrayExpression(dirArgs, dir.loc);
14995 }
14996 function stringifyDynamicPropNames(props) {
14997 let propsNamesString = `[`;
14998 for (let i = 0, l = props.length; i < l; i++) {
14999 propsNamesString += JSON.stringify(props[i]);
15000 if (i < l - 1)
15001 propsNamesString += ', ';
15002 }
15003 return propsNamesString + `]`;
15004 }
15005 function isComponentTag(tag) {
15006 return tag === 'component' || tag === 'Component';
15007 }
15008
15009 const transformSlotOutlet = (node, context) => {
15010 if (isSlotOutlet(node)) {
15011 const { children, loc } = node;
15012 const { slotName, slotProps } = processSlotOutlet(node, context);
15013 const slotArgs = [
15014 context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
15015 slotName,
15016 '{}',
15017 'undefined',
15018 'true'
15019 ];
15020 let expectedLen = 2;
15021 if (slotProps) {
15022 slotArgs[2] = slotProps;
15023 expectedLen = 3;
15024 }
15025 if (children.length) {
15026 slotArgs[3] = createFunctionExpression([], children, false, false, loc);
15027 expectedLen = 4;
15028 }
15029 if (context.scopeId && !context.slotted) {
15030 expectedLen = 5;
15031 }
15032 slotArgs.splice(expectedLen); // remove unused arguments
15033 node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
15034 }
15035 };
15036 function processSlotOutlet(node, context) {
15037 let slotName = `"default"`;
15038 let slotProps = undefined;
15039 const nonNameProps = [];
15040 for (let i = 0; i < node.props.length; i++) {
15041 const p = node.props[i];
15042 if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
15043 if (p.value) {
15044 if (p.name === 'name') {
15045 slotName = JSON.stringify(p.value.content);
15046 }
15047 else {
15048 p.name = camelize(p.name);
15049 nonNameProps.push(p);
15050 }
15051 }
15052 }
15053 else {
15054 if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
15055 if (p.exp)
15056 slotName = p.exp;
15057 }
15058 else {
15059 if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
15060 p.arg.content = camelize(p.arg.content);
15061 }
15062 nonNameProps.push(p);
15063 }
15064 }
15065 }
15066 if (nonNameProps.length > 0) {
15067 const { props, directives } = buildProps(node, context, nonNameProps, false, false);
15068 slotProps = props;
15069 if (directives.length) {
15070 context.onError(createCompilerError(36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
15071 }
15072 }
15073 return {
15074 slotName,
15075 slotProps
15076 };
15077 }
15078
15079 const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;
15080 const transformOn$1 = (dir, node, context, augmentor) => {
15081 const { loc, modifiers, arg } = dir;
15082 if (!dir.exp && !modifiers.length) {
15083 context.onError(createCompilerError(35 /* ErrorCodes.X_V_ON_NO_EXPRESSION */, loc));
15084 }
15085 let eventName;
15086 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15087 if (arg.isStatic) {
15088 let rawName = arg.content;
15089 // TODO deprecate @vnodeXXX usage
15090 if (rawName.startsWith('vue:')) {
15091 rawName = `vnode-${rawName.slice(4)}`;
15092 }
15093 const eventString = node.tagType !== 0 /* ElementTypes.ELEMENT */ ||
15094 rawName.startsWith('vnode') ||
15095 !/[A-Z]/.test(rawName)
15096 ? // for non-element and vnode lifecycle event listeners, auto convert
15097 // it to camelCase. See issue #2249
15098 toHandlerKey(camelize(rawName))
15099 : // preserve case for plain element listeners that have uppercase
15100 // letters, as these may be custom elements' custom events
15101 `on:${rawName}`;
15102 eventName = createSimpleExpression(eventString, true, arg.loc);
15103 }
15104 else {
15105 // #2388
15106 eventName = createCompoundExpression([
15107 `${context.helperString(TO_HANDLER_KEY)}(`,
15108 arg,
15109 `)`
15110 ]);
15111 }
15112 }
15113 else {
15114 // already a compound expression.
15115 eventName = arg;
15116 eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
15117 eventName.children.push(`)`);
15118 }
15119 // handler processing
15120 let exp = dir.exp;
15121 if (exp && !exp.content.trim()) {
15122 exp = undefined;
15123 }
15124 let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
15125 if (exp) {
15126 const isMemberExp = isMemberExpression(exp.content);
15127 const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
15128 const hasMultipleStatements = exp.content.includes(`;`);
15129 {
15130 validateBrowserExpression(exp, context, false, hasMultipleStatements);
15131 }
15132 if (isInlineStatement || (shouldCache && isMemberExp)) {
15133 // wrap inline statement in a function expression
15134 exp = createCompoundExpression([
15135 `${isInlineStatement
15136 ? `$event`
15137 : `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
15138 exp,
15139 hasMultipleStatements ? `}` : `)`
15140 ]);
15141 }
15142 }
15143 let ret = {
15144 props: [
15145 createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
15146 ]
15147 };
15148 // apply extended compiler augmentor
15149 if (augmentor) {
15150 ret = augmentor(ret);
15151 }
15152 if (shouldCache) {
15153 // cache handlers so that it's always the same handler being passed down.
15154 // this avoids unnecessary re-renders when users use inline handlers on
15155 // components.
15156 ret.props[0].value = context.cache(ret.props[0].value);
15157 }
15158 // mark the key as handler for props normalization check
15159 ret.props.forEach(p => (p.key.isHandlerKey = true));
15160 return ret;
15161 };
15162
15163 // v-bind without arg is handled directly in ./transformElements.ts due to it affecting
15164 // codegen for the entire props object. This transform here is only for v-bind
15165 // *with* args.
15166 const transformBind = (dir, _node, context) => {
15167 const { exp, modifiers, loc } = dir;
15168 const arg = dir.arg;
15169 if (arg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15170 arg.children.unshift(`(`);
15171 arg.children.push(`) || ""`);
15172 }
15173 else if (!arg.isStatic) {
15174 arg.content = `${arg.content} || ""`;
15175 }
15176 // .sync is replaced by v-model:arg
15177 if (modifiers.includes('camel')) {
15178 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15179 if (arg.isStatic) {
15180 arg.content = camelize(arg.content);
15181 }
15182 else {
15183 arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
15184 }
15185 }
15186 else {
15187 arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
15188 arg.children.push(`)`);
15189 }
15190 }
15191 if (!context.inSSR) {
15192 if (modifiers.includes('prop')) {
15193 injectPrefix(arg, '.');
15194 }
15195 if (modifiers.includes('attr')) {
15196 injectPrefix(arg, '^');
15197 }
15198 }
15199 if (!exp ||
15200 (exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && !exp.content.trim())) {
15201 context.onError(createCompilerError(34 /* ErrorCodes.X_V_BIND_NO_EXPRESSION */, loc));
15202 return {
15203 props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
15204 };
15205 }
15206 return {
15207 props: [createObjectProperty(arg, exp)]
15208 };
15209 };
15210 const injectPrefix = (arg, prefix) => {
15211 if (arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
15212 if (arg.isStatic) {
15213 arg.content = prefix + arg.content;
15214 }
15215 else {
15216 arg.content = `\`${prefix}\${${arg.content}}\``;
15217 }
15218 }
15219 else {
15220 arg.children.unshift(`'${prefix}' + (`);
15221 arg.children.push(`)`);
15222 }
15223 };
15224
15225 // Merge adjacent text nodes and expressions into a single expression
15226 // e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
15227 const transformText = (node, context) => {
15228 if (node.type === 0 /* NodeTypes.ROOT */ ||
15229 node.type === 1 /* NodeTypes.ELEMENT */ ||
15230 node.type === 11 /* NodeTypes.FOR */ ||
15231 node.type === 10 /* NodeTypes.IF_BRANCH */) {
15232 // perform the transform on node exit so that all expressions have already
15233 // been processed.
15234 return () => {
15235 const children = node.children;
15236 let currentContainer = undefined;
15237 let hasText = false;
15238 for (let i = 0; i < children.length; i++) {
15239 const child = children[i];
15240 if (isText$1(child)) {
15241 hasText = true;
15242 for (let j = i + 1; j < children.length; j++) {
15243 const next = children[j];
15244 if (isText$1(next)) {
15245 if (!currentContainer) {
15246 currentContainer = children[i] = createCompoundExpression([child], child.loc);
15247 }
15248 // merge adjacent text node into current
15249 currentContainer.children.push(` + `, next);
15250 children.splice(j, 1);
15251 j--;
15252 }
15253 else {
15254 currentContainer = undefined;
15255 break;
15256 }
15257 }
15258 }
15259 }
15260 if (!hasText ||
15261 // if this is a plain element with a single text child, leave it
15262 // as-is since the runtime has dedicated fast path for this by directly
15263 // setting textContent of the element.
15264 // for component root it's always normalized anyway.
15265 (children.length === 1 &&
15266 (node.type === 0 /* NodeTypes.ROOT */ ||
15267 (node.type === 1 /* NodeTypes.ELEMENT */ &&
15268 node.tagType === 0 /* ElementTypes.ELEMENT */ &&
15269 // #3756
15270 // custom directives can potentially add DOM elements arbitrarily,
15271 // we need to avoid setting textContent of the element at runtime
15272 // to avoid accidentally overwriting the DOM elements added
15273 // by the user through custom directives.
15274 !node.props.find(p => p.type === 7 /* NodeTypes.DIRECTIVE */ &&
15275 !context.directiveTransforms[p.name]) &&
15276 // in compat mode, <template> tags with no special directives
15277 // will be rendered as a fragment so its children must be
15278 // converted into vnodes.
15279 !(false ))))) {
15280 return;
15281 }
15282 // pre-convert text nodes into createTextVNode(text) calls to avoid
15283 // runtime normalization.
15284 for (let i = 0; i < children.length; i++) {
15285 const child = children[i];
15286 if (isText$1(child) || child.type === 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
15287 const callArgs = [];
15288 // createTextVNode defaults to single whitespace, so if it is a
15289 // single space the code could be an empty call to save bytes.
15290 if (child.type !== 2 /* NodeTypes.TEXT */ || child.content !== ' ') {
15291 callArgs.push(child);
15292 }
15293 // mark dynamic text with flag so it gets patched inside a block
15294 if (!context.ssr &&
15295 getConstantType(child, context) === 0 /* ConstantTypes.NOT_CONSTANT */) {
15296 callArgs.push(1 /* PatchFlags.TEXT */ +
15297 (` /* ${PatchFlagNames[1 /* PatchFlags.TEXT */]} */` ));
15298 }
15299 children[i] = {
15300 type: 12 /* NodeTypes.TEXT_CALL */,
15301 content: child,
15302 loc: child.loc,
15303 codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
15304 };
15305 }
15306 }
15307 };
15308 }
15309 };
15310
15311 const seen$1 = new WeakSet();
15312 const transformOnce = (node, context) => {
15313 if (node.type === 1 /* NodeTypes.ELEMENT */ && findDir(node, 'once', true)) {
15314 if (seen$1.has(node) || context.inVOnce) {
15315 return;
15316 }
15317 seen$1.add(node);
15318 context.inVOnce = true;
15319 context.helper(SET_BLOCK_TRACKING);
15320 return () => {
15321 context.inVOnce = false;
15322 const cur = context.currentNode;
15323 if (cur.codegenNode) {
15324 cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
15325 }
15326 };
15327 }
15328 };
15329
15330 const transformModel$1 = (dir, node, context) => {
15331 const { exp, arg } = dir;
15332 if (!exp) {
15333 context.onError(createCompilerError(41 /* ErrorCodes.X_V_MODEL_NO_EXPRESSION */, dir.loc));
15334 return createTransformProps();
15335 }
15336 const rawExp = exp.loc.source;
15337 const expString = exp.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ ? exp.content : rawExp;
15338 // im SFC <script setup> inline mode, the exp may have been transformed into
15339 // _unref(exp)
15340 const bindingType = context.bindingMetadata[rawExp];
15341 // check props
15342 if (bindingType === "props" /* BindingTypes.PROPS */ ||
15343 bindingType === "props-aliased" /* BindingTypes.PROPS_ALIASED */) {
15344 context.onError(createCompilerError(44 /* ErrorCodes.X_V_MODEL_ON_PROPS */, exp.loc));
15345 return createTransformProps();
15346 }
15347 const maybeRef = !true ;
15348 if (!expString.trim() ||
15349 (!isMemberExpression(expString) && !maybeRef)) {
15350 context.onError(createCompilerError(42 /* ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
15351 return createTransformProps();
15352 }
15353 const propName = arg ? arg : createSimpleExpression('modelValue', true);
15354 const eventName = arg
15355 ? isStaticExp(arg)
15356 ? `onUpdate:${camelize(arg.content)}`
15357 : createCompoundExpression(['"onUpdate:" + ', arg])
15358 : `onUpdate:modelValue`;
15359 let assignmentExp;
15360 const eventArg = context.isTS ? `($event: any)` : `$event`;
15361 {
15362 assignmentExp = createCompoundExpression([
15363 `${eventArg} => ((`,
15364 exp,
15365 `) = $event)`
15366 ]);
15367 }
15368 const props = [
15369 // modelValue: foo
15370 createObjectProperty(propName, dir.exp),
15371 // "onUpdate:modelValue": $event => (foo = $event)
15372 createObjectProperty(eventName, assignmentExp)
15373 ];
15374 // modelModifiers: { foo: true, "bar-baz": true }
15375 if (dir.modifiers.length && node.tagType === 1 /* ElementTypes.COMPONENT */) {
15376 const modifiers = dir.modifiers
15377 .map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
15378 .join(`, `);
15379 const modifiersKey = arg
15380 ? isStaticExp(arg)
15381 ? `${arg.content}Modifiers`
15382 : createCompoundExpression([arg, ' + "Modifiers"'])
15383 : `modelModifiers`;
15384 props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* ConstantTypes.CAN_HOIST */)));
15385 }
15386 return createTransformProps(props);
15387 };
15388 function createTransformProps(props = []) {
15389 return { props };
15390 }
15391
15392 const seen = new WeakSet();
15393 const transformMemo = (node, context) => {
15394 if (node.type === 1 /* NodeTypes.ELEMENT */) {
15395 const dir = findDir(node, 'memo');
15396 if (!dir || seen.has(node)) {
15397 return;
15398 }
15399 seen.add(node);
15400 return () => {
15401 const codegenNode = node.codegenNode ||
15402 context.currentNode.codegenNode;
15403 if (codegenNode && codegenNode.type === 13 /* NodeTypes.VNODE_CALL */) {
15404 // non-component sub tree should be turned into a block
15405 if (node.tagType !== 1 /* ElementTypes.COMPONENT */) {
15406 makeBlock(codegenNode, context);
15407 }
15408 node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
15409 dir.exp,
15410 createFunctionExpression(undefined, codegenNode),
15411 `_cache`,
15412 String(context.cached++)
15413 ]);
15414 }
15415 };
15416 }
15417 };
15418
15419 function getBaseTransformPreset(prefixIdentifiers) {
15420 return [
15421 [
15422 transformOnce,
15423 transformIf,
15424 transformMemo,
15425 transformFor,
15426 ...([]),
15427 ...([transformExpression]
15428 ),
15429 transformSlotOutlet,
15430 transformElement,
15431 trackSlotScopes,
15432 transformText
15433 ],
15434 {
15435 on: transformOn$1,
15436 bind: transformBind,
15437 model: transformModel$1
15438 }
15439 ];
15440 }
15441 // we name it `baseCompile` so that higher order compilers like
15442 // @vue/compiler-dom can export `compile` while re-exporting everything else.
15443 function baseCompile(template, options = {}) {
15444 const onError = options.onError || defaultOnError;
15445 const isModuleMode = options.mode === 'module';
15446 /* istanbul ignore if */
15447 {
15448 if (options.prefixIdentifiers === true) {
15449 onError(createCompilerError(47 /* ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED */));
15450 }
15451 else if (isModuleMode) {
15452 onError(createCompilerError(48 /* ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED */));
15453 }
15454 }
15455 const prefixIdentifiers = !true ;
15456 if (options.cacheHandlers) {
15457 onError(createCompilerError(49 /* ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED */));
15458 }
15459 if (options.scopeId && !isModuleMode) {
15460 onError(createCompilerError(50 /* ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED */));
15461 }
15462 const ast = isString(template) ? baseParse(template, options) : template;
15463 const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
15464 transform(ast, extend({}, options, {
15465 prefixIdentifiers,
15466 nodeTransforms: [
15467 ...nodeTransforms,
15468 ...(options.nodeTransforms || []) // user transforms
15469 ],
15470 directiveTransforms: extend({}, directiveTransforms, options.directiveTransforms || {} // user transforms
15471 )
15472 }));
15473 return generate(ast, extend({}, options, {
15474 prefixIdentifiers
15475 }));
15476 }
15477
15478 const noopDirectiveTransform = () => ({ props: [] });
15479
15480 const V_MODEL_RADIO = Symbol(`vModelRadio` );
15481 const V_MODEL_CHECKBOX = Symbol(`vModelCheckbox` );
15482 const V_MODEL_TEXT = Symbol(`vModelText` );
15483 const V_MODEL_SELECT = Symbol(`vModelSelect` );
15484 const V_MODEL_DYNAMIC = Symbol(`vModelDynamic` );
15485 const V_ON_WITH_MODIFIERS = Symbol(`vOnModifiersGuard` );
15486 const V_ON_WITH_KEYS = Symbol(`vOnKeysGuard` );
15487 const V_SHOW = Symbol(`vShow` );
15488 const TRANSITION = Symbol(`Transition` );
15489 const TRANSITION_GROUP = Symbol(`TransitionGroup` );
15490 registerRuntimeHelpers({
15491 [V_MODEL_RADIO]: `vModelRadio`,
15492 [V_MODEL_CHECKBOX]: `vModelCheckbox`,
15493 [V_MODEL_TEXT]: `vModelText`,
15494 [V_MODEL_SELECT]: `vModelSelect`,
15495 [V_MODEL_DYNAMIC]: `vModelDynamic`,
15496 [V_ON_WITH_MODIFIERS]: `withModifiers`,
15497 [V_ON_WITH_KEYS]: `withKeys`,
15498 [V_SHOW]: `vShow`,
15499 [TRANSITION]: `Transition`,
15500 [TRANSITION_GROUP]: `TransitionGroup`
15501 });
15502
15503 /* eslint-disable no-restricted-globals */
15504 let decoder;
15505 function decodeHtmlBrowser(raw, asAttr = false) {
15506 if (!decoder) {
15507 decoder = document.createElement('div');
15508 }
15509 if (asAttr) {
15510 decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`;
15511 return decoder.children[0].getAttribute('foo');
15512 }
15513 else {
15514 decoder.innerHTML = raw;
15515 return decoder.textContent;
15516 }
15517 }
15518
15519 const isRawTextContainer = /*#__PURE__*/ makeMap('style,iframe,script,noscript', true);
15520 const parserOptions = {
15521 isVoidTag,
15522 isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
15523 isPreTag: tag => tag === 'pre',
15524 decodeEntities: decodeHtmlBrowser ,
15525 isBuiltInComponent: (tag) => {
15526 if (isBuiltInType(tag, `Transition`)) {
15527 return TRANSITION;
15528 }
15529 else if (isBuiltInType(tag, `TransitionGroup`)) {
15530 return TRANSITION_GROUP;
15531 }
15532 },
15533 // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
15534 getNamespace(tag, parent) {
15535 let ns = parent ? parent.ns : 0 /* DOMNamespaces.HTML */;
15536 if (parent && ns === 2 /* DOMNamespaces.MATH_ML */) {
15537 if (parent.tag === 'annotation-xml') {
15538 if (tag === 'svg') {
15539 return 1 /* DOMNamespaces.SVG */;
15540 }
15541 if (parent.props.some(a => a.type === 6 /* NodeTypes.ATTRIBUTE */ &&
15542 a.name === 'encoding' &&
15543 a.value != null &&
15544 (a.value.content === 'text/html' ||
15545 a.value.content === 'application/xhtml+xml'))) {
15546 ns = 0 /* DOMNamespaces.HTML */;
15547 }
15548 }
15549 else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
15550 tag !== 'mglyph' &&
15551 tag !== 'malignmark') {
15552 ns = 0 /* DOMNamespaces.HTML */;
15553 }
15554 }
15555 else if (parent && ns === 1 /* DOMNamespaces.SVG */) {
15556 if (parent.tag === 'foreignObject' ||
15557 parent.tag === 'desc' ||
15558 parent.tag === 'title') {
15559 ns = 0 /* DOMNamespaces.HTML */;
15560 }
15561 }
15562 if (ns === 0 /* DOMNamespaces.HTML */) {
15563 if (tag === 'svg') {
15564 return 1 /* DOMNamespaces.SVG */;
15565 }
15566 if (tag === 'math') {
15567 return 2 /* DOMNamespaces.MATH_ML */;
15568 }
15569 }
15570 return ns;
15571 },
15572 // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
15573 getTextMode({ tag, ns }) {
15574 if (ns === 0 /* DOMNamespaces.HTML */) {
15575 if (tag === 'textarea' || tag === 'title') {
15576 return 1 /* TextModes.RCDATA */;
15577 }
15578 if (isRawTextContainer(tag)) {
15579 return 2 /* TextModes.RAWTEXT */;
15580 }
15581 }
15582 return 0 /* TextModes.DATA */;
15583 }
15584 };
15585
15586 // Parse inline CSS strings for static style attributes into an object.
15587 // This is a NodeTransform since it works on the static `style` attribute and
15588 // converts it into a dynamic equivalent:
15589 // style="color: red" -> :style='{ "color": "red" }'
15590 // It is then processed by `transformElement` and included in the generated
15591 // props.
15592 const transformStyle = node => {
15593 if (node.type === 1 /* NodeTypes.ELEMENT */) {
15594 node.props.forEach((p, i) => {
15595 if (p.type === 6 /* NodeTypes.ATTRIBUTE */ && p.name === 'style' && p.value) {
15596 // replace p with an expression node
15597 node.props[i] = {
15598 type: 7 /* NodeTypes.DIRECTIVE */,
15599 name: `bind`,
15600 arg: createSimpleExpression(`style`, true, p.loc),
15601 exp: parseInlineCSS(p.value.content, p.loc),
15602 modifiers: [],
15603 loc: p.loc
15604 };
15605 }
15606 });
15607 }
15608 };
15609 const parseInlineCSS = (cssText, loc) => {
15610 const normalized = parseStringStyle(cssText);
15611 return createSimpleExpression(JSON.stringify(normalized), false, loc, 3 /* ConstantTypes.CAN_STRINGIFY */);
15612 };
15613
15614 function createDOMCompilerError(code, loc) {
15615 return createCompilerError(code, loc, DOMErrorMessages );
15616 }
15617 const DOMErrorMessages = {
15618 [51 /* DOMErrorCodes.X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
15619 [52 /* DOMErrorCodes.X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
15620 [53 /* DOMErrorCodes.X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
15621 [54 /* DOMErrorCodes.X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
15622 [55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
15623 [56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
15624 [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.`,
15625 [58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
15626 [59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
15627 [60 /* DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
15628 [61 /* DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
15629 };
15630
15631 const transformVHtml = (dir, node, context) => {
15632 const { exp, loc } = dir;
15633 if (!exp) {
15634 context.onError(createDOMCompilerError(51 /* DOMErrorCodes.X_V_HTML_NO_EXPRESSION */, loc));
15635 }
15636 if (node.children.length) {
15637 context.onError(createDOMCompilerError(52 /* DOMErrorCodes.X_V_HTML_WITH_CHILDREN */, loc));
15638 node.children.length = 0;
15639 }
15640 return {
15641 props: [
15642 createObjectProperty(createSimpleExpression(`innerHTML`, true, loc), exp || createSimpleExpression('', true))
15643 ]
15644 };
15645 };
15646
15647 const transformVText = (dir, node, context) => {
15648 const { exp, loc } = dir;
15649 if (!exp) {
15650 context.onError(createDOMCompilerError(53 /* DOMErrorCodes.X_V_TEXT_NO_EXPRESSION */, loc));
15651 }
15652 if (node.children.length) {
15653 context.onError(createDOMCompilerError(54 /* DOMErrorCodes.X_V_TEXT_WITH_CHILDREN */, loc));
15654 node.children.length = 0;
15655 }
15656 return {
15657 props: [
15658 createObjectProperty(createSimpleExpression(`textContent`, true), exp
15659 ? getConstantType(exp, context) > 0
15660 ? exp
15661 : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
15662 : createSimpleExpression('', true))
15663 ]
15664 };
15665 };
15666
15667 const transformModel = (dir, node, context) => {
15668 const baseResult = transformModel$1(dir, node, context);
15669 // base transform has errors OR component v-model (only need props)
15670 if (!baseResult.props.length || node.tagType === 1 /* ElementTypes.COMPONENT */) {
15671 return baseResult;
15672 }
15673 if (dir.arg) {
15674 context.onError(createDOMCompilerError(56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
15675 }
15676 function checkDuplicatedValue() {
15677 const value = findProp(node, 'value');
15678 if (value) {
15679 context.onError(createDOMCompilerError(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
15680 }
15681 }
15682 const { tag } = node;
15683 const isCustomElement = context.isCustomElement(tag);
15684 if (tag === 'input' ||
15685 tag === 'textarea' ||
15686 tag === 'select' ||
15687 isCustomElement) {
15688 let directiveToUse = V_MODEL_TEXT;
15689 let isInvalidType = false;
15690 if (tag === 'input' || isCustomElement) {
15691 const type = findProp(node, `type`);
15692 if (type) {
15693 if (type.type === 7 /* NodeTypes.DIRECTIVE */) {
15694 // :type="foo"
15695 directiveToUse = V_MODEL_DYNAMIC;
15696 }
15697 else if (type.value) {
15698 switch (type.value.content) {
15699 case 'radio':
15700 directiveToUse = V_MODEL_RADIO;
15701 break;
15702 case 'checkbox':
15703 directiveToUse = V_MODEL_CHECKBOX;
15704 break;
15705 case 'file':
15706 isInvalidType = true;
15707 context.onError(createDOMCompilerError(57 /* DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
15708 break;
15709 default:
15710 // text type
15711 checkDuplicatedValue();
15712 break;
15713 }
15714 }
15715 }
15716 else if (hasDynamicKeyVBind(node)) {
15717 // element has bindings with dynamic keys, which can possibly contain
15718 // "type".
15719 directiveToUse = V_MODEL_DYNAMIC;
15720 }
15721 else {
15722 // text type
15723 checkDuplicatedValue();
15724 }
15725 }
15726 else if (tag === 'select') {
15727 directiveToUse = V_MODEL_SELECT;
15728 }
15729 else {
15730 // textarea
15731 checkDuplicatedValue();
15732 }
15733 // inject runtime directive
15734 // by returning the helper symbol via needRuntime
15735 // the import will replaced a resolveDirective call.
15736 if (!isInvalidType) {
15737 baseResult.needRuntime = context.helper(directiveToUse);
15738 }
15739 }
15740 else {
15741 context.onError(createDOMCompilerError(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
15742 }
15743 // native vmodel doesn't need the `modelValue` props since they are also
15744 // passed to the runtime as `binding.value`. removing it reduces code size.
15745 baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
15746 p.key.content === 'modelValue'));
15747 return baseResult;
15748 };
15749
15750 const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`);
15751 const isNonKeyModifier = /*#__PURE__*/ makeMap(
15752 // event propagation management
15753`stop,prevent,self,` +
15754 // system modifiers + exact
15755 `ctrl,shift,alt,meta,exact,` +
15756 // mouse
15757 `middle`);
15758 // left & right could be mouse or key modifiers based on event type
15759 const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right');
15760 const isKeyboardEvent = /*#__PURE__*/ makeMap(`onkeyup,onkeydown,onkeypress`, true);
15761 const resolveModifiers = (key, modifiers, context, loc) => {
15762 const keyModifiers = [];
15763 const nonKeyModifiers = [];
15764 const eventOptionModifiers = [];
15765 for (let i = 0; i < modifiers.length; i++) {
15766 const modifier = modifiers[i];
15767 if (isEventOptionModifier(modifier)) {
15768 // eventOptionModifiers: modifiers for addEventListener() options,
15769 // e.g. .passive & .capture
15770 eventOptionModifiers.push(modifier);
15771 }
15772 else {
15773 // runtimeModifiers: modifiers that needs runtime guards
15774 if (maybeKeyModifier(modifier)) {
15775 if (isStaticExp(key)) {
15776 if (isKeyboardEvent(key.content)) {
15777 keyModifiers.push(modifier);
15778 }
15779 else {
15780 nonKeyModifiers.push(modifier);
15781 }
15782 }
15783 else {
15784 keyModifiers.push(modifier);
15785 nonKeyModifiers.push(modifier);
15786 }
15787 }
15788 else {
15789 if (isNonKeyModifier(modifier)) {
15790 nonKeyModifiers.push(modifier);
15791 }
15792 else {
15793 keyModifiers.push(modifier);
15794 }
15795 }
15796 }
15797 }
15798 return {
15799 keyModifiers,
15800 nonKeyModifiers,
15801 eventOptionModifiers
15802 };
15803 };
15804 const transformClick = (key, event) => {
15805 const isStaticClick = isStaticExp(key) && key.content.toLowerCase() === 'onclick';
15806 return isStaticClick
15807 ? createSimpleExpression(event, true)
15808 : key.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */
15809 ? createCompoundExpression([
15810 `(`,
15811 key,
15812 `) === "onClick" ? "${event}" : (`,
15813 key,
15814 `)`
15815 ])
15816 : key;
15817 };
15818 const transformOn = (dir, node, context) => {
15819 return transformOn$1(dir, node, context, baseResult => {
15820 const { modifiers } = dir;
15821 if (!modifiers.length)
15822 return baseResult;
15823 let { key, value: handlerExp } = baseResult.props[0];
15824 const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
15825 // normalize click.right and click.middle since they don't actually fire
15826 if (nonKeyModifiers.includes('right')) {
15827 key = transformClick(key, `onContextmenu`);
15828 }
15829 if (nonKeyModifiers.includes('middle')) {
15830 key = transformClick(key, `onMouseup`);
15831 }
15832 if (nonKeyModifiers.length) {
15833 handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
15834 handlerExp,
15835 JSON.stringify(nonKeyModifiers)
15836 ]);
15837 }
15838 if (keyModifiers.length &&
15839 // if event name is dynamic, always wrap with keys guard
15840 (!isStaticExp(key) || isKeyboardEvent(key.content))) {
15841 handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
15842 handlerExp,
15843 JSON.stringify(keyModifiers)
15844 ]);
15845 }
15846 if (eventOptionModifiers.length) {
15847 const modifierPostfix = eventOptionModifiers.map(capitalize).join('');
15848 key = isStaticExp(key)
15849 ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
15850 : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`]);
15851 }
15852 return {
15853 props: [createObjectProperty(key, handlerExp)]
15854 };
15855 });
15856 };
15857
15858 const transformShow = (dir, node, context) => {
15859 const { exp, loc } = dir;
15860 if (!exp) {
15861 context.onError(createDOMCompilerError(59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */, loc));
15862 }
15863 return {
15864 props: [],
15865 needRuntime: context.helper(V_SHOW)
15866 };
15867 };
15868
15869 const transformTransition = (node, context) => {
15870 if (node.type === 1 /* NodeTypes.ELEMENT */ &&
15871 node.tagType === 1 /* ElementTypes.COMPONENT */) {
15872 const component = context.isBuiltInComponent(node.tag);
15873 if (component === TRANSITION) {
15874 return () => {
15875 if (!node.children.length) {
15876 return;
15877 }
15878 // warn multiple transition children
15879 if (hasMultipleChildren(node)) {
15880 context.onError(createDOMCompilerError(60 /* DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN */, {
15881 start: node.children[0].loc.start,
15882 end: node.children[node.children.length - 1].loc.end,
15883 source: ''
15884 }));
15885 }
15886 // check if it's s single child w/ v-show
15887 // if yes, inject "persisted: true" to the transition props
15888 const child = node.children[0];
15889 if (child.type === 1 /* NodeTypes.ELEMENT */) {
15890 for (const p of child.props) {
15891 if (p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'show') {
15892 node.props.push({
15893 type: 6 /* NodeTypes.ATTRIBUTE */,
15894 name: 'persisted',
15895 value: undefined,
15896 loc: node.loc
15897 });
15898 }
15899 }
15900 }
15901 };
15902 }
15903 }
15904 };
15905 function hasMultipleChildren(node) {
15906 // #1352 filter out potential comment nodes.
15907 const children = (node.children = node.children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */ &&
15908 !(c.type === 2 /* NodeTypes.TEXT */ && !c.content.trim())));
15909 const child = children[0];
15910 return (children.length !== 1 ||
15911 child.type === 11 /* NodeTypes.FOR */ ||
15912 (child.type === 9 /* NodeTypes.IF */ && child.branches.some(hasMultipleChildren)));
15913 }
15914
15915 const ignoreSideEffectTags = (node, context) => {
15916 if (node.type === 1 /* NodeTypes.ELEMENT */ &&
15917 node.tagType === 0 /* ElementTypes.ELEMENT */ &&
15918 (node.tag === 'script' || node.tag === 'style')) {
15919 context.onError(createDOMCompilerError(61 /* DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
15920 context.removeNode();
15921 }
15922 };
15923
15924 const DOMNodeTransforms = [
15925 transformStyle,
15926 ...([transformTransition] )
15927 ];
15928 const DOMDirectiveTransforms = {
15929 cloak: noopDirectiveTransform,
15930 html: transformVHtml,
15931 text: transformVText,
15932 model: transformModel,
15933 on: transformOn,
15934 show: transformShow
15935 };
15936 function compile(template, options = {}) {
15937 return baseCompile(template, extend({}, parserOptions, options, {
15938 nodeTransforms: [
15939 // ignore <script> and <tag>
15940 // this is not put inside DOMNodeTransforms because that list is used
15941 // by compiler-ssr to generate vnode fallback branches
15942 ignoreSideEffectTags,
15943 ...DOMNodeTransforms,
15944 ...(options.nodeTransforms || [])
15945 ],
15946 directiveTransforms: extend({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
15947 transformHoist: null
15948 }));
15949 }
15950
15951 // This entry is the "full-build" that includes both the runtime
15952 {
15953 initDev();
15954 }
15955 const compileCache = Object.create(null);
15956 function compileToFunction(template, options) {
15957 if (!isString(template)) {
15958 if (template.nodeType) {
15959 template = template.innerHTML;
15960 }
15961 else {
15962 warn(`invalid template option: `, template);
15963 return NOOP;
15964 }
15965 }
15966 const key = template;
15967 const cached = compileCache[key];
15968 if (cached) {
15969 return cached;
15970 }
15971 if (template[0] === '#') {
15972 const el = document.querySelector(template);
15973 if (!el) {
15974 warn(`Template element not found or is empty: ${template}`);
15975 }
15976 // __UNSAFE__
15977 // Reason: potential execution of JS expressions in in-DOM template.
15978 // The user must make sure the in-DOM template is trusted. If it's rendered
15979 // by the server, the template should not contain any user data.
15980 template = el ? el.innerHTML : ``;
15981 }
15982 const opts = extend({
15983 hoistStatic: true,
15984 onError: onError ,
15985 onWarn: e => onError(e, true)
15986 }, options);
15987 if (!opts.isCustomElement && typeof customElements !== 'undefined') {
15988 opts.isCustomElement = tag => !!customElements.get(tag);
15989 }
15990 const { code } = compile(template, opts);
15991 function onError(err, asWarning = false) {
15992 const message = asWarning
15993 ? err.message
15994 : `Template compilation error: ${err.message}`;
15995 const codeFrame = err.loc &&
15996 generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
15997 warn(codeFrame ? `${message}\n${codeFrame}` : message);
15998 }
15999 // The wildcard import results in a huge object with every export
16000 // with keys that cannot be mangled, and can be quite heavy size-wise.
16001 // In the global build we know `Vue` is available globally so we can avoid
16002 // the wildcard object.
16003 const render = (new Function(code)() );
16004 render._rc = true;
16005 return (compileCache[key] = render);
16006 }
16007 registerRuntimeCompiler(compileToFunction);
16008
16009 exports.BaseTransition = BaseTransition;
16010 exports.Comment = Comment;
16011 exports.EffectScope = EffectScope;
16012 exports.Fragment = Fragment;
16013 exports.KeepAlive = KeepAlive;
16014 exports.ReactiveEffect = ReactiveEffect;
16015 exports.Static = Static;
16016 exports.Suspense = Suspense;
16017 exports.Teleport = Teleport;
16018 exports.Text = Text;
16019 exports.Transition = Transition;
16020 exports.TransitionGroup = TransitionGroup;
16021 exports.VueElement = VueElement;
16022 exports.assertNumber = assertNumber;
16023 exports.callWithAsyncErrorHandling = callWithAsyncErrorHandling;
16024 exports.callWithErrorHandling = callWithErrorHandling;
16025 exports.camelize = camelize;
16026 exports.capitalize = capitalize;
16027 exports.cloneVNode = cloneVNode;
16028 exports.compatUtils = compatUtils;
16029 exports.compile = compileToFunction;
16030 exports.computed = computed;
16031 exports.createApp = createApp;
16032 exports.createBlock = createBlock;
16033 exports.createCommentVNode = createCommentVNode;
16034 exports.createElementBlock = createElementBlock;
16035 exports.createElementVNode = createBaseVNode;
16036 exports.createHydrationRenderer = createHydrationRenderer;
16037 exports.createPropsRestProxy = createPropsRestProxy;
16038 exports.createRenderer = createRenderer;
16039 exports.createSSRApp = createSSRApp;
16040 exports.createSlots = createSlots;
16041 exports.createStaticVNode = createStaticVNode;
16042 exports.createTextVNode = createTextVNode;
16043 exports.createVNode = createVNode;
16044 exports.customRef = customRef;
16045 exports.defineAsyncComponent = defineAsyncComponent;
16046 exports.defineComponent = defineComponent;
16047 exports.defineCustomElement = defineCustomElement;
16048 exports.defineEmits = defineEmits;
16049 exports.defineExpose = defineExpose;
16050 exports.defineProps = defineProps;
16051 exports.defineSSRCustomElement = defineSSRCustomElement;
16052 exports.effect = effect;
16053 exports.effectScope = effectScope;
16054 exports.getCurrentInstance = getCurrentInstance;
16055 exports.getCurrentScope = getCurrentScope;
16056 exports.getTransitionRawChildren = getTransitionRawChildren;
16057 exports.guardReactiveProps = guardReactiveProps;
16058 exports.h = h;
16059 exports.handleError = handleError;
16060 exports.hydrate = hydrate;
16061 exports.initCustomFormatter = initCustomFormatter;
16062 exports.initDirectivesForSSR = initDirectivesForSSR;
16063 exports.inject = inject;
16064 exports.isMemoSame = isMemoSame;
16065 exports.isProxy = isProxy;
16066 exports.isReactive = isReactive;
16067 exports.isReadonly = isReadonly;
16068 exports.isRef = isRef;
16069 exports.isRuntimeOnly = isRuntimeOnly;
16070 exports.isShallow = isShallow;
16071 exports.isVNode = isVNode;
16072 exports.markRaw = markRaw;
16073 exports.mergeDefaults = mergeDefaults;
16074 exports.mergeProps = mergeProps;
16075 exports.nextTick = nextTick;
16076 exports.normalizeClass = normalizeClass;
16077 exports.normalizeProps = normalizeProps;
16078 exports.normalizeStyle = normalizeStyle;
16079 exports.onActivated = onActivated;
16080 exports.onBeforeMount = onBeforeMount;
16081 exports.onBeforeUnmount = onBeforeUnmount;
16082 exports.onBeforeUpdate = onBeforeUpdate;
16083 exports.onDeactivated = onDeactivated;
16084 exports.onErrorCaptured = onErrorCaptured;
16085 exports.onMounted = onMounted;
16086 exports.onRenderTracked = onRenderTracked;
16087 exports.onRenderTriggered = onRenderTriggered;
16088 exports.onScopeDispose = onScopeDispose;
16089 exports.onServerPrefetch = onServerPrefetch;
16090 exports.onUnmounted = onUnmounted;
16091 exports.onUpdated = onUpdated;
16092 exports.openBlock = openBlock;
16093 exports.popScopeId = popScopeId;
16094 exports.provide = provide;
16095 exports.proxyRefs = proxyRefs;
16096 exports.pushScopeId = pushScopeId;
16097 exports.queuePostFlushCb = queuePostFlushCb;
16098 exports.reactive = reactive;
16099 exports.readonly = readonly;
16100 exports.ref = ref;
16101 exports.registerRuntimeCompiler = registerRuntimeCompiler;
16102 exports.render = render;
16103 exports.renderList = renderList;
16104 exports.renderSlot = renderSlot;
16105 exports.resolveComponent = resolveComponent;
16106 exports.resolveDirective = resolveDirective;
16107 exports.resolveDynamicComponent = resolveDynamicComponent;
16108 exports.resolveFilter = resolveFilter;
16109 exports.resolveTransitionHooks = resolveTransitionHooks;
16110 exports.setBlockTracking = setBlockTracking;
16111 exports.setDevtoolsHook = setDevtoolsHook;
16112 exports.setTransitionHooks = setTransitionHooks;
16113 exports.shallowReactive = shallowReactive;
16114 exports.shallowReadonly = shallowReadonly;
16115 exports.shallowRef = shallowRef;
16116 exports.ssrContextKey = ssrContextKey;
16117 exports.ssrUtils = ssrUtils;
16118 exports.stop = stop;
16119 exports.toDisplayString = toDisplayString;
16120 exports.toHandlerKey = toHandlerKey;
16121 exports.toHandlers = toHandlers;
16122 exports.toRaw = toRaw;
16123 exports.toRef = toRef;
16124 exports.toRefs = toRefs;
16125 exports.transformVNodeArgs = transformVNodeArgs;
16126 exports.triggerRef = triggerRef;
16127 exports.unref = unref;
16128 exports.useAttrs = useAttrs;
16129 exports.useCssModule = useCssModule;
16130 exports.useCssVars = useCssVars;
16131 exports.useSSRContext = useSSRContext;
16132 exports.useSlots = useSlots;
16133 exports.useTransitionState = useTransitionState;
16134 exports.vModelCheckbox = vModelCheckbox;
16135 exports.vModelDynamic = vModelDynamic;
16136 exports.vModelRadio = vModelRadio;
16137 exports.vModelSelect = vModelSelect;
16138 exports.vModelText = vModelText;
16139 exports.vShow = vShow;
16140 exports.version = version;
16141 exports.warn = warn;
16142 exports.watch = watch;
16143 exports.watchEffect = watchEffect;
16144 exports.watchPostEffect = watchPostEffect;
16145 exports.watchSyncEffect = watchSyncEffect;
16146 exports.withAsyncContext = withAsyncContext;
16147 exports.withCtx = withCtx;
16148 exports.withDefaults = withDefaults;
16149 exports.withDirectives = withDirectives;
16150 exports.withKeys = withKeys;
16151 exports.withMemo = withMemo;
16152 exports.withModifiers = withModifiers;
16153 exports.withScopeId = withScopeId;
16154
16155 Object.defineProperty(exports, '__esModule', { value: true });
16156
16157 return exports;
16158
16159})({});