UNPKG

314 kBJavaScriptView Raw
1/*!
2 * Vue.js v2.6.7
3 * (c) 2014-2019 Evan You
4 * Released under the MIT License.
5 */
6/* */
7
8const emptyObject = Object.freeze({});
9
10// These helpers produce better VM code in JS engines due to their
11// explicitness and function inlining.
12function isUndef (v) {
13 return v === undefined || v === null
14}
15
16function isDef (v) {
17 return v !== undefined && v !== null
18}
19
20function isTrue (v) {
21 return v === true
22}
23
24function isFalse (v) {
25 return v === false
26}
27
28/**
29 * Check if value is primitive.
30 */
31function isPrimitive (value) {
32 return (
33 typeof value === 'string' ||
34 typeof value === 'number' ||
35 // $flow-disable-line
36 typeof value === 'symbol' ||
37 typeof value === 'boolean'
38 )
39}
40
41/**
42 * Quick object check - this is primarily used to tell
43 * Objects from primitive values when we know the value
44 * is a JSON-compliant type.
45 */
46function isObject (obj) {
47 return obj !== null && typeof obj === 'object'
48}
49
50/**
51 * Get the raw type string of a value, e.g., [object Object].
52 */
53const _toString = Object.prototype.toString;
54
55function toRawType (value) {
56 return _toString.call(value).slice(8, -1)
57}
58
59/**
60 * Strict object type check. Only returns true
61 * for plain JavaScript objects.
62 */
63function isPlainObject (obj) {
64 return _toString.call(obj) === '[object Object]'
65}
66
67function isRegExp (v) {
68 return _toString.call(v) === '[object RegExp]'
69}
70
71/**
72 * Check if val is a valid array index.
73 */
74function isValidArrayIndex (val) {
75 const n = parseFloat(String(val));
76 return n >= 0 && Math.floor(n) === n && isFinite(val)
77}
78
79function isPromise (val) {
80 return (
81 isDef(val) &&
82 typeof val.then === 'function' &&
83 typeof val.catch === 'function'
84 )
85}
86
87/**
88 * Convert a value to a string that is actually rendered.
89 */
90function toString (val) {
91 return val == null
92 ? ''
93 : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
94 ? JSON.stringify(val, null, 2)
95 : String(val)
96}
97
98/**
99 * Convert an input value to a number for persistence.
100 * If the conversion fails, return original string.
101 */
102function toNumber (val) {
103 const n = parseFloat(val);
104 return isNaN(n) ? val : n
105}
106
107/**
108 * Make a map and return a function for checking if a key
109 * is in that map.
110 */
111function makeMap (
112 str,
113 expectsLowerCase
114) {
115 const map = Object.create(null);
116 const list = str.split(',');
117 for (let i = 0; i < list.length; i++) {
118 map[list[i]] = true;
119 }
120 return expectsLowerCase
121 ? val => map[val.toLowerCase()]
122 : val => map[val]
123}
124
125/**
126 * Check if a tag is a built-in tag.
127 */
128const isBuiltInTag = makeMap('slot,component', true);
129
130/**
131 * Check if an attribute is a reserved attribute.
132 */
133const isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');
134
135/**
136 * Remove an item from an array.
137 */
138function remove (arr, item) {
139 if (arr.length) {
140 const index = arr.indexOf(item);
141 if (index > -1) {
142 return arr.splice(index, 1)
143 }
144 }
145}
146
147/**
148 * Check whether an object has the property.
149 */
150const hasOwnProperty = Object.prototype.hasOwnProperty;
151function hasOwn (obj, key) {
152 return hasOwnProperty.call(obj, key)
153}
154
155/**
156 * Create a cached version of a pure function.
157 */
158function cached (fn) {
159 const cache = Object.create(null);
160 return (function cachedFn (str) {
161 const hit = cache[str];
162 return hit || (cache[str] = fn(str))
163 })
164}
165
166/**
167 * Camelize a hyphen-delimited string.
168 */
169const camelizeRE = /-(\w)/g;
170const camelize = cached((str) => {
171 return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
172});
173
174/**
175 * Capitalize a string.
176 */
177const capitalize = cached((str) => {
178 return str.charAt(0).toUpperCase() + str.slice(1)
179});
180
181/**
182 * Hyphenate a camelCase string.
183 */
184const hyphenateRE = /\B([A-Z])/g;
185const hyphenate = cached((str) => {
186 return str.replace(hyphenateRE, '-$1').toLowerCase()
187});
188
189/**
190 * Simple bind polyfill for environments that do not support it,
191 * e.g., PhantomJS 1.x. Technically, we don't need this anymore
192 * since native bind is now performant enough in most browsers.
193 * But removing it would mean breaking code that was able to run in
194 * PhantomJS 1.x, so this must be kept for backward compatibility.
195 */
196
197/* istanbul ignore next */
198function polyfillBind (fn, ctx) {
199 function boundFn (a) {
200 const l = arguments.length;
201 return l
202 ? l > 1
203 ? fn.apply(ctx, arguments)
204 : fn.call(ctx, a)
205 : fn.call(ctx)
206 }
207
208 boundFn._length = fn.length;
209 return boundFn
210}
211
212function nativeBind (fn, ctx) {
213 return fn.bind(ctx)
214}
215
216const bind = Function.prototype.bind
217 ? nativeBind
218 : polyfillBind;
219
220/**
221 * Convert an Array-like object to a real Array.
222 */
223function toArray (list, start) {
224 start = start || 0;
225 let i = list.length - start;
226 const ret = new Array(i);
227 while (i--) {
228 ret[i] = list[i + start];
229 }
230 return ret
231}
232
233/**
234 * Mix properties into target object.
235 */
236function extend (to, _from) {
237 for (const key in _from) {
238 to[key] = _from[key];
239 }
240 return to
241}
242
243/**
244 * Merge an Array of Objects into a single Object.
245 */
246function toObject (arr) {
247 const res = {};
248 for (let i = 0; i < arr.length; i++) {
249 if (arr[i]) {
250 extend(res, arr[i]);
251 }
252 }
253 return res
254}
255
256/* eslint-disable no-unused-vars */
257
258/**
259 * Perform no operation.
260 * Stubbing args to make Flow happy without leaving useless transpiled code
261 * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/).
262 */
263function noop (a, b, c) {}
264
265/**
266 * Always return false.
267 */
268const no = (a, b, c) => false;
269
270/* eslint-enable no-unused-vars */
271
272/**
273 * Return the same value.
274 */
275const identity = (_) => _;
276
277/**
278 * Generate a string containing static keys from compiler modules.
279 */
280function genStaticKeys (modules) {
281 return modules.reduce((keys, m) => {
282 return keys.concat(m.staticKeys || [])
283 }, []).join(',')
284}
285
286/**
287 * Check if two values are loosely equal - that is,
288 * if they are plain objects, do they have the same shape?
289 */
290function looseEqual (a, b) {
291 if (a === b) return true
292 const isObjectA = isObject(a);
293 const isObjectB = isObject(b);
294 if (isObjectA && isObjectB) {
295 try {
296 const isArrayA = Array.isArray(a);
297 const isArrayB = Array.isArray(b);
298 if (isArrayA && isArrayB) {
299 return a.length === b.length && a.every((e, i) => {
300 return looseEqual(e, b[i])
301 })
302 } else if (a instanceof Date && b instanceof Date) {
303 return a.getTime() === b.getTime()
304 } else if (!isArrayA && !isArrayB) {
305 const keysA = Object.keys(a);
306 const keysB = Object.keys(b);
307 return keysA.length === keysB.length && keysA.every(key => {
308 return looseEqual(a[key], b[key])
309 })
310 } else {
311 /* istanbul ignore next */
312 return false
313 }
314 } catch (e) {
315 /* istanbul ignore next */
316 return false
317 }
318 } else if (!isObjectA && !isObjectB) {
319 return String(a) === String(b)
320 } else {
321 return false
322 }
323}
324
325/**
326 * Return the first index at which a loosely equal value can be
327 * found in the array (if value is a plain object, the array must
328 * contain an object of the same shape), or -1 if it is not present.
329 */
330function looseIndexOf (arr, val) {
331 for (let i = 0; i < arr.length; i++) {
332 if (looseEqual(arr[i], val)) return i
333 }
334 return -1
335}
336
337/**
338 * Ensure a function is called only once.
339 */
340function once (fn) {
341 let called = false;
342 return function () {
343 if (!called) {
344 called = true;
345 fn.apply(this, arguments);
346 }
347 }
348}
349
350const SSR_ATTR = 'data-server-rendered';
351
352const ASSET_TYPES = [
353 'component',
354 'directive',
355 'filter'
356];
357
358const LIFECYCLE_HOOKS = [
359 'beforeCreate',
360 'created',
361 'beforeMount',
362 'mounted',
363 'beforeUpdate',
364 'updated',
365 'beforeDestroy',
366 'destroyed',
367 'activated',
368 'deactivated',
369 'errorCaptured',
370 'serverPrefetch'
371];
372
373/* */
374
375
376
377var config = ({
378 /**
379 * Option merge strategies (used in core/util/options)
380 */
381 // $flow-disable-line
382 optionMergeStrategies: Object.create(null),
383
384 /**
385 * Whether to suppress warnings.
386 */
387 silent: false,
388
389 /**
390 * Show production mode tip message on boot?
391 */
392 productionTip: "development" !== 'production',
393
394 /**
395 * Whether to enable devtools
396 */
397 devtools: "development" !== 'production',
398
399 /**
400 * Whether to record perf
401 */
402 performance: false,
403
404 /**
405 * Error handler for watcher errors
406 */
407 errorHandler: null,
408
409 /**
410 * Warn handler for watcher warns
411 */
412 warnHandler: null,
413
414 /**
415 * Ignore certain custom elements
416 */
417 ignoredElements: [],
418
419 /**
420 * Custom user key aliases for v-on
421 */
422 // $flow-disable-line
423 keyCodes: Object.create(null),
424
425 /**
426 * Check if a tag is reserved so that it cannot be registered as a
427 * component. This is platform-dependent and may be overwritten.
428 */
429 isReservedTag: no,
430
431 /**
432 * Check if an attribute is reserved so that it cannot be used as a component
433 * prop. This is platform-dependent and may be overwritten.
434 */
435 isReservedAttr: no,
436
437 /**
438 * Check if a tag is an unknown element.
439 * Platform-dependent.
440 */
441 isUnknownElement: no,
442
443 /**
444 * Get the namespace of an element
445 */
446 getTagNamespace: noop,
447
448 /**
449 * Parse the real tag name for the specific platform.
450 */
451 parsePlatformTagName: identity,
452
453 /**
454 * Check if an attribute must be bound using property, e.g. value
455 * Platform-dependent.
456 */
457 mustUseProp: no,
458
459 /**
460 * Perform updates asynchronously. Intended to be used by Vue Test Utils
461 * This will significantly reduce performance if set to false.
462 */
463 async: true,
464
465 /**
466 * Exposed for legacy reasons
467 */
468 _lifecycleHooks: LIFECYCLE_HOOKS
469});
470
471/* */
472
473/**
474 * unicode letters used for parsing html tags, component names and property paths.
475 * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
476 * skipping \u10000-\uEFFFF due to it freezing up PhantomJS
477 */
478const unicodeLetters = 'a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD';
479
480/**
481 * Check if a string starts with $ or _
482 */
483function isReserved (str) {
484 const c = (str + '').charCodeAt(0);
485 return c === 0x24 || c === 0x5F
486}
487
488/**
489 * Define a property.
490 */
491function def (obj, key, val, enumerable) {
492 Object.defineProperty(obj, key, {
493 value: val,
494 enumerable: !!enumerable,
495 writable: true,
496 configurable: true
497 });
498}
499
500/**
501 * Parse simple path.
502 */
503const bailRE = new RegExp(`[^${unicodeLetters}.$_\\d]`);
504function parsePath (path) {
505 if (bailRE.test(path)) {
506 return
507 }
508 const segments = path.split('.');
509 return function (obj) {
510 for (let i = 0; i < segments.length; i++) {
511 if (!obj) return
512 obj = obj[segments[i]];
513 }
514 return obj
515 }
516}
517
518/* */
519
520// can we use __proto__?
521const hasProto = '__proto__' in {};
522
523// Browser environment sniffing
524const inBrowser = typeof window !== 'undefined';
525const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
526const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
527const UA = inBrowser && window.navigator.userAgent.toLowerCase();
528const isIE = UA && /msie|trident/.test(UA);
529const isIE9 = UA && UA.indexOf('msie 9.0') > 0;
530const isEdge = UA && UA.indexOf('edge/') > 0;
531const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
532const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
533const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
534const isPhantomJS = UA && /phantomjs/.test(UA);
535const isFF = UA && UA.match(/firefox\/(\d+)/);
536
537// Firefox has a "watch" function on Object.prototype...
538const nativeWatch = ({}).watch;
539
540let supportsPassive = false;
541if (inBrowser) {
542 try {
543 const opts = {};
544 Object.defineProperty(opts, 'passive', ({
545 get () {
546 /* istanbul ignore next */
547 supportsPassive = true;
548 }
549 })); // https://github.com/facebook/flow/issues/285
550 window.addEventListener('test-passive', null, opts);
551 } catch (e) {}
552}
553
554// this needs to be lazy-evaled because vue may be required before
555// vue-server-renderer can set VUE_ENV
556let _isServer;
557const isServerRendering = () => {
558 if (_isServer === undefined) {
559 /* istanbul ignore if */
560 if (!inBrowser && !inWeex && typeof global !== 'undefined') {
561 // detect presence of vue-server-renderer and avoid
562 // Webpack shimming the process
563 _isServer = global['process'] && global['process'].env.VUE_ENV === 'server';
564 } else {
565 _isServer = false;
566 }
567 }
568 return _isServer
569};
570
571// detect devtools
572const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
573
574/* istanbul ignore next */
575function isNative (Ctor) {
576 return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
577}
578
579const hasSymbol =
580 typeof Symbol !== 'undefined' && isNative(Symbol) &&
581 typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);
582
583let _Set;
584/* istanbul ignore if */ // $flow-disable-line
585if (typeof Set !== 'undefined' && isNative(Set)) {
586 // use native Set when available.
587 _Set = Set;
588} else {
589 // a non-standard Set polyfill that only works with primitive keys.
590 _Set = class Set {
591
592 constructor () {
593 this.set = Object.create(null);
594 }
595 has (key) {
596 return this.set[key] === true
597 }
598 add (key) {
599 this.set[key] = true;
600 }
601 clear () {
602 this.set = Object.create(null);
603 }
604 };
605}
606
607/* */
608
609let warn = noop;
610let tip = noop;
611let generateComponentTrace = (noop); // work around flow check
612let formatComponentName = (noop);
613
614{
615 const hasConsole = typeof console !== 'undefined';
616 const classifyRE = /(?:^|[-_])(\w)/g;
617 const classify = str => str
618 .replace(classifyRE, c => c.toUpperCase())
619 .replace(/[-_]/g, '');
620
621 warn = (msg, vm) => {
622 const trace = vm ? generateComponentTrace(vm) : '';
623
624 if (config.warnHandler) {
625 config.warnHandler.call(null, msg, vm, trace);
626 } else if (hasConsole && (!config.silent)) {
627 console.error(`[Vue warn]: ${msg}${trace}`);
628 }
629 };
630
631 tip = (msg, vm) => {
632 if (hasConsole && (!config.silent)) {
633 console.warn(`[Vue tip]: ${msg}` + (
634 vm ? generateComponentTrace(vm) : ''
635 ));
636 }
637 };
638
639 formatComponentName = (vm, includeFile) => {
640 if (vm.$root === vm) {
641 return '<Root>'
642 }
643 const options = typeof vm === 'function' && vm.cid != null
644 ? vm.options
645 : vm._isVue
646 ? vm.$options || vm.constructor.options
647 : vm;
648 let name = options.name || options._componentTag;
649 const file = options.__file;
650 if (!name && file) {
651 const match = file.match(/([^/\\]+)\.vue$/);
652 name = match && match[1];
653 }
654
655 return (
656 (name ? `<${classify(name)}>` : `<Anonymous>`) +
657 (file && includeFile !== false ? ` at ${file}` : '')
658 )
659 };
660
661 const repeat = (str, n) => {
662 let res = '';
663 while (n) {
664 if (n % 2 === 1) res += str;
665 if (n > 1) str += str;
666 n >>= 1;
667 }
668 return res
669 };
670
671 generateComponentTrace = vm => {
672 if (vm._isVue && vm.$parent) {
673 const tree = [];
674 let currentRecursiveSequence = 0;
675 while (vm) {
676 if (tree.length > 0) {
677 const last = tree[tree.length - 1];
678 if (last.constructor === vm.constructor) {
679 currentRecursiveSequence++;
680 vm = vm.$parent;
681 continue
682 } else if (currentRecursiveSequence > 0) {
683 tree[tree.length - 1] = [last, currentRecursiveSequence];
684 currentRecursiveSequence = 0;
685 }
686 }
687 tree.push(vm);
688 vm = vm.$parent;
689 }
690 return '\n\nfound in\n\n' + tree
691 .map((vm, i) => `${
692 i === 0 ? '---> ' : repeat(' ', 5 + i * 2)
693 }${
694 Array.isArray(vm)
695 ? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)`
696 : formatComponentName(vm)
697 }`)
698 .join('\n')
699 } else {
700 return `\n\n(found in ${formatComponentName(vm)})`
701 }
702 };
703}
704
705/* */
706
707let uid = 0;
708
709/**
710 * A dep is an observable that can have multiple
711 * directives subscribing to it.
712 */
713class Dep {
714
715
716
717
718 constructor () {
719 this.id = uid++;
720 this.subs = [];
721 }
722
723 addSub (sub) {
724 this.subs.push(sub);
725 }
726
727 removeSub (sub) {
728 remove(this.subs, sub);
729 }
730
731 depend () {
732 if (Dep.target) {
733 Dep.target.addDep(this);
734 }
735 }
736
737 notify () {
738 // stabilize the subscriber list first
739 const subs = this.subs.slice();
740 if (!config.async) {
741 // subs aren't sorted in scheduler if not running async
742 // we need to sort them now to make sure they fire in correct
743 // order
744 subs.sort((a, b) => a.id - b.id);
745 }
746 for (let i = 0, l = subs.length; i < l; i++) {
747 subs[i].update();
748 }
749 }
750}
751
752// The current target watcher being evaluated.
753// This is globally unique because only one watcher
754// can be evaluated at a time.
755Dep.target = null;
756const targetStack = [];
757
758function pushTarget (target) {
759 targetStack.push(target);
760 Dep.target = target;
761}
762
763function popTarget () {
764 targetStack.pop();
765 Dep.target = targetStack[targetStack.length - 1];
766}
767
768/* */
769
770class VNode {
771
772
773
774
775
776
777 // rendered in this component's scope
778
779
780 // component instance
781 // component placeholder node
782
783 // strictly internal
784 // contains raw HTML? (server only)
785 // hoisted static node
786 // necessary for enter transition check
787 // empty comment placeholder?
788 // is a cloned node?
789 // is a v-once node?
790 // async component factory function
791
792
793
794 // real context vm for functional nodes
795 // for SSR caching
796 // used to store functional render context for devtools
797 // functional scope id support
798
799 constructor (
800 tag,
801 data,
802 children,
803 text,
804 elm,
805 context,
806 componentOptions,
807 asyncFactory
808 ) {
809 this.tag = tag;
810 this.data = data;
811 this.children = children;
812 this.text = text;
813 this.elm = elm;
814 this.ns = undefined;
815 this.context = context;
816 this.fnContext = undefined;
817 this.fnOptions = undefined;
818 this.fnScopeId = undefined;
819 this.key = data && data.key;
820 this.componentOptions = componentOptions;
821 this.componentInstance = undefined;
822 this.parent = undefined;
823 this.raw = false;
824 this.isStatic = false;
825 this.isRootInsert = true;
826 this.isComment = false;
827 this.isCloned = false;
828 this.isOnce = false;
829 this.asyncFactory = asyncFactory;
830 this.asyncMeta = undefined;
831 this.isAsyncPlaceholder = false;
832 }
833
834 // DEPRECATED: alias for componentInstance for backwards compat.
835 /* istanbul ignore next */
836 get child () {
837 return this.componentInstance
838 }
839}
840
841const createEmptyVNode = (text = '') => {
842 const node = new VNode();
843 node.text = text;
844 node.isComment = true;
845 return node
846};
847
848function createTextVNode (val) {
849 return new VNode(undefined, undefined, undefined, String(val))
850}
851
852// optimized shallow clone
853// used for static nodes and slot nodes because they may be reused across
854// multiple renders, cloning them avoids errors when DOM manipulations rely
855// on their elm reference.
856function cloneVNode (vnode) {
857 const cloned = new VNode(
858 vnode.tag,
859 vnode.data,
860 // #7975
861 // clone children array to avoid mutating original in case of cloning
862 // a child.
863 vnode.children && vnode.children.slice(),
864 vnode.text,
865 vnode.elm,
866 vnode.context,
867 vnode.componentOptions,
868 vnode.asyncFactory
869 );
870 cloned.ns = vnode.ns;
871 cloned.isStatic = vnode.isStatic;
872 cloned.key = vnode.key;
873 cloned.isComment = vnode.isComment;
874 cloned.fnContext = vnode.fnContext;
875 cloned.fnOptions = vnode.fnOptions;
876 cloned.fnScopeId = vnode.fnScopeId;
877 cloned.asyncMeta = vnode.asyncMeta;
878 cloned.isCloned = true;
879 return cloned
880}
881
882/*
883 * not type checking this file because flow doesn't play well with
884 * dynamically accessing methods on Array prototype
885 */
886
887const arrayProto = Array.prototype;
888const arrayMethods = Object.create(arrayProto);
889
890const methodsToPatch = [
891 'push',
892 'pop',
893 'shift',
894 'unshift',
895 'splice',
896 'sort',
897 'reverse'
898];
899
900/**
901 * Intercept mutating methods and emit events
902 */
903methodsToPatch.forEach(function (method) {
904 // cache original method
905 const original = arrayProto[method];
906 def(arrayMethods, method, function mutator (...args) {
907 const result = original.apply(this, args);
908 const ob = this.__ob__;
909 let inserted;
910 switch (method) {
911 case 'push':
912 case 'unshift':
913 inserted = args;
914 break
915 case 'splice':
916 inserted = args.slice(2);
917 break
918 }
919 if (inserted) ob.observeArray(inserted);
920 // notify change
921 ob.dep.notify();
922 return result
923 });
924});
925
926/* */
927
928const arrayKeys = Object.getOwnPropertyNames(arrayMethods);
929
930/**
931 * In some cases we may want to disable observation inside a component's
932 * update computation.
933 */
934let shouldObserve = true;
935
936function toggleObserving (value) {
937 shouldObserve = value;
938}
939
940/**
941 * Observer class that is attached to each observed
942 * object. Once attached, the observer converts the target
943 * object's property keys into getter/setters that
944 * collect dependencies and dispatch updates.
945 */
946class Observer {
947
948
949 // number of vms that have this object as root $data
950
951 constructor (value) {
952 this.value = value;
953 this.dep = new Dep();
954 this.vmCount = 0;
955 def(value, '__ob__', this);
956 if (Array.isArray(value)) {
957 if (hasProto) {
958 protoAugment(value, arrayMethods);
959 } else {
960 copyAugment(value, arrayMethods, arrayKeys);
961 }
962 this.observeArray(value);
963 } else {
964 this.walk(value);
965 }
966 }
967
968 /**
969 * Walk through all properties and convert them into
970 * getter/setters. This method should only be called when
971 * value type is Object.
972 */
973 walk (obj) {
974 const keys = Object.keys(obj);
975 for (let i = 0; i < keys.length; i++) {
976 defineReactive$$1(obj, keys[i]);
977 }
978 }
979
980 /**
981 * Observe a list of Array items.
982 */
983 observeArray (items) {
984 for (let i = 0, l = items.length; i < l; i++) {
985 observe(items[i]);
986 }
987 }
988}
989
990// helpers
991
992/**
993 * Augment a target Object or Array by intercepting
994 * the prototype chain using __proto__
995 */
996function protoAugment (target, src) {
997 /* eslint-disable no-proto */
998 target.__proto__ = src;
999 /* eslint-enable no-proto */
1000}
1001
1002/**
1003 * Augment a target Object or Array by defining
1004 * hidden properties.
1005 */
1006/* istanbul ignore next */
1007function copyAugment (target, src, keys) {
1008 for (let i = 0, l = keys.length; i < l; i++) {
1009 const key = keys[i];
1010 def(target, key, src[key]);
1011 }
1012}
1013
1014/**
1015 * Attempt to create an observer instance for a value,
1016 * returns the new observer if successfully observed,
1017 * or the existing observer if the value already has one.
1018 */
1019function observe (value, asRootData) {
1020 if (!isObject(value) || value instanceof VNode) {
1021 return
1022 }
1023 let ob;
1024 if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
1025 ob = value.__ob__;
1026 } else if (
1027 shouldObserve &&
1028 !isServerRendering() &&
1029 (Array.isArray(value) || isPlainObject(value)) &&
1030 Object.isExtensible(value) &&
1031 !value._isVue
1032 ) {
1033 ob = new Observer(value);
1034 }
1035 if (asRootData && ob) {
1036 ob.vmCount++;
1037 }
1038 return ob
1039}
1040
1041/**
1042 * Define a reactive property on an Object.
1043 */
1044function defineReactive$$1 (
1045 obj,
1046 key,
1047 val,
1048 customSetter,
1049 shallow
1050) {
1051 const dep = new Dep();
1052
1053 const property = Object.getOwnPropertyDescriptor(obj, key);
1054 if (property && property.configurable === false) {
1055 return
1056 }
1057
1058 // cater for pre-defined getter/setters
1059 const getter = property && property.get;
1060 const setter = property && property.set;
1061 if ((!getter || setter) && arguments.length === 2) {
1062 val = obj[key];
1063 }
1064
1065 let childOb = !shallow && observe(val);
1066 Object.defineProperty(obj, key, {
1067 enumerable: true,
1068 configurable: true,
1069 get: function reactiveGetter () {
1070 const value = getter ? getter.call(obj) : val;
1071 if (Dep.target) {
1072 dep.depend();
1073 if (childOb) {
1074 childOb.dep.depend();
1075 if (Array.isArray(value)) {
1076 dependArray(value);
1077 }
1078 }
1079 }
1080 return value
1081 },
1082 set: function reactiveSetter (newVal) {
1083 const value = getter ? getter.call(obj) : val;
1084 /* eslint-disable no-self-compare */
1085 if (newVal === value || (newVal !== newVal && value !== value)) {
1086 return
1087 }
1088 /* eslint-enable no-self-compare */
1089 if (customSetter) {
1090 customSetter();
1091 }
1092 // #7981: for accessor properties without setter
1093 if (getter && !setter) return
1094 if (setter) {
1095 setter.call(obj, newVal);
1096 } else {
1097 val = newVal;
1098 }
1099 childOb = !shallow && observe(newVal);
1100 dep.notify();
1101 }
1102 });
1103}
1104
1105/**
1106 * Set a property on an object. Adds the new property and
1107 * triggers change notification if the property doesn't
1108 * already exist.
1109 */
1110function set (target, key, val) {
1111 if (isUndef(target) || isPrimitive(target)
1112 ) {
1113 warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target)}`);
1114 }
1115 if (Array.isArray(target) && isValidArrayIndex(key)) {
1116 target.length = Math.max(target.length, key);
1117 target.splice(key, 1, val);
1118 return val
1119 }
1120 if (key in target && !(key in Object.prototype)) {
1121 target[key] = val;
1122 return val
1123 }
1124 const ob = (target).__ob__;
1125 if (target._isVue || (ob && ob.vmCount)) {
1126 warn(
1127 'Avoid adding reactive properties to a Vue instance or its root $data ' +
1128 'at runtime - declare it upfront in the data option.'
1129 );
1130 return val
1131 }
1132 if (!ob) {
1133 target[key] = val;
1134 return val
1135 }
1136 defineReactive$$1(ob.value, key, val);
1137 ob.dep.notify();
1138 return val
1139}
1140
1141/**
1142 * Delete a property and trigger change if necessary.
1143 */
1144function del (target, key) {
1145 if (isUndef(target) || isPrimitive(target)
1146 ) {
1147 warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target)}`);
1148 }
1149 if (Array.isArray(target) && isValidArrayIndex(key)) {
1150 target.splice(key, 1);
1151 return
1152 }
1153 const ob = (target).__ob__;
1154 if (target._isVue || (ob && ob.vmCount)) {
1155 warn(
1156 'Avoid deleting properties on a Vue instance or its root $data ' +
1157 '- just set it to null.'
1158 );
1159 return
1160 }
1161 if (!hasOwn(target, key)) {
1162 return
1163 }
1164 delete target[key];
1165 if (!ob) {
1166 return
1167 }
1168 ob.dep.notify();
1169}
1170
1171/**
1172 * Collect dependencies on array elements when the array is touched, since
1173 * we cannot intercept array element access like property getters.
1174 */
1175function dependArray (value) {
1176 for (let e, i = 0, l = value.length; i < l; i++) {
1177 e = value[i];
1178 e && e.__ob__ && e.__ob__.dep.depend();
1179 if (Array.isArray(e)) {
1180 dependArray(e);
1181 }
1182 }
1183}
1184
1185/* */
1186
1187/**
1188 * Option overwriting strategies are functions that handle
1189 * how to merge a parent option value and a child option
1190 * value into the final value.
1191 */
1192const strats = config.optionMergeStrategies;
1193
1194/**
1195 * Options with restrictions
1196 */
1197{
1198 strats.el = strats.propsData = function (parent, child, vm, key) {
1199 if (!vm) {
1200 warn(
1201 `option "${key}" can only be used during instance ` +
1202 'creation with the `new` keyword.'
1203 );
1204 }
1205 return defaultStrat(parent, child)
1206 };
1207}
1208
1209/**
1210 * Helper that recursively merges two data objects together.
1211 */
1212function mergeData (to, from) {
1213 if (!from) return to
1214 let key, toVal, fromVal;
1215
1216 const keys = hasSymbol
1217 ? Reflect.ownKeys(from)
1218 : Object.keys(from);
1219
1220 for (let i = 0; i < keys.length; i++) {
1221 key = keys[i];
1222 // in case the object is already observed...
1223 if (key === '__ob__') continue
1224 toVal = to[key];
1225 fromVal = from[key];
1226 if (!hasOwn(to, key)) {
1227 set(to, key, fromVal);
1228 } else if (
1229 toVal !== fromVal &&
1230 isPlainObject(toVal) &&
1231 isPlainObject(fromVal)
1232 ) {
1233 mergeData(toVal, fromVal);
1234 }
1235 }
1236 return to
1237}
1238
1239/**
1240 * Data
1241 */
1242function mergeDataOrFn (
1243 parentVal,
1244 childVal,
1245 vm
1246) {
1247 if (!vm) {
1248 // in a Vue.extend merge, both should be functions
1249 if (!childVal) {
1250 return parentVal
1251 }
1252 if (!parentVal) {
1253 return childVal
1254 }
1255 // when parentVal & childVal are both present,
1256 // we need to return a function that returns the
1257 // merged result of both functions... no need to
1258 // check if parentVal is a function here because
1259 // it has to be a function to pass previous merges.
1260 return function mergedDataFn () {
1261 return mergeData(
1262 typeof childVal === 'function' ? childVal.call(this, this) : childVal,
1263 typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
1264 )
1265 }
1266 } else {
1267 return function mergedInstanceDataFn () {
1268 // instance merge
1269 const instanceData = typeof childVal === 'function'
1270 ? childVal.call(vm, vm)
1271 : childVal;
1272 const defaultData = typeof parentVal === 'function'
1273 ? parentVal.call(vm, vm)
1274 : parentVal;
1275 if (instanceData) {
1276 return mergeData(instanceData, defaultData)
1277 } else {
1278 return defaultData
1279 }
1280 }
1281 }
1282}
1283
1284strats.data = function (
1285 parentVal,
1286 childVal,
1287 vm
1288) {
1289 if (!vm) {
1290 if (childVal && typeof childVal !== 'function') {
1291 warn(
1292 'The "data" option should be a function ' +
1293 'that returns a per-instance value in component ' +
1294 'definitions.',
1295 vm
1296 );
1297
1298 return parentVal
1299 }
1300 return mergeDataOrFn(parentVal, childVal)
1301 }
1302
1303 return mergeDataOrFn(parentVal, childVal, vm)
1304};
1305
1306/**
1307 * Hooks and props are merged as arrays.
1308 */
1309function mergeHook (
1310 parentVal,
1311 childVal
1312) {
1313 const res = childVal
1314 ? parentVal
1315 ? parentVal.concat(childVal)
1316 : Array.isArray(childVal)
1317 ? childVal
1318 : [childVal]
1319 : parentVal;
1320 return res
1321 ? dedupeHooks(res)
1322 : res
1323}
1324
1325function dedupeHooks (hooks) {
1326 const res = [];
1327 for (let i = 0; i < hooks.length; i++) {
1328 if (res.indexOf(hooks[i]) === -1) {
1329 res.push(hooks[i]);
1330 }
1331 }
1332 return res
1333}
1334
1335LIFECYCLE_HOOKS.forEach(hook => {
1336 strats[hook] = mergeHook;
1337});
1338
1339/**
1340 * Assets
1341 *
1342 * When a vm is present (instance creation), we need to do
1343 * a three-way merge between constructor options, instance
1344 * options and parent options.
1345 */
1346function mergeAssets (
1347 parentVal,
1348 childVal,
1349 vm,
1350 key
1351) {
1352 const res = Object.create(parentVal || null);
1353 if (childVal) {
1354 assertObjectType(key, childVal, vm);
1355 return extend(res, childVal)
1356 } else {
1357 return res
1358 }
1359}
1360
1361ASSET_TYPES.forEach(function (type) {
1362 strats[type + 's'] = mergeAssets;
1363});
1364
1365/**
1366 * Watchers.
1367 *
1368 * Watchers hashes should not overwrite one
1369 * another, so we merge them as arrays.
1370 */
1371strats.watch = function (
1372 parentVal,
1373 childVal,
1374 vm,
1375 key
1376) {
1377 // work around Firefox's Object.prototype.watch...
1378 if (parentVal === nativeWatch) parentVal = undefined;
1379 if (childVal === nativeWatch) childVal = undefined;
1380 /* istanbul ignore if */
1381 if (!childVal) return Object.create(parentVal || null)
1382 {
1383 assertObjectType(key, childVal, vm);
1384 }
1385 if (!parentVal) return childVal
1386 const ret = {};
1387 extend(ret, parentVal);
1388 for (const key in childVal) {
1389 let parent = ret[key];
1390 const child = childVal[key];
1391 if (parent && !Array.isArray(parent)) {
1392 parent = [parent];
1393 }
1394 ret[key] = parent
1395 ? parent.concat(child)
1396 : Array.isArray(child) ? child : [child];
1397 }
1398 return ret
1399};
1400
1401/**
1402 * Other object hashes.
1403 */
1404strats.props =
1405strats.methods =
1406strats.inject =
1407strats.computed = function (
1408 parentVal,
1409 childVal,
1410 vm,
1411 key
1412) {
1413 if (childVal && "development" !== 'production') {
1414 assertObjectType(key, childVal, vm);
1415 }
1416 if (!parentVal) return childVal
1417 const ret = Object.create(null);
1418 extend(ret, parentVal);
1419 if (childVal) extend(ret, childVal);
1420 return ret
1421};
1422strats.provide = mergeDataOrFn;
1423
1424/**
1425 * Default strategy.
1426 */
1427const defaultStrat = function (parentVal, childVal) {
1428 return childVal === undefined
1429 ? parentVal
1430 : childVal
1431};
1432
1433/**
1434 * Validate component names
1435 */
1436function checkComponents (options) {
1437 for (const key in options.components) {
1438 validateComponentName(key);
1439 }
1440}
1441
1442function validateComponentName (name) {
1443 if (!new RegExp(`^[a-zA-Z][\\-\\.0-9_${unicodeLetters}]*$`).test(name)) {
1444 warn(
1445 'Invalid component name: "' + name + '". Component names ' +
1446 'should conform to valid custom element name in html5 specification.'
1447 );
1448 }
1449 if (isBuiltInTag(name) || config.isReservedTag(name)) {
1450 warn(
1451 'Do not use built-in or reserved HTML elements as component ' +
1452 'id: ' + name
1453 );
1454 }
1455}
1456
1457/**
1458 * Ensure all props option syntax are normalized into the
1459 * Object-based format.
1460 */
1461function normalizeProps (options, vm) {
1462 const props = options.props;
1463 if (!props) return
1464 const res = {};
1465 let i, val, name;
1466 if (Array.isArray(props)) {
1467 i = props.length;
1468 while (i--) {
1469 val = props[i];
1470 if (typeof val === 'string') {
1471 name = camelize(val);
1472 res[name] = { type: null };
1473 } else {
1474 warn('props must be strings when using array syntax.');
1475 }
1476 }
1477 } else if (isPlainObject(props)) {
1478 for (const key in props) {
1479 val = props[key];
1480 name = camelize(key);
1481 res[name] = isPlainObject(val)
1482 ? val
1483 : { type: val };
1484 }
1485 } else {
1486 warn(
1487 `Invalid value for option "props": expected an Array or an Object, ` +
1488 `but got ${toRawType(props)}.`,
1489 vm
1490 );
1491 }
1492 options.props = res;
1493}
1494
1495/**
1496 * Normalize all injections into Object-based format
1497 */
1498function normalizeInject (options, vm) {
1499 const inject = options.inject;
1500 if (!inject) return
1501 const normalized = options.inject = {};
1502 if (Array.isArray(inject)) {
1503 for (let i = 0; i < inject.length; i++) {
1504 normalized[inject[i]] = { from: inject[i] };
1505 }
1506 } else if (isPlainObject(inject)) {
1507 for (const key in inject) {
1508 const val = inject[key];
1509 normalized[key] = isPlainObject(val)
1510 ? extend({ from: key }, val)
1511 : { from: val };
1512 }
1513 } else {
1514 warn(
1515 `Invalid value for option "inject": expected an Array or an Object, ` +
1516 `but got ${toRawType(inject)}.`,
1517 vm
1518 );
1519 }
1520}
1521
1522/**
1523 * Normalize raw function directives into object format.
1524 */
1525function normalizeDirectives (options) {
1526 const dirs = options.directives;
1527 if (dirs) {
1528 for (const key in dirs) {
1529 const def$$1 = dirs[key];
1530 if (typeof def$$1 === 'function') {
1531 dirs[key] = { bind: def$$1, update: def$$1 };
1532 }
1533 }
1534 }
1535}
1536
1537function assertObjectType (name, value, vm) {
1538 if (!isPlainObject(value)) {
1539 warn(
1540 `Invalid value for option "${name}": expected an Object, ` +
1541 `but got ${toRawType(value)}.`,
1542 vm
1543 );
1544 }
1545}
1546
1547/**
1548 * Merge two option objects into a new one.
1549 * Core utility used in both instantiation and inheritance.
1550 */
1551function mergeOptions (
1552 parent,
1553 child,
1554 vm
1555) {
1556 {
1557 checkComponents(child);
1558 }
1559
1560 if (typeof child === 'function') {
1561 child = child.options;
1562 }
1563
1564 normalizeProps(child, vm);
1565 normalizeInject(child, vm);
1566 normalizeDirectives(child);
1567
1568 // Apply extends and mixins on the child options,
1569 // but only if it is a raw options object that isn't
1570 // the result of another mergeOptions call.
1571 // Only merged options has the _base property.
1572 if (!child._base) {
1573 if (child.extends) {
1574 parent = mergeOptions(parent, child.extends, vm);
1575 }
1576 if (child.mixins) {
1577 for (let i = 0, l = child.mixins.length; i < l; i++) {
1578 parent = mergeOptions(parent, child.mixins[i], vm);
1579 }
1580 }
1581 }
1582
1583 const options = {};
1584 let key;
1585 for (key in parent) {
1586 mergeField(key);
1587 }
1588 for (key in child) {
1589 if (!hasOwn(parent, key)) {
1590 mergeField(key);
1591 }
1592 }
1593 function mergeField (key) {
1594 const strat = strats[key] || defaultStrat;
1595 options[key] = strat(parent[key], child[key], vm, key);
1596 }
1597 return options
1598}
1599
1600/**
1601 * Resolve an asset.
1602 * This function is used because child instances need access
1603 * to assets defined in its ancestor chain.
1604 */
1605function resolveAsset (
1606 options,
1607 type,
1608 id,
1609 warnMissing
1610) {
1611 /* istanbul ignore if */
1612 if (typeof id !== 'string') {
1613 return
1614 }
1615 const assets = options[type];
1616 // check local registration variations first
1617 if (hasOwn(assets, id)) return assets[id]
1618 const camelizedId = camelize(id);
1619 if (hasOwn(assets, camelizedId)) return assets[camelizedId]
1620 const PascalCaseId = capitalize(camelizedId);
1621 if (hasOwn(assets, PascalCaseId)) return assets[PascalCaseId]
1622 // fallback to prototype chain
1623 const res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
1624 if (warnMissing && !res) {
1625 warn(
1626 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
1627 options
1628 );
1629 }
1630 return res
1631}
1632
1633/* */
1634
1635
1636
1637function validateProp (
1638 key,
1639 propOptions,
1640 propsData,
1641 vm
1642) {
1643 const prop = propOptions[key];
1644 const absent = !hasOwn(propsData, key);
1645 let value = propsData[key];
1646 // boolean casting
1647 const booleanIndex = getTypeIndex(Boolean, prop.type);
1648 if (booleanIndex > -1) {
1649 if (absent && !hasOwn(prop, 'default')) {
1650 value = false;
1651 } else if (value === '' || value === hyphenate(key)) {
1652 // only cast empty string / same name to boolean if
1653 // boolean has higher priority
1654 const stringIndex = getTypeIndex(String, prop.type);
1655 if (stringIndex < 0 || booleanIndex < stringIndex) {
1656 value = true;
1657 }
1658 }
1659 }
1660 // check default value
1661 if (value === undefined) {
1662 value = getPropDefaultValue(vm, prop, key);
1663 // since the default value is a fresh copy,
1664 // make sure to observe it.
1665 const prevShouldObserve = shouldObserve;
1666 toggleObserving(true);
1667 observe(value);
1668 toggleObserving(prevShouldObserve);
1669 }
1670 {
1671 assertProp(prop, key, value, vm, absent);
1672 }
1673 return value
1674}
1675
1676/**
1677 * Get the default value of a prop.
1678 */
1679function getPropDefaultValue (vm, prop, key) {
1680 // no default, return undefined
1681 if (!hasOwn(prop, 'default')) {
1682 return undefined
1683 }
1684 const def = prop.default;
1685 // warn against non-factory defaults for Object & Array
1686 if (isObject(def)) {
1687 warn(
1688 'Invalid default value for prop "' + key + '": ' +
1689 'Props with type Object/Array must use a factory function ' +
1690 'to return the default value.',
1691 vm
1692 );
1693 }
1694 // the raw prop value was also undefined from previous render,
1695 // return previous default value to avoid unnecessary watcher trigger
1696 if (vm && vm.$options.propsData &&
1697 vm.$options.propsData[key] === undefined &&
1698 vm._props[key] !== undefined
1699 ) {
1700 return vm._props[key]
1701 }
1702 // call factory function for non-Function types
1703 // a value is Function if its prototype is function even across different execution context
1704 return typeof def === 'function' && getType(prop.type) !== 'Function'
1705 ? def.call(vm)
1706 : def
1707}
1708
1709/**
1710 * Assert whether a prop is valid.
1711 */
1712function assertProp (
1713 prop,
1714 name,
1715 value,
1716 vm,
1717 absent
1718) {
1719 if (prop.required && absent) {
1720 warn(
1721 'Missing required prop: "' + name + '"',
1722 vm
1723 );
1724 return
1725 }
1726 if (value == null && !prop.required) {
1727 return
1728 }
1729 let type = prop.type;
1730 let valid = !type || type === true;
1731 const expectedTypes = [];
1732 if (type) {
1733 if (!Array.isArray(type)) {
1734 type = [type];
1735 }
1736 for (let i = 0; i < type.length && !valid; i++) {
1737 const assertedType = assertType(value, type[i]);
1738 expectedTypes.push(assertedType.expectedType || '');
1739 valid = assertedType.valid;
1740 }
1741 }
1742
1743 if (!valid) {
1744 warn(
1745 getInvalidTypeMessage(name, value, expectedTypes),
1746 vm
1747 );
1748 return
1749 }
1750 const validator = prop.validator;
1751 if (validator) {
1752 if (!validator(value)) {
1753 warn(
1754 'Invalid prop: custom validator check failed for prop "' + name + '".',
1755 vm
1756 );
1757 }
1758 }
1759}
1760
1761const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;
1762
1763function assertType (value, type) {
1764 let valid;
1765 const expectedType = getType(type);
1766 if (simpleCheckRE.test(expectedType)) {
1767 const t = typeof value;
1768 valid = t === expectedType.toLowerCase();
1769 // for primitive wrapper objects
1770 if (!valid && t === 'object') {
1771 valid = value instanceof type;
1772 }
1773 } else if (expectedType === 'Object') {
1774 valid = isPlainObject(value);
1775 } else if (expectedType === 'Array') {
1776 valid = Array.isArray(value);
1777 } else {
1778 valid = value instanceof type;
1779 }
1780 return {
1781 valid,
1782 expectedType
1783 }
1784}
1785
1786/**
1787 * Use function string name to check built-in types,
1788 * because a simple equality check will fail when running
1789 * across different vms / iframes.
1790 */
1791function getType (fn) {
1792 const match = fn && fn.toString().match(/^\s*function (\w+)/);
1793 return match ? match[1] : ''
1794}
1795
1796function isSameType (a, b) {
1797 return getType(a) === getType(b)
1798}
1799
1800function getTypeIndex (type, expectedTypes) {
1801 if (!Array.isArray(expectedTypes)) {
1802 return isSameType(expectedTypes, type) ? 0 : -1
1803 }
1804 for (let i = 0, len = expectedTypes.length; i < len; i++) {
1805 if (isSameType(expectedTypes[i], type)) {
1806 return i
1807 }
1808 }
1809 return -1
1810}
1811
1812function getInvalidTypeMessage (name, value, expectedTypes) {
1813 let message = `Invalid prop: type check failed for prop "${name}".` +
1814 ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
1815 const expectedType = expectedTypes[0];
1816 const receivedType = toRawType(value);
1817 const expectedValue = styleValue(value, expectedType);
1818 const receivedValue = styleValue(value, receivedType);
1819 // check if we need to specify expected value
1820 if (expectedTypes.length === 1 &&
1821 isExplicable(expectedType) &&
1822 !isBoolean(expectedType, receivedType)) {
1823 message += ` with value ${expectedValue}`;
1824 }
1825 message += `, got ${receivedType} `;
1826 // check if we need to specify received value
1827 if (isExplicable(receivedType)) {
1828 message += `with value ${receivedValue}.`;
1829 }
1830 return message
1831}
1832
1833function styleValue (value, type) {
1834 if (type === 'String') {
1835 return `"${value}"`
1836 } else if (type === 'Number') {
1837 return `${Number(value)}`
1838 } else {
1839 return `${value}`
1840 }
1841}
1842
1843function isExplicable (value) {
1844 const explicitTypes = ['string', 'number', 'boolean'];
1845 return explicitTypes.some(elem => value.toLowerCase() === elem)
1846}
1847
1848function isBoolean (...args) {
1849 return args.some(elem => elem.toLowerCase() === 'boolean')
1850}
1851
1852/* */
1853
1854function handleError (err, vm, info) {
1855 // Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
1856 // See: https://github.com/vuejs/vuex/issues/1505
1857 pushTarget();
1858 try {
1859 if (vm) {
1860 let cur = vm;
1861 while ((cur = cur.$parent)) {
1862 const hooks = cur.$options.errorCaptured;
1863 if (hooks) {
1864 for (let i = 0; i < hooks.length; i++) {
1865 try {
1866 const capture = hooks[i].call(cur, err, vm, info) === false;
1867 if (capture) return
1868 } catch (e) {
1869 globalHandleError(e, cur, 'errorCaptured hook');
1870 }
1871 }
1872 }
1873 }
1874 }
1875 globalHandleError(err, vm, info);
1876 } finally {
1877 popTarget();
1878 }
1879}
1880
1881function invokeWithErrorHandling (
1882 handler,
1883 context,
1884 args,
1885 vm,
1886 info
1887) {
1888 let res;
1889 try {
1890 res = args ? handler.apply(context, args) : handler.call(context);
1891 if (res && !res._isVue && isPromise(res)) {
1892 // issue #9511
1893 // reassign to res to avoid catch triggering multiple times when nested calls
1894 res = res.catch(e => handleError(e, vm, info + ` (Promise/async)`));
1895 }
1896 } catch (e) {
1897 handleError(e, vm, info);
1898 }
1899 return res
1900}
1901
1902function globalHandleError (err, vm, info) {
1903 if (config.errorHandler) {
1904 try {
1905 return config.errorHandler.call(null, err, vm, info)
1906 } catch (e) {
1907 // if the user intentionally throws the original error in the handler,
1908 // do not log it twice
1909 if (e !== err) {
1910 logError(e, null, 'config.errorHandler');
1911 }
1912 }
1913 }
1914 logError(err, vm, info);
1915}
1916
1917function logError (err, vm, info) {
1918 {
1919 warn(`Error in ${info}: "${err.toString()}"`, vm);
1920 }
1921 /* istanbul ignore else */
1922 if ((inBrowser || inWeex) && typeof console !== 'undefined') {
1923 console.error(err);
1924 } else {
1925 throw err
1926 }
1927}
1928
1929/* */
1930
1931let isUsingMicroTask = false;
1932
1933const callbacks = [];
1934let pending = false;
1935
1936function flushCallbacks () {
1937 pending = false;
1938 const copies = callbacks.slice(0);
1939 callbacks.length = 0;
1940 for (let i = 0; i < copies.length; i++) {
1941 copies[i]();
1942 }
1943}
1944
1945// Here we have async deferring wrappers using microtasks.
1946// In 2.5 we used (macro) tasks (in combination with microtasks).
1947// However, it has subtle problems when state is changed right before repaint
1948// (e.g. #6813, out-in transitions).
1949// Also, using (macro) tasks in event handler would cause some weird behaviors
1950// that cannot be circumvented (e.g. #7109, #7153, #7546, #7834, #8109).
1951// So we now use microtasks everywhere, again.
1952// A major drawback of this tradeoff is that there are some scenarios
1953// where microtasks have too high a priority and fire in between supposedly
1954// sequential events (e.g. #4521, #6690, which have workarounds)
1955// or even between bubbling of the same event (#6566).
1956let timerFunc;
1957
1958// The nextTick behavior leverages the microtask queue, which can be accessed
1959// via either native Promise.then or MutationObserver.
1960// MutationObserver has wider support, however it is seriously bugged in
1961// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
1962// completely stops working after triggering a few times... so, if native
1963// Promise is available, we will use it:
1964/* istanbul ignore next, $flow-disable-line */
1965if (typeof Promise !== 'undefined' && isNative(Promise)) {
1966 const p = Promise.resolve();
1967 timerFunc = () => {
1968 p.then(flushCallbacks);
1969 // In problematic UIWebViews, Promise.then doesn't completely break, but
1970 // it can get stuck in a weird state where callbacks are pushed into the
1971 // microtask queue but the queue isn't being flushed, until the browser
1972 // needs to do some other work, e.g. handle a timer. Therefore we can
1973 // "force" the microtask queue to be flushed by adding an empty timer.
1974 if (isIOS) setTimeout(noop);
1975 };
1976 isUsingMicroTask = true;
1977} else if (!isIE && typeof MutationObserver !== 'undefined' && (
1978 isNative(MutationObserver) ||
1979 // PhantomJS and iOS 7.x
1980 MutationObserver.toString() === '[object MutationObserverConstructor]'
1981)) {
1982 // Use MutationObserver where native Promise is not available,
1983 // e.g. PhantomJS, iOS7, Android 4.4
1984 // (#6466 MutationObserver is unreliable in IE11)
1985 let counter = 1;
1986 const observer = new MutationObserver(flushCallbacks);
1987 const textNode = document.createTextNode(String(counter));
1988 observer.observe(textNode, {
1989 characterData: true
1990 });
1991 timerFunc = () => {
1992 counter = (counter + 1) % 2;
1993 textNode.data = String(counter);
1994 };
1995 isUsingMicroTask = true;
1996} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
1997 // Fallback to setImmediate.
1998 // Techinically it leverages the (macro) task queue,
1999 // but it is still a better choice than setTimeout.
2000 timerFunc = () => {
2001 setImmediate(flushCallbacks);
2002 };
2003} else {
2004 // Fallback to setTimeout.
2005 timerFunc = () => {
2006 setTimeout(flushCallbacks, 0);
2007 };
2008}
2009
2010function nextTick (cb, ctx) {
2011 let _resolve;
2012 callbacks.push(() => {
2013 if (cb) {
2014 try {
2015 cb.call(ctx);
2016 } catch (e) {
2017 handleError(e, ctx, 'nextTick');
2018 }
2019 } else if (_resolve) {
2020 _resolve(ctx);
2021 }
2022 });
2023 if (!pending) {
2024 pending = true;
2025 timerFunc();
2026 }
2027 // $flow-disable-line
2028 if (!cb && typeof Promise !== 'undefined') {
2029 return new Promise(resolve => {
2030 _resolve = resolve;
2031 })
2032 }
2033}
2034
2035/* */
2036
2037let mark;
2038let measure;
2039
2040{
2041 const perf = inBrowser && window.performance;
2042 /* istanbul ignore if */
2043 if (
2044 perf &&
2045 perf.mark &&
2046 perf.measure &&
2047 perf.clearMarks &&
2048 perf.clearMeasures
2049 ) {
2050 mark = tag => perf.mark(tag);
2051 measure = (name, startTag, endTag) => {
2052 perf.measure(name, startTag, endTag);
2053 perf.clearMarks(startTag);
2054 perf.clearMarks(endTag);
2055 // perf.clearMeasures(name)
2056 };
2057 }
2058}
2059
2060/* not type checking this file because flow doesn't play well with Proxy */
2061
2062let initProxy;
2063
2064{
2065 const allowedGlobals = makeMap(
2066 'Infinity,undefined,NaN,isFinite,isNaN,' +
2067 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
2068 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
2069 'require' // for Webpack/Browserify
2070 );
2071
2072 const warnNonPresent = (target, key) => {
2073 warn(
2074 `Property or method "${key}" is not defined on the instance but ` +
2075 'referenced during render. Make sure that this property is reactive, ' +
2076 'either in the data option, or for class-based components, by ' +
2077 'initializing the property. ' +
2078 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
2079 target
2080 );
2081 };
2082
2083 const warnReservedPrefix = (target, key) => {
2084 warn(
2085 `Property "${key}" must be accessed with "$data.${key}" because ` +
2086 'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
2087 'prevent conflicts with Vue internals' +
2088 'See: https://vuejs.org/v2/api/#data',
2089 target
2090 );
2091 };
2092
2093 const hasProxy =
2094 typeof Proxy !== 'undefined' && isNative(Proxy);
2095
2096 if (hasProxy) {
2097 const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact');
2098 config.keyCodes = new Proxy(config.keyCodes, {
2099 set (target, key, value) {
2100 if (isBuiltInModifier(key)) {
2101 warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`);
2102 return false
2103 } else {
2104 target[key] = value;
2105 return true
2106 }
2107 }
2108 });
2109 }
2110
2111 const hasHandler = {
2112 has (target, key) {
2113 const has = key in target;
2114 const isAllowed = allowedGlobals(key) ||
2115 (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data));
2116 if (!has && !isAllowed) {
2117 if (key in target.$data) warnReservedPrefix(target, key);
2118 else warnNonPresent(target, key);
2119 }
2120 return has || !isAllowed
2121 }
2122 };
2123
2124 const getHandler = {
2125 get (target, key) {
2126 if (typeof key === 'string' && !(key in target)) {
2127 if (key in target.$data) warnReservedPrefix(target, key);
2128 else warnNonPresent(target, key);
2129 }
2130 return target[key]
2131 }
2132 };
2133
2134 initProxy = function initProxy (vm) {
2135 if (hasProxy) {
2136 // determine which proxy handler to use
2137 const options = vm.$options;
2138 const handlers = options.render && options.render._withStripped
2139 ? getHandler
2140 : hasHandler;
2141 vm._renderProxy = new Proxy(vm, handlers);
2142 } else {
2143 vm._renderProxy = vm;
2144 }
2145 };
2146}
2147
2148/* */
2149
2150const seenObjects = new _Set();
2151
2152/**
2153 * Recursively traverse an object to evoke all converted
2154 * getters, so that every nested property inside the object
2155 * is collected as a "deep" dependency.
2156 */
2157function traverse (val) {
2158 _traverse(val, seenObjects);
2159 seenObjects.clear();
2160}
2161
2162function _traverse (val, seen) {
2163 let i, keys;
2164 const isA = Array.isArray(val);
2165 if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
2166 return
2167 }
2168 if (val.__ob__) {
2169 const depId = val.__ob__.dep.id;
2170 if (seen.has(depId)) {
2171 return
2172 }
2173 seen.add(depId);
2174 }
2175 if (isA) {
2176 i = val.length;
2177 while (i--) _traverse(val[i], seen);
2178 } else {
2179 keys = Object.keys(val);
2180 i = keys.length;
2181 while (i--) _traverse(val[keys[i]], seen);
2182 }
2183}
2184
2185/* */
2186
2187const normalizeEvent = cached((name) => {
2188 const passive = name.charAt(0) === '&';
2189 name = passive ? name.slice(1) : name;
2190 const once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first
2191 name = once$$1 ? name.slice(1) : name;
2192 const capture = name.charAt(0) === '!';
2193 name = capture ? name.slice(1) : name;
2194 return {
2195 name,
2196 once: once$$1,
2197 capture,
2198 passive
2199 }
2200});
2201
2202function createFnInvoker (fns, vm) {
2203 function invoker () {
2204 const fns = invoker.fns;
2205 if (Array.isArray(fns)) {
2206 const cloned = fns.slice();
2207 for (let i = 0; i < cloned.length; i++) {
2208 invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`);
2209 }
2210 } else {
2211 // return handler return value for single handlers
2212 return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)
2213 }
2214 }
2215 invoker.fns = fns;
2216 return invoker
2217}
2218
2219function updateListeners (
2220 on,
2221 oldOn,
2222 add,
2223 remove$$1,
2224 createOnceHandler,
2225 vm
2226) {
2227 let name, def$$1, cur, old, event;
2228 for (name in on) {
2229 def$$1 = cur = on[name];
2230 old = oldOn[name];
2231 event = normalizeEvent(name);
2232 if (isUndef(cur)) {
2233 warn(
2234 `Invalid handler for event "${event.name}": got ` + String(cur),
2235 vm
2236 );
2237 } else if (isUndef(old)) {
2238 if (isUndef(cur.fns)) {
2239 cur = on[name] = createFnInvoker(cur, vm);
2240 }
2241 if (isTrue(event.once)) {
2242 cur = on[name] = createOnceHandler(event.name, cur, event.capture);
2243 }
2244 add(event.name, cur, event.capture, event.passive, event.params);
2245 } else if (cur !== old) {
2246 old.fns = cur;
2247 on[name] = old;
2248 }
2249 }
2250 for (name in oldOn) {
2251 if (isUndef(on[name])) {
2252 event = normalizeEvent(name);
2253 remove$$1(event.name, oldOn[name], event.capture);
2254 }
2255 }
2256}
2257
2258/* */
2259
2260function mergeVNodeHook (def, hookKey, hook) {
2261 if (def instanceof VNode) {
2262 def = def.data.hook || (def.data.hook = {});
2263 }
2264 let invoker;
2265 const oldHook = def[hookKey];
2266
2267 function wrappedHook () {
2268 hook.apply(this, arguments);
2269 // important: remove merged hook to ensure it's called only once
2270 // and prevent memory leak
2271 remove(invoker.fns, wrappedHook);
2272 }
2273
2274 if (isUndef(oldHook)) {
2275 // no existing hook
2276 invoker = createFnInvoker([wrappedHook]);
2277 } else {
2278 /* istanbul ignore if */
2279 if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
2280 // already a merged invoker
2281 invoker = oldHook;
2282 invoker.fns.push(wrappedHook);
2283 } else {
2284 // existing plain hook
2285 invoker = createFnInvoker([oldHook, wrappedHook]);
2286 }
2287 }
2288
2289 invoker.merged = true;
2290 def[hookKey] = invoker;
2291}
2292
2293/* */
2294
2295function extractPropsFromVNodeData (
2296 data,
2297 Ctor,
2298 tag
2299) {
2300 // we are only extracting raw values here.
2301 // validation and default values are handled in the child
2302 // component itself.
2303 const propOptions = Ctor.options.props;
2304 if (isUndef(propOptions)) {
2305 return
2306 }
2307 const res = {};
2308 const { attrs, props } = data;
2309 if (isDef(attrs) || isDef(props)) {
2310 for (const key in propOptions) {
2311 const altKey = hyphenate(key);
2312 {
2313 const keyInLowerCase = key.toLowerCase();
2314 if (
2315 key !== keyInLowerCase &&
2316 attrs && hasOwn(attrs, keyInLowerCase)
2317 ) {
2318 tip(
2319 `Prop "${keyInLowerCase}" is passed to component ` +
2320 `${formatComponentName(tag || Ctor)}, but the declared prop name is` +
2321 ` "${key}". ` +
2322 `Note that HTML attributes are case-insensitive and camelCased ` +
2323 `props need to use their kebab-case equivalents when using in-DOM ` +
2324 `templates. You should probably use "${altKey}" instead of "${key}".`
2325 );
2326 }
2327 }
2328 checkProp(res, props, key, altKey, true) ||
2329 checkProp(res, attrs, key, altKey, false);
2330 }
2331 }
2332 return res
2333}
2334
2335function checkProp (
2336 res,
2337 hash,
2338 key,
2339 altKey,
2340 preserve
2341) {
2342 if (isDef(hash)) {
2343 if (hasOwn(hash, key)) {
2344 res[key] = hash[key];
2345 if (!preserve) {
2346 delete hash[key];
2347 }
2348 return true
2349 } else if (hasOwn(hash, altKey)) {
2350 res[key] = hash[altKey];
2351 if (!preserve) {
2352 delete hash[altKey];
2353 }
2354 return true
2355 }
2356 }
2357 return false
2358}
2359
2360/* */
2361
2362// The template compiler attempts to minimize the need for normalization by
2363// statically analyzing the template at compile time.
2364//
2365// For plain HTML markup, normalization can be completely skipped because the
2366// generated render function is guaranteed to return Array<VNode>. There are
2367// two cases where extra normalization is needed:
2368
2369// 1. When the children contains components - because a functional component
2370// may return an Array instead of a single root. In this case, just a simple
2371// normalization is needed - if any child is an Array, we flatten the whole
2372// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
2373// because functional components already normalize their own children.
2374function simpleNormalizeChildren (children) {
2375 for (let i = 0; i < children.length; i++) {
2376 if (Array.isArray(children[i])) {
2377 return Array.prototype.concat.apply([], children)
2378 }
2379 }
2380 return children
2381}
2382
2383// 2. When the children contains constructs that always generated nested Arrays,
2384// e.g. <template>, <slot>, v-for, or when the children is provided by user
2385// with hand-written render functions / JSX. In such cases a full normalization
2386// is needed to cater to all possible types of children values.
2387function normalizeChildren (children) {
2388 return isPrimitive(children)
2389 ? [createTextVNode(children)]
2390 : Array.isArray(children)
2391 ? normalizeArrayChildren(children)
2392 : undefined
2393}
2394
2395function isTextNode (node) {
2396 return isDef(node) && isDef(node.text) && isFalse(node.isComment)
2397}
2398
2399function normalizeArrayChildren (children, nestedIndex) {
2400 const res = [];
2401 let i, c, lastIndex, last;
2402 for (i = 0; i < children.length; i++) {
2403 c = children[i];
2404 if (isUndef(c) || typeof c === 'boolean') continue
2405 lastIndex = res.length - 1;
2406 last = res[lastIndex];
2407 // nested
2408 if (Array.isArray(c)) {
2409 if (c.length > 0) {
2410 c = normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`);
2411 // merge adjacent text nodes
2412 if (isTextNode(c[0]) && isTextNode(last)) {
2413 res[lastIndex] = createTextVNode(last.text + (c[0]).text);
2414 c.shift();
2415 }
2416 res.push.apply(res, c);
2417 }
2418 } else if (isPrimitive(c)) {
2419 if (isTextNode(last)) {
2420 // merge adjacent text nodes
2421 // this is necessary for SSR hydration because text nodes are
2422 // essentially merged when rendered to HTML strings
2423 res[lastIndex] = createTextVNode(last.text + c);
2424 } else if (c !== '') {
2425 // convert primitive to vnode
2426 res.push(createTextVNode(c));
2427 }
2428 } else {
2429 if (isTextNode(c) && isTextNode(last)) {
2430 // merge adjacent text nodes
2431 res[lastIndex] = createTextVNode(last.text + c.text);
2432 } else {
2433 // default key for nested array children (likely generated by v-for)
2434 if (isTrue(children._isVList) &&
2435 isDef(c.tag) &&
2436 isUndef(c.key) &&
2437 isDef(nestedIndex)) {
2438 c.key = `__vlist${nestedIndex}_${i}__`;
2439 }
2440 res.push(c);
2441 }
2442 }
2443 }
2444 return res
2445}
2446
2447/* */
2448
2449function initProvide (vm) {
2450 const provide = vm.$options.provide;
2451 if (provide) {
2452 vm._provided = typeof provide === 'function'
2453 ? provide.call(vm)
2454 : provide;
2455 }
2456}
2457
2458function initInjections (vm) {
2459 const result = resolveInject(vm.$options.inject, vm);
2460 if (result) {
2461 toggleObserving(false);
2462 Object.keys(result).forEach(key => {
2463 /* istanbul ignore else */
2464 {
2465 defineReactive$$1(vm, key, result[key], () => {
2466 warn(
2467 `Avoid mutating an injected value directly since the changes will be ` +
2468 `overwritten whenever the provided component re-renders. ` +
2469 `injection being mutated: "${key}"`,
2470 vm
2471 );
2472 });
2473 }
2474 });
2475 toggleObserving(true);
2476 }
2477}
2478
2479function resolveInject (inject, vm) {
2480 if (inject) {
2481 // inject is :any because flow is not smart enough to figure out cached
2482 const result = Object.create(null);
2483 const keys = hasSymbol
2484 ? Reflect.ownKeys(inject)
2485 : Object.keys(inject);
2486
2487 for (let i = 0; i < keys.length; i++) {
2488 const key = keys[i];
2489 // #6574 in case the inject object is observed...
2490 if (key === '__ob__') continue
2491 const provideKey = inject[key].from;
2492 let source = vm;
2493 while (source) {
2494 if (source._provided && hasOwn(source._provided, provideKey)) {
2495 result[key] = source._provided[provideKey];
2496 break
2497 }
2498 source = source.$parent;
2499 }
2500 if (!source) {
2501 if ('default' in inject[key]) {
2502 const provideDefault = inject[key].default;
2503 result[key] = typeof provideDefault === 'function'
2504 ? provideDefault.call(vm)
2505 : provideDefault;
2506 } else {
2507 warn(`Injection "${key}" not found`, vm);
2508 }
2509 }
2510 }
2511 return result
2512 }
2513}
2514
2515/* */
2516
2517
2518
2519/**
2520 * Runtime helper for resolving raw children VNodes into a slot object.
2521 */
2522function resolveSlots (
2523 children,
2524 context
2525) {
2526 if (!children || !children.length) {
2527 return {}
2528 }
2529 const slots = {};
2530 for (let i = 0, l = children.length; i < l; i++) {
2531 const child = children[i];
2532 const data = child.data;
2533 // remove slot attribute if the node is resolved as a Vue slot node
2534 if (data && data.attrs && data.attrs.slot) {
2535 delete data.attrs.slot;
2536 }
2537 // named slots should only be respected if the vnode was rendered in the
2538 // same context.
2539 if ((child.context === context || child.fnContext === context) &&
2540 data && data.slot != null
2541 ) {
2542 const name = data.slot;
2543 const slot = (slots[name] || (slots[name] = []));
2544 if (child.tag === 'template') {
2545 slot.push.apply(slot, child.children || []);
2546 } else {
2547 slot.push(child);
2548 }
2549 } else {
2550 (slots.default || (slots.default = [])).push(child);
2551 }
2552 }
2553 // ignore slots that contains only whitespace
2554 for (const name in slots) {
2555 if (slots[name].every(isWhitespace)) {
2556 delete slots[name];
2557 }
2558 }
2559 return slots
2560}
2561
2562function isWhitespace (node) {
2563 return (node.isComment && !node.asyncFactory) || node.text === ' '
2564}
2565
2566/* */
2567
2568function normalizeScopedSlots (
2569 slots,
2570 normalSlots,
2571 prevSlots
2572) {
2573 let res;
2574 const isStable = slots ? !!slots.$stable : true;
2575 const key = slots && slots.$key;
2576 if (!slots) {
2577 res = {};
2578 } else if (slots._normalized) {
2579 // fast path 1: child component re-render only, parent did not change
2580 return slots._normalized
2581 } else if (
2582 isStable &&
2583 prevSlots &&
2584 prevSlots !== emptyObject &&
2585 key === prevSlots.$key &&
2586 Object.keys(normalSlots).length === 0
2587 ) {
2588 // fast path 2: stable scoped slots w/ no normal slots to proxy,
2589 // only need to normalize once
2590 return prevSlots
2591 } else {
2592 res = {};
2593 for (const key in slots) {
2594 if (slots[key] && key[0] !== '$') {
2595 res[key] = normalizeScopedSlot(normalSlots, key, slots[key]);
2596 }
2597 }
2598 }
2599 // expose normal slots on scopedSlots
2600 for (const key in normalSlots) {
2601 if (!(key in res)) {
2602 res[key] = proxyNormalSlot(normalSlots, key);
2603 }
2604 }
2605 // avoriaz seems to mock a non-extensible $scopedSlots object
2606 // and when that is passed down this would cause an error
2607 if (slots && Object.isExtensible(slots)) {
2608 (slots)._normalized = res;
2609 }
2610 def(res, '$stable', isStable);
2611 def(res, '$key', key);
2612 return res
2613}
2614
2615function normalizeScopedSlot(normalSlots, key, fn) {
2616 const normalized = function () {
2617 let res = arguments.length ? fn.apply(null, arguments) : fn({});
2618 res = res && typeof res === 'object' && !Array.isArray(res)
2619 ? [res] // single vnode
2620 : normalizeChildren(res);
2621 return res && res.length === 0
2622 ? undefined
2623 : res
2624 };
2625 // this is a slot using the new v-slot syntax without scope. although it is
2626 // compiled as a scoped slot, render fn users would expect it to be present
2627 // on this.$slots because the usage is semantically a normal slot.
2628 if (fn.proxy) {
2629 Object.defineProperty(normalSlots, key, {
2630 get: normalized,
2631 enumerable: true,
2632 configurable: true
2633 });
2634 }
2635 return normalized
2636}
2637
2638function proxyNormalSlot(slots, key) {
2639 return () => slots[key]
2640}
2641
2642/* */
2643
2644/**
2645 * Runtime helper for rendering v-for lists.
2646 */
2647function renderList (
2648 val,
2649 render
2650) {
2651 let ret, i, l, keys, key;
2652 if (Array.isArray(val) || typeof val === 'string') {
2653 ret = new Array(val.length);
2654 for (i = 0, l = val.length; i < l; i++) {
2655 ret[i] = render(val[i], i);
2656 }
2657 } else if (typeof val === 'number') {
2658 ret = new Array(val);
2659 for (i = 0; i < val; i++) {
2660 ret[i] = render(i + 1, i);
2661 }
2662 } else if (isObject(val)) {
2663 if (hasSymbol && val[Symbol.iterator]) {
2664 ret = [];
2665 const iterator = val[Symbol.iterator]();
2666 let result = iterator.next();
2667 while (!result.done) {
2668 ret.push(render(result.value, ret.length));
2669 result = iterator.next();
2670 }
2671 } else {
2672 keys = Object.keys(val);
2673 ret = new Array(keys.length);
2674 for (i = 0, l = keys.length; i < l; i++) {
2675 key = keys[i];
2676 ret[i] = render(val[key], key, i);
2677 }
2678 }
2679 }
2680 if (!isDef(ret)) {
2681 ret = [];
2682 }
2683 (ret)._isVList = true;
2684 return ret
2685}
2686
2687/* */
2688
2689/**
2690 * Runtime helper for rendering <slot>
2691 */
2692function renderSlot (
2693 name,
2694 fallback,
2695 props,
2696 bindObject
2697) {
2698 const scopedSlotFn = this.$scopedSlots[name];
2699 let nodes;
2700 if (scopedSlotFn) { // scoped slot
2701 props = props || {};
2702 if (bindObject) {
2703 if (!isObject(bindObject)) {
2704 warn(
2705 'slot v-bind without argument expects an Object',
2706 this
2707 );
2708 }
2709 props = extend(extend({}, bindObject), props);
2710 }
2711 nodes = scopedSlotFn(props) || fallback;
2712 } else {
2713 nodes = this.$slots[name] || fallback;
2714 }
2715
2716 const target = props && props.slot;
2717 if (target) {
2718 return this.$createElement('template', { slot: target }, nodes)
2719 } else {
2720 return nodes
2721 }
2722}
2723
2724/* */
2725
2726/**
2727 * Runtime helper for resolving filters
2728 */
2729function resolveFilter (id) {
2730 return resolveAsset(this.$options, 'filters', id, true) || identity
2731}
2732
2733/* */
2734
2735function isKeyNotMatch (expect, actual) {
2736 if (Array.isArray(expect)) {
2737 return expect.indexOf(actual) === -1
2738 } else {
2739 return expect !== actual
2740 }
2741}
2742
2743/**
2744 * Runtime helper for checking keyCodes from config.
2745 * exposed as Vue.prototype._k
2746 * passing in eventKeyName as last argument separately for backwards compat
2747 */
2748function checkKeyCodes (
2749 eventKeyCode,
2750 key,
2751 builtInKeyCode,
2752 eventKeyName,
2753 builtInKeyName
2754) {
2755 const mappedKeyCode = config.keyCodes[key] || builtInKeyCode;
2756 if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
2757 return isKeyNotMatch(builtInKeyName, eventKeyName)
2758 } else if (mappedKeyCode) {
2759 return isKeyNotMatch(mappedKeyCode, eventKeyCode)
2760 } else if (eventKeyName) {
2761 return hyphenate(eventKeyName) !== key
2762 }
2763}
2764
2765/* */
2766
2767/**
2768 * Runtime helper for merging v-bind="object" into a VNode's data.
2769 */
2770function bindObjectProps (
2771 data,
2772 tag,
2773 value,
2774 asProp,
2775 isSync
2776) {
2777 if (value) {
2778 if (!isObject(value)) {
2779 warn(
2780 'v-bind without argument expects an Object or Array value',
2781 this
2782 );
2783 } else {
2784 if (Array.isArray(value)) {
2785 value = toObject(value);
2786 }
2787 let hash;
2788 for (const key in value) {
2789 if (
2790 key === 'class' ||
2791 key === 'style' ||
2792 isReservedAttribute(key)
2793 ) {
2794 hash = data;
2795 } else {
2796 const type = data.attrs && data.attrs.type;
2797 hash = asProp || config.mustUseProp(tag, type, key)
2798 ? data.domProps || (data.domProps = {})
2799 : data.attrs || (data.attrs = {});
2800 }
2801 const camelizedKey = camelize(key);
2802 if (!(key in hash) && !(camelizedKey in hash)) {
2803 hash[key] = value[key];
2804
2805 if (isSync) {
2806 const on = data.on || (data.on = {});
2807 on[`update:${camelizedKey}`] = function ($event) {
2808 value[key] = $event;
2809 };
2810 }
2811 }
2812 }
2813 }
2814 }
2815 return data
2816}
2817
2818/* */
2819
2820/**
2821 * Runtime helper for rendering static trees.
2822 */
2823function renderStatic (
2824 index,
2825 isInFor
2826) {
2827 const cached = this._staticTrees || (this._staticTrees = []);
2828 let tree = cached[index];
2829 // if has already-rendered static tree and not inside v-for,
2830 // we can reuse the same tree.
2831 if (tree && !isInFor) {
2832 return tree
2833 }
2834 // otherwise, render a fresh tree.
2835 tree = cached[index] = this.$options.staticRenderFns[index].call(
2836 this._renderProxy,
2837 null,
2838 this // for render fns generated for functional component templates
2839 );
2840 markStatic(tree, `__static__${index}`, false);
2841 return tree
2842}
2843
2844/**
2845 * Runtime helper for v-once.
2846 * Effectively it means marking the node as static with a unique key.
2847 */
2848function markOnce (
2849 tree,
2850 index,
2851 key
2852) {
2853 markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true);
2854 return tree
2855}
2856
2857function markStatic (
2858 tree,
2859 key,
2860 isOnce
2861) {
2862 if (Array.isArray(tree)) {
2863 for (let i = 0; i < tree.length; i++) {
2864 if (tree[i] && typeof tree[i] !== 'string') {
2865 markStaticNode(tree[i], `${key}_${i}`, isOnce);
2866 }
2867 }
2868 } else {
2869 markStaticNode(tree, key, isOnce);
2870 }
2871}
2872
2873function markStaticNode (node, key, isOnce) {
2874 node.isStatic = true;
2875 node.key = key;
2876 node.isOnce = isOnce;
2877}
2878
2879/* */
2880
2881function bindObjectListeners (data, value) {
2882 if (value) {
2883 if (!isPlainObject(value)) {
2884 warn(
2885 'v-on without argument expects an Object value',
2886 this
2887 );
2888 } else {
2889 const on = data.on = data.on ? extend({}, data.on) : {};
2890 for (const key in value) {
2891 const existing = on[key];
2892 const ours = value[key];
2893 on[key] = existing ? [].concat(existing, ours) : ours;
2894 }
2895 }
2896 }
2897 return data
2898}
2899
2900/* */
2901
2902function resolveScopedSlots (
2903 fns, // see flow/vnode
2904 res,
2905 // the following are added in 2.6
2906 hasDynamicKeys,
2907 contentHashKey
2908) {
2909 res = res || { $stable: !hasDynamicKeys };
2910 for (let i = 0; i < fns.length; i++) {
2911 const slot = fns[i];
2912 if (Array.isArray(slot)) {
2913 resolveScopedSlots(slot, res, hasDynamicKeys);
2914 } else if (slot) {
2915 // marker for reverse proxying v-slot without scope on this.$slots
2916 if (slot.proxy) {
2917 slot.fn.proxy = true;
2918 }
2919 res[slot.key] = slot.fn;
2920 }
2921 }
2922 if (contentHashKey) {
2923 (res).$key = contentHashKey;
2924 }
2925 return res
2926}
2927
2928/* */
2929
2930function bindDynamicKeys (baseObj, values) {
2931 for (let i = 0; i < values.length; i += 2) {
2932 const key = values[i];
2933 if (typeof key === 'string' && key) {
2934 baseObj[values[i]] = values[i + 1];
2935 } else if (key !== '' && key !== null) {
2936 // null is a speical value for explicitly removing a binding
2937 warn(
2938 `Invalid value for dynamic directive argument (expected string or null): ${key}`,
2939 this
2940 );
2941 }
2942 }
2943 return baseObj
2944}
2945
2946// helper to dynamically append modifier runtime markers to event names.
2947// ensure only append when value is already string, otherwise it will be cast
2948// to string and cause the type check to miss.
2949function prependModifier (value, symbol) {
2950 return typeof value === 'string' ? symbol + value : value
2951}
2952
2953/* */
2954
2955function installRenderHelpers (target) {
2956 target._o = markOnce;
2957 target._n = toNumber;
2958 target._s = toString;
2959 target._l = renderList;
2960 target._t = renderSlot;
2961 target._q = looseEqual;
2962 target._i = looseIndexOf;
2963 target._m = renderStatic;
2964 target._f = resolveFilter;
2965 target._k = checkKeyCodes;
2966 target._b = bindObjectProps;
2967 target._v = createTextVNode;
2968 target._e = createEmptyVNode;
2969 target._u = resolveScopedSlots;
2970 target._g = bindObjectListeners;
2971 target._d = bindDynamicKeys;
2972 target._p = prependModifier;
2973}
2974
2975/* */
2976
2977function FunctionalRenderContext (
2978 data,
2979 props,
2980 children,
2981 parent,
2982 Ctor
2983) {
2984 const options = Ctor.options;
2985 // ensure the createElement function in functional components
2986 // gets a unique context - this is necessary for correct named slot check
2987 let contextVm;
2988 if (hasOwn(parent, '_uid')) {
2989 contextVm = Object.create(parent);
2990 // $flow-disable-line
2991 contextVm._original = parent;
2992 } else {
2993 // the context vm passed in is a functional context as well.
2994 // in this case we want to make sure we are able to get a hold to the
2995 // real context instance.
2996 contextVm = parent;
2997 // $flow-disable-line
2998 parent = parent._original;
2999 }
3000 const isCompiled = isTrue(options._compiled);
3001 const needNormalization = !isCompiled;
3002
3003 this.data = data;
3004 this.props = props;
3005 this.children = children;
3006 this.parent = parent;
3007 this.listeners = data.on || emptyObject;
3008 this.injections = resolveInject(options.inject, parent);
3009 this.slots = () => {
3010 if (!this.$slots) {
3011 normalizeScopedSlots(
3012 data.scopedSlots,
3013 this.$slots = resolveSlots(children, parent)
3014 );
3015 }
3016 return this.$slots
3017 };
3018
3019 Object.defineProperty(this, 'scopedSlots', ({
3020 enumerable: true,
3021 get () {
3022 return normalizeScopedSlots(data.scopedSlots, this.slots())
3023 }
3024 }));
3025
3026 // support for compiled functional template
3027 if (isCompiled) {
3028 // exposing $options for renderStatic()
3029 this.$options = options;
3030 // pre-resolve slots for renderSlot()
3031 this.$slots = this.slots();
3032 this.$scopedSlots = normalizeScopedSlots(data.scopedSlots, this.$slots);
3033 }
3034
3035 if (options._scopeId) {
3036 this._c = (a, b, c, d) => {
3037 const vnode = createElement(contextVm, a, b, c, d, needNormalization);
3038 if (vnode && !Array.isArray(vnode)) {
3039 vnode.fnScopeId = options._scopeId;
3040 vnode.fnContext = parent;
3041 }
3042 return vnode
3043 };
3044 } else {
3045 this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization);
3046 }
3047}
3048
3049installRenderHelpers(FunctionalRenderContext.prototype);
3050
3051function createFunctionalComponent (
3052 Ctor,
3053 propsData,
3054 data,
3055 contextVm,
3056 children
3057) {
3058 const options = Ctor.options;
3059 const props = {};
3060 const propOptions = options.props;
3061 if (isDef(propOptions)) {
3062 for (const key in propOptions) {
3063 props[key] = validateProp(key, propOptions, propsData || emptyObject);
3064 }
3065 } else {
3066 if (isDef(data.attrs)) mergeProps(props, data.attrs);
3067 if (isDef(data.props)) mergeProps(props, data.props);
3068 }
3069
3070 const renderContext = new FunctionalRenderContext(
3071 data,
3072 props,
3073 children,
3074 contextVm,
3075 Ctor
3076 );
3077
3078 const vnode = options.render.call(null, renderContext._c, renderContext);
3079
3080 if (vnode instanceof VNode) {
3081 return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options, renderContext)
3082 } else if (Array.isArray(vnode)) {
3083 const vnodes = normalizeChildren(vnode) || [];
3084 const res = new Array(vnodes.length);
3085 for (let i = 0; i < vnodes.length; i++) {
3086 res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options, renderContext);
3087 }
3088 return res
3089 }
3090}
3091
3092function cloneAndMarkFunctionalResult (vnode, data, contextVm, options, renderContext) {
3093 // #7817 clone node before setting fnContext, otherwise if the node is reused
3094 // (e.g. it was from a cached normal slot) the fnContext causes named slots
3095 // that should not be matched to match.
3096 const clone = cloneVNode(vnode);
3097 clone.fnContext = contextVm;
3098 clone.fnOptions = options;
3099 {
3100 (clone.devtoolsMeta = clone.devtoolsMeta || {}).renderContext = renderContext;
3101 }
3102 if (data.slot) {
3103 (clone.data || (clone.data = {})).slot = data.slot;
3104 }
3105 return clone
3106}
3107
3108function mergeProps (to, from) {
3109 for (const key in from) {
3110 to[camelize(key)] = from[key];
3111 }
3112}
3113
3114/* */
3115
3116/* */
3117
3118/* */
3119
3120/* */
3121
3122// inline hooks to be invoked on component VNodes during patch
3123const componentVNodeHooks = {
3124 init (vnode, hydrating) {
3125 if (
3126 vnode.componentInstance &&
3127 !vnode.componentInstance._isDestroyed &&
3128 vnode.data.keepAlive
3129 ) {
3130 // kept-alive components, treat as a patch
3131 const mountedNode = vnode; // work around flow
3132 componentVNodeHooks.prepatch(mountedNode, mountedNode);
3133 } else {
3134 const child = vnode.componentInstance = createComponentInstanceForVnode(
3135 vnode,
3136 activeInstance
3137 );
3138 child.$mount(hydrating ? vnode.elm : undefined, hydrating);
3139 }
3140 },
3141
3142 prepatch (oldVnode, vnode) {
3143 const options = vnode.componentOptions;
3144 const child = vnode.componentInstance = oldVnode.componentInstance;
3145 updateChildComponent(
3146 child,
3147 options.propsData, // updated props
3148 options.listeners, // updated listeners
3149 vnode, // new parent vnode
3150 options.children // new children
3151 );
3152 },
3153
3154 insert (vnode) {
3155 const { context, componentInstance } = vnode;
3156 if (!componentInstance._isMounted) {
3157 componentInstance._isMounted = true;
3158 callHook(componentInstance, 'mounted');
3159 }
3160 if (vnode.data.keepAlive) {
3161 if (context._isMounted) {
3162 // vue-router#1212
3163 // During updates, a kept-alive component's child components may
3164 // change, so directly walking the tree here may call activated hooks
3165 // on incorrect children. Instead we push them into a queue which will
3166 // be processed after the whole patch process ended.
3167 queueActivatedComponent(componentInstance);
3168 } else {
3169 activateChildComponent(componentInstance, true /* direct */);
3170 }
3171 }
3172 },
3173
3174 destroy (vnode) {
3175 const { componentInstance } = vnode;
3176 if (!componentInstance._isDestroyed) {
3177 if (!vnode.data.keepAlive) {
3178 componentInstance.$destroy();
3179 } else {
3180 deactivateChildComponent(componentInstance, true /* direct */);
3181 }
3182 }
3183 }
3184};
3185
3186const hooksToMerge = Object.keys(componentVNodeHooks);
3187
3188function createComponent (
3189 Ctor,
3190 data,
3191 context,
3192 children,
3193 tag
3194) {
3195 if (isUndef(Ctor)) {
3196 return
3197 }
3198
3199 const baseCtor = context.$options._base;
3200
3201 // plain options object: turn it into a constructor
3202 if (isObject(Ctor)) {
3203 Ctor = baseCtor.extend(Ctor);
3204 }
3205
3206 // if at this stage it's not a constructor or an async component factory,
3207 // reject.
3208 if (typeof Ctor !== 'function') {
3209 {
3210 warn(`Invalid Component definition: ${String(Ctor)}`, context);
3211 }
3212 return
3213 }
3214
3215 // async component
3216 let asyncFactory;
3217 if (isUndef(Ctor.cid)) {
3218 asyncFactory = Ctor;
3219 Ctor = resolveAsyncComponent(asyncFactory, baseCtor);
3220 if (Ctor === undefined) {
3221 // return a placeholder node for async component, which is rendered
3222 // as a comment node but preserves all the raw information for the node.
3223 // the information will be used for async server-rendering and hydration.
3224 return createAsyncPlaceholder(
3225 asyncFactory,
3226 data,
3227 context,
3228 children,
3229 tag
3230 )
3231 }
3232 }
3233
3234 data = data || {};
3235
3236 // resolve constructor options in case global mixins are applied after
3237 // component constructor creation
3238 resolveConstructorOptions(Ctor);
3239
3240 // transform component v-model data into props & events
3241 if (isDef(data.model)) {
3242 transformModel(Ctor.options, data);
3243 }
3244
3245 // extract props
3246 const propsData = extractPropsFromVNodeData(data, Ctor, tag);
3247
3248 // functional component
3249 if (isTrue(Ctor.options.functional)) {
3250 return createFunctionalComponent(Ctor, propsData, data, context, children)
3251 }
3252
3253 // extract listeners, since these needs to be treated as
3254 // child component listeners instead of DOM listeners
3255 const listeners = data.on;
3256 // replace with listeners with .native modifier
3257 // so it gets processed during parent component patch.
3258 data.on = data.nativeOn;
3259
3260 if (isTrue(Ctor.options.abstract)) {
3261 // abstract components do not keep anything
3262 // other than props & listeners & slot
3263
3264 // work around flow
3265 const slot = data.slot;
3266 data = {};
3267 if (slot) {
3268 data.slot = slot;
3269 }
3270 }
3271
3272 // install component management hooks onto the placeholder node
3273 installComponentHooks(data);
3274
3275 // return a placeholder vnode
3276 const name = Ctor.options.name || tag;
3277 const vnode = new VNode(
3278 `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
3279 data, undefined, undefined, undefined, context,
3280 { Ctor, propsData, listeners, tag, children },
3281 asyncFactory
3282 );
3283
3284 return vnode
3285}
3286
3287function createComponentInstanceForVnode (
3288 vnode, // we know it's MountedComponentVNode but flow doesn't
3289 parent, // activeInstance in lifecycle state
3290) {
3291 const options = {
3292 _isComponent: true,
3293 _parentVnode: vnode,
3294 parent
3295 };
3296 // check inline-template render functions
3297 const inlineTemplate = vnode.data.inlineTemplate;
3298 if (isDef(inlineTemplate)) {
3299 options.render = inlineTemplate.render;
3300 options.staticRenderFns = inlineTemplate.staticRenderFns;
3301 }
3302 return new vnode.componentOptions.Ctor(options)
3303}
3304
3305function installComponentHooks (data) {
3306 const hooks = data.hook || (data.hook = {});
3307 for (let i = 0; i < hooksToMerge.length; i++) {
3308 const key = hooksToMerge[i];
3309 const existing = hooks[key];
3310 const toMerge = componentVNodeHooks[key];
3311 if (existing !== toMerge && !(existing && existing._merged)) {
3312 hooks[key] = existing ? mergeHook$1(toMerge, existing) : toMerge;
3313 }
3314 }
3315}
3316
3317function mergeHook$1 (f1, f2) {
3318 const merged = (a, b) => {
3319 // flow complains about extra args which is why we use any
3320 f1(a, b);
3321 f2(a, b);
3322 };
3323 merged._merged = true;
3324 return merged
3325}
3326
3327// transform component v-model info (value and callback) into
3328// prop and event handler respectively.
3329function transformModel (options, data) {
3330 const prop = (options.model && options.model.prop) || 'value';
3331 const event = (options.model && options.model.event) || 'input'
3332 ;(data.attrs || (data.attrs = {}))[prop] = data.model.value;
3333 const on = data.on || (data.on = {});
3334 const existing = on[event];
3335 const callback = data.model.callback;
3336 if (isDef(existing)) {
3337 if (
3338 Array.isArray(existing)
3339 ? existing.indexOf(callback) === -1
3340 : existing !== callback
3341 ) {
3342 on[event] = [callback].concat(existing);
3343 }
3344 } else {
3345 on[event] = callback;
3346 }
3347}
3348
3349/* */
3350
3351const SIMPLE_NORMALIZE = 1;
3352const ALWAYS_NORMALIZE = 2;
3353
3354// wrapper function for providing a more flexible interface
3355// without getting yelled at by flow
3356function createElement (
3357 context,
3358 tag,
3359 data,
3360 children,
3361 normalizationType,
3362 alwaysNormalize
3363) {
3364 if (Array.isArray(data) || isPrimitive(data)) {
3365 normalizationType = children;
3366 children = data;
3367 data = undefined;
3368 }
3369 if (isTrue(alwaysNormalize)) {
3370 normalizationType = ALWAYS_NORMALIZE;
3371 }
3372 return _createElement(context, tag, data, children, normalizationType)
3373}
3374
3375function _createElement (
3376 context,
3377 tag,
3378 data,
3379 children,
3380 normalizationType
3381) {
3382 if (isDef(data) && isDef((data).__ob__)) {
3383 warn(
3384 `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
3385 'Always create fresh vnode data objects in each render!',
3386 context
3387 );
3388 return createEmptyVNode()
3389 }
3390 // object syntax in v-bind
3391 if (isDef(data) && isDef(data.is)) {
3392 tag = data.is;
3393 }
3394 if (!tag) {
3395 // in case of component :is set to falsy value
3396 return createEmptyVNode()
3397 }
3398 // warn against non-primitive key
3399 if (isDef(data) && isDef(data.key) && !isPrimitive(data.key)
3400 ) {
3401 {
3402 warn(
3403 'Avoid using non-primitive value as key, ' +
3404 'use string/number value instead.',
3405 context
3406 );
3407 }
3408 }
3409 // support single function children as default scoped slot
3410 if (Array.isArray(children) &&
3411 typeof children[0] === 'function'
3412 ) {
3413 data = data || {};
3414 data.scopedSlots = { default: children[0] };
3415 children.length = 0;
3416 }
3417 if (normalizationType === ALWAYS_NORMALIZE) {
3418 children = normalizeChildren(children);
3419 } else if (normalizationType === SIMPLE_NORMALIZE) {
3420 children = simpleNormalizeChildren(children);
3421 }
3422 let vnode, ns;
3423 if (typeof tag === 'string') {
3424 let Ctor;
3425 ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
3426 if (config.isReservedTag(tag)) {
3427 // platform built-in elements
3428 vnode = new VNode(
3429 config.parsePlatformTagName(tag), data, children,
3430 undefined, undefined, context
3431 );
3432 } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
3433 // component
3434 vnode = createComponent(Ctor, data, context, children, tag);
3435 } else {
3436 // unknown or unlisted namespaced elements
3437 // check at runtime because it may get assigned a namespace when its
3438 // parent normalizes children
3439 vnode = new VNode(
3440 tag, data, children,
3441 undefined, undefined, context
3442 );
3443 }
3444 } else {
3445 // direct component options / constructor
3446 vnode = createComponent(tag, data, context, children);
3447 }
3448 if (Array.isArray(vnode)) {
3449 return vnode
3450 } else if (isDef(vnode)) {
3451 if (isDef(ns)) applyNS(vnode, ns);
3452 if (isDef(data)) registerDeepBindings(data);
3453 return vnode
3454 } else {
3455 return createEmptyVNode()
3456 }
3457}
3458
3459function applyNS (vnode, ns, force) {
3460 vnode.ns = ns;
3461 if (vnode.tag === 'foreignObject') {
3462 // use default namespace inside foreignObject
3463 ns = undefined;
3464 force = true;
3465 }
3466 if (isDef(vnode.children)) {
3467 for (let i = 0, l = vnode.children.length; i < l; i++) {
3468 const child = vnode.children[i];
3469 if (isDef(child.tag) && (
3470 isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) {
3471 applyNS(child, ns, force);
3472 }
3473 }
3474 }
3475}
3476
3477// ref #5318
3478// necessary to ensure parent re-render when deep bindings like :style and
3479// :class are used on slot nodes
3480function registerDeepBindings (data) {
3481 if (isObject(data.style)) {
3482 traverse(data.style);
3483 }
3484 if (isObject(data.class)) {
3485 traverse(data.class);
3486 }
3487}
3488
3489/* */
3490
3491function initRender (vm) {
3492 vm._vnode = null; // the root of the child tree
3493 vm._staticTrees = null; // v-once cached trees
3494 const options = vm.$options;
3495 const parentVnode = vm.$vnode = options._parentVnode; // the placeholder node in parent tree
3496 const renderContext = parentVnode && parentVnode.context;
3497 vm.$slots = resolveSlots(options._renderChildren, renderContext);
3498 vm.$scopedSlots = emptyObject;
3499 // bind the createElement fn to this instance
3500 // so that we get proper render context inside it.
3501 // args order: tag, data, children, normalizationType, alwaysNormalize
3502 // internal version is used by render functions compiled from templates
3503 vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false);
3504 // normalization is always applied for the public version, used in
3505 // user-written render functions.
3506 vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true);
3507
3508 // $attrs & $listeners are exposed for easier HOC creation.
3509 // they need to be reactive so that HOCs using them are always updated
3510 const parentData = parentVnode && parentVnode.data;
3511
3512 /* istanbul ignore else */
3513 {
3514 defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
3515 !isUpdatingChildComponent && warn(`$attrs is readonly.`, vm);
3516 }, true);
3517 defineReactive$$1(vm, '$listeners', options._parentListeners || emptyObject, () => {
3518 !isUpdatingChildComponent && warn(`$listeners is readonly.`, vm);
3519 }, true);
3520 }
3521}
3522
3523let currentRenderingInstance = null;
3524
3525function renderMixin (Vue) {
3526 // install runtime convenience helpers
3527 installRenderHelpers(Vue.prototype);
3528
3529 Vue.prototype.$nextTick = function (fn) {
3530 return nextTick(fn, this)
3531 };
3532
3533 Vue.prototype._render = function () {
3534 const vm = this;
3535 const { render, _parentVnode } = vm.$options;
3536
3537 if (_parentVnode) {
3538 vm.$scopedSlots = normalizeScopedSlots(
3539 _parentVnode.data.scopedSlots,
3540 vm.$slots,
3541 vm.$scopedSlots
3542 );
3543 }
3544
3545 // set parent vnode. this allows render functions to have access
3546 // to the data on the placeholder node.
3547 vm.$vnode = _parentVnode;
3548 // render self
3549 let vnode;
3550 try {
3551 // There's no need to maintain a stack becaues all render fns are called
3552 // separately from one another. Nested component's render fns are called
3553 // when parent component is patched.
3554 currentRenderingInstance = vm;
3555 vnode = render.call(vm._renderProxy, vm.$createElement);
3556 } catch (e) {
3557 handleError(e, vm, `render`);
3558 // return error render result,
3559 // or previous vnode to prevent render error causing blank component
3560 /* istanbul ignore else */
3561 if (vm.$options.renderError) {
3562 try {
3563 vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e);
3564 } catch (e) {
3565 handleError(e, vm, `renderError`);
3566 vnode = vm._vnode;
3567 }
3568 } else {
3569 vnode = vm._vnode;
3570 }
3571 } finally {
3572 currentRenderingInstance = null;
3573 }
3574 // if the returned array contains only a single node, allow it
3575 if (Array.isArray(vnode) && vnode.length === 1) {
3576 vnode = vnode[0];
3577 }
3578 // return empty vnode in case the render function errored out
3579 if (!(vnode instanceof VNode)) {
3580 if (Array.isArray(vnode)) {
3581 warn(
3582 'Multiple root nodes returned from render function. Render function ' +
3583 'should return a single root node.',
3584 vm
3585 );
3586 }
3587 vnode = createEmptyVNode();
3588 }
3589 // set parent
3590 vnode.parent = _parentVnode;
3591 return vnode
3592 };
3593}
3594
3595/* */
3596
3597function ensureCtor (comp, base) {
3598 if (
3599 comp.__esModule ||
3600 (hasSymbol && comp[Symbol.toStringTag] === 'Module')
3601 ) {
3602 comp = comp.default;
3603 }
3604 return isObject(comp)
3605 ? base.extend(comp)
3606 : comp
3607}
3608
3609function createAsyncPlaceholder (
3610 factory,
3611 data,
3612 context,
3613 children,
3614 tag
3615) {
3616 const node = createEmptyVNode();
3617 node.asyncFactory = factory;
3618 node.asyncMeta = { data, context, children, tag };
3619 return node
3620}
3621
3622function resolveAsyncComponent (
3623 factory,
3624 baseCtor
3625) {
3626 if (isTrue(factory.error) && isDef(factory.errorComp)) {
3627 return factory.errorComp
3628 }
3629
3630 if (isDef(factory.resolved)) {
3631 return factory.resolved
3632 }
3633
3634 if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
3635 return factory.loadingComp
3636 }
3637
3638 const owner = currentRenderingInstance;
3639 if (isDef(factory.owners)) {
3640 // already pending
3641 factory.owners.push(owner);
3642 } else {
3643 const owners = factory.owners = [owner];
3644 let sync = true;
3645
3646 const forceRender = (renderCompleted) => {
3647 for (let i = 0, l = owners.length; i < l; i++) {
3648 (owners[i]).$forceUpdate();
3649 }
3650
3651 if (renderCompleted) {
3652 owners.length = 0;
3653 }
3654 };
3655
3656 const resolve = once((res) => {
3657 // cache resolved
3658 factory.resolved = ensureCtor(res, baseCtor);
3659 // invoke callbacks only if this is not a synchronous resolve
3660 // (async resolves are shimmed as synchronous during SSR)
3661 if (!sync) {
3662 forceRender(true);
3663 } else {
3664 owners.length = 0;
3665 }
3666 });
3667
3668 const reject = once(reason => {
3669 warn(
3670 `Failed to resolve async component: ${String(factory)}` +
3671 (reason ? `\nReason: ${reason}` : '')
3672 );
3673 if (isDef(factory.errorComp)) {
3674 factory.error = true;
3675 forceRender(true);
3676 }
3677 });
3678
3679 const res = factory(resolve, reject);
3680
3681 if (isObject(res)) {
3682 if (isPromise(res)) {
3683 // () => Promise
3684 if (isUndef(factory.resolved)) {
3685 res.then(resolve, reject);
3686 }
3687 } else if (isPromise(res.component)) {
3688 res.component.then(resolve, reject);
3689
3690 if (isDef(res.error)) {
3691 factory.errorComp = ensureCtor(res.error, baseCtor);
3692 }
3693
3694 if (isDef(res.loading)) {
3695 factory.loadingComp = ensureCtor(res.loading, baseCtor);
3696 if (res.delay === 0) {
3697 factory.loading = true;
3698 } else {
3699 setTimeout(() => {
3700 if (isUndef(factory.resolved) && isUndef(factory.error)) {
3701 factory.loading = true;
3702 forceRender(false);
3703 }
3704 }, res.delay || 200);
3705 }
3706 }
3707
3708 if (isDef(res.timeout)) {
3709 setTimeout(() => {
3710 if (isUndef(factory.resolved)) {
3711 reject(
3712 `timeout (${res.timeout}ms)`
3713 );
3714 }
3715 }, res.timeout);
3716 }
3717 }
3718 }
3719
3720 sync = false;
3721 // return in case resolved synchronously
3722 return factory.loading
3723 ? factory.loadingComp
3724 : factory.resolved
3725 }
3726}
3727
3728/* */
3729
3730function isAsyncPlaceholder (node) {
3731 return node.isComment && node.asyncFactory
3732}
3733
3734/* */
3735
3736function getFirstComponentChild (children) {
3737 if (Array.isArray(children)) {
3738 for (let i = 0; i < children.length; i++) {
3739 const c = children[i];
3740 if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
3741 return c
3742 }
3743 }
3744 }
3745}
3746
3747/* */
3748
3749/* */
3750
3751function initEvents (vm) {
3752 vm._events = Object.create(null);
3753 vm._hasHookEvent = false;
3754 // init parent attached events
3755 const listeners = vm.$options._parentListeners;
3756 if (listeners) {
3757 updateComponentListeners(vm, listeners);
3758 }
3759}
3760
3761let target;
3762
3763function add (event, fn) {
3764 target.$on(event, fn);
3765}
3766
3767function remove$1 (event, fn) {
3768 target.$off(event, fn);
3769}
3770
3771function createOnceHandler (event, fn) {
3772 const _target = target;
3773 return function onceHandler () {
3774 const res = fn.apply(null, arguments);
3775 if (res !== null) {
3776 _target.$off(event, onceHandler);
3777 }
3778 }
3779}
3780
3781function updateComponentListeners (
3782 vm,
3783 listeners,
3784 oldListeners
3785) {
3786 target = vm;
3787 updateListeners(listeners, oldListeners || {}, add, remove$1, createOnceHandler, vm);
3788 target = undefined;
3789}
3790
3791function eventsMixin (Vue) {
3792 const hookRE = /^hook:/;
3793 Vue.prototype.$on = function (event, fn) {
3794 const vm = this;
3795 if (Array.isArray(event)) {
3796 for (let i = 0, l = event.length; i < l; i++) {
3797 vm.$on(event[i], fn);
3798 }
3799 } else {
3800 (vm._events[event] || (vm._events[event] = [])).push(fn);
3801 // optimize hook:event cost by using a boolean flag marked at registration
3802 // instead of a hash lookup
3803 if (hookRE.test(event)) {
3804 vm._hasHookEvent = true;
3805 }
3806 }
3807 return vm
3808 };
3809
3810 Vue.prototype.$once = function (event, fn) {
3811 const vm = this;
3812 function on () {
3813 vm.$off(event, on);
3814 fn.apply(vm, arguments);
3815 }
3816 on.fn = fn;
3817 vm.$on(event, on);
3818 return vm
3819 };
3820
3821 Vue.prototype.$off = function (event, fn) {
3822 const vm = this;
3823 // all
3824 if (!arguments.length) {
3825 vm._events = Object.create(null);
3826 return vm
3827 }
3828 // array of events
3829 if (Array.isArray(event)) {
3830 for (let i = 0, l = event.length; i < l; i++) {
3831 vm.$off(event[i], fn);
3832 }
3833 return vm
3834 }
3835 // specific event
3836 const cbs = vm._events[event];
3837 if (!cbs) {
3838 return vm
3839 }
3840 if (!fn) {
3841 vm._events[event] = null;
3842 return vm
3843 }
3844 // specific handler
3845 let cb;
3846 let i = cbs.length;
3847 while (i--) {
3848 cb = cbs[i];
3849 if (cb === fn || cb.fn === fn) {
3850 cbs.splice(i, 1);
3851 break
3852 }
3853 }
3854 return vm
3855 };
3856
3857 Vue.prototype.$emit = function (event) {
3858 const vm = this;
3859 {
3860 const lowerCaseEvent = event.toLowerCase();
3861 if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
3862 tip(
3863 `Event "${lowerCaseEvent}" is emitted in component ` +
3864 `${formatComponentName(vm)} but the handler is registered for "${event}". ` +
3865 `Note that HTML attributes are case-insensitive and you cannot use ` +
3866 `v-on to listen to camelCase events when using in-DOM templates. ` +
3867 `You should probably use "${hyphenate(event)}" instead of "${event}".`
3868 );
3869 }
3870 }
3871 let cbs = vm._events[event];
3872 if (cbs) {
3873 cbs = cbs.length > 1 ? toArray(cbs) : cbs;
3874 const args = toArray(arguments, 1);
3875 const info = `event handler for "${event}"`;
3876 for (let i = 0, l = cbs.length; i < l; i++) {
3877 invokeWithErrorHandling(cbs[i], vm, args, vm, info);
3878 }
3879 }
3880 return vm
3881 };
3882}
3883
3884/* */
3885
3886let activeInstance = null;
3887let isUpdatingChildComponent = false;
3888
3889function setActiveInstance(vm) {
3890 const prevActiveInstance = activeInstance;
3891 activeInstance = vm;
3892 return () => {
3893 activeInstance = prevActiveInstance;
3894 }
3895}
3896
3897function initLifecycle (vm) {
3898 const options = vm.$options;
3899
3900 // locate first non-abstract parent
3901 let parent = options.parent;
3902 if (parent && !options.abstract) {
3903 while (parent.$options.abstract && parent.$parent) {
3904 parent = parent.$parent;
3905 }
3906 parent.$children.push(vm);
3907 }
3908
3909 vm.$parent = parent;
3910 vm.$root = parent ? parent.$root : vm;
3911
3912 vm.$children = [];
3913 vm.$refs = {};
3914
3915 vm._watcher = null;
3916 vm._inactive = null;
3917 vm._directInactive = false;
3918 vm._isMounted = false;
3919 vm._isDestroyed = false;
3920 vm._isBeingDestroyed = false;
3921}
3922
3923function lifecycleMixin (Vue) {
3924 Vue.prototype._update = function (vnode, hydrating) {
3925 const vm = this;
3926 const prevEl = vm.$el;
3927 const prevVnode = vm._vnode;
3928 const restoreActiveInstance = setActiveInstance(vm);
3929 vm._vnode = vnode;
3930 // Vue.prototype.__patch__ is injected in entry points
3931 // based on the rendering backend used.
3932 if (!prevVnode) {
3933 // initial render
3934 vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
3935 } else {
3936 // updates
3937 vm.$el = vm.__patch__(prevVnode, vnode);
3938 }
3939 restoreActiveInstance();
3940 // update __vue__ reference
3941 if (prevEl) {
3942 prevEl.__vue__ = null;
3943 }
3944 if (vm.$el) {
3945 vm.$el.__vue__ = vm;
3946 }
3947 // if parent is an HOC, update its $el as well
3948 if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
3949 vm.$parent.$el = vm.$el;
3950 }
3951 // updated hook is called by the scheduler to ensure that children are
3952 // updated in a parent's updated hook.
3953 };
3954
3955 Vue.prototype.$forceUpdate = function () {
3956 const vm = this;
3957 if (vm._watcher) {
3958 vm._watcher.update();
3959 }
3960 };
3961
3962 Vue.prototype.$destroy = function () {
3963 const vm = this;
3964 if (vm._isBeingDestroyed) {
3965 return
3966 }
3967 callHook(vm, 'beforeDestroy');
3968 vm._isBeingDestroyed = true;
3969 // remove self from parent
3970 const parent = vm.$parent;
3971 if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
3972 remove(parent.$children, vm);
3973 }
3974 // teardown watchers
3975 if (vm._watcher) {
3976 vm._watcher.teardown();
3977 }
3978 let i = vm._watchers.length;
3979 while (i--) {
3980 vm._watchers[i].teardown();
3981 }
3982 // remove reference from data ob
3983 // frozen object may not have observer.
3984 if (vm._data.__ob__) {
3985 vm._data.__ob__.vmCount--;
3986 }
3987 // call the last hook...
3988 vm._isDestroyed = true;
3989 // invoke destroy hooks on current rendered tree
3990 vm.__patch__(vm._vnode, null);
3991 // fire destroyed hook
3992 callHook(vm, 'destroyed');
3993 // turn off all instance listeners.
3994 vm.$off();
3995 // remove __vue__ reference
3996 if (vm.$el) {
3997 vm.$el.__vue__ = null;
3998 }
3999 // release circular reference (#6759)
4000 if (vm.$vnode) {
4001 vm.$vnode.parent = null;
4002 }
4003 };
4004}
4005
4006function mountComponent (
4007 vm,
4008 el,
4009 hydrating
4010) {
4011 vm.$el = el;
4012 if (!vm.$options.render) {
4013 vm.$options.render = createEmptyVNode;
4014 {
4015 /* istanbul ignore if */
4016 if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
4017 vm.$options.el || el) {
4018 warn(
4019 'You are using the runtime-only build of Vue where the template ' +
4020 'compiler is not available. Either pre-compile the templates into ' +
4021 'render functions, or use the compiler-included build.',
4022 vm
4023 );
4024 } else {
4025 warn(
4026 'Failed to mount component: template or render function not defined.',
4027 vm
4028 );
4029 }
4030 }
4031 }
4032 callHook(vm, 'beforeMount');
4033
4034 let updateComponent;
4035 /* istanbul ignore if */
4036 if (config.performance && mark) {
4037 updateComponent = () => {
4038 const name = vm._name;
4039 const id = vm._uid;
4040 const startTag = `vue-perf-start:${id}`;
4041 const endTag = `vue-perf-end:${id}`;
4042
4043 mark(startTag);
4044 const vnode = vm._render();
4045 mark(endTag);
4046 measure(`vue ${name} render`, startTag, endTag);
4047
4048 mark(startTag);
4049 vm._update(vnode, hydrating);
4050 mark(endTag);
4051 measure(`vue ${name} patch`, startTag, endTag);
4052 };
4053 } else {
4054 updateComponent = () => {
4055 vm._update(vm._render(), hydrating);
4056 };
4057 }
4058
4059 // we set this to vm._watcher inside the watcher's constructor
4060 // since the watcher's initial patch may call $forceUpdate (e.g. inside child
4061 // component's mounted hook), which relies on vm._watcher being already defined
4062 new Watcher(vm, updateComponent, noop, {
4063 before () {
4064 if (vm._isMounted && !vm._isDestroyed) {
4065 callHook(vm, 'beforeUpdate');
4066 }
4067 }
4068 }, true /* isRenderWatcher */);
4069 hydrating = false;
4070
4071 // manually mounted instance, call mounted on self
4072 // mounted is called for render-created child components in its inserted hook
4073 if (vm.$vnode == null) {
4074 vm._isMounted = true;
4075 callHook(vm, 'mounted');
4076 }
4077 return vm
4078}
4079
4080function updateChildComponent (
4081 vm,
4082 propsData,
4083 listeners,
4084 parentVnode,
4085 renderChildren
4086) {
4087 {
4088 isUpdatingChildComponent = true;
4089 }
4090
4091 // determine whether component has slot children
4092 // we need to do this before overwriting $options._renderChildren.
4093
4094 // check if there are dynamic scopedSlots (hand-written or compiled but with
4095 // dynamic slot names). Static scoped slots compiled from template has the
4096 // "$stable" marker.
4097 const newScopedSlots = parentVnode.data.scopedSlots;
4098 const oldScopedSlots = vm.$scopedSlots;
4099 const hasDynamicScopedSlot = !!(
4100 (newScopedSlots && !newScopedSlots.$stable) ||
4101 (oldScopedSlots !== emptyObject && !oldScopedSlots.$stable) ||
4102 (newScopedSlots && vm.$scopedSlots.$key !== newScopedSlots.$key)
4103 );
4104
4105 // Any static slot children from the parent may have changed during parent's
4106 // update. Dynamic scoped slots may also have changed. In such cases, a forced
4107 // update is necessary to ensure correctness.
4108 const needsForceUpdate = !!(
4109 renderChildren || // has new static slots
4110 vm.$options._renderChildren || // has old static slots
4111 hasDynamicScopedSlot
4112 );
4113
4114 vm.$options._parentVnode = parentVnode;
4115 vm.$vnode = parentVnode; // update vm's placeholder node without re-render
4116
4117 if (vm._vnode) { // update child tree's parent
4118 vm._vnode.parent = parentVnode;
4119 }
4120 vm.$options._renderChildren = renderChildren;
4121
4122 // update $attrs and $listeners hash
4123 // these are also reactive so they may trigger child update if the child
4124 // used them during render
4125 vm.$attrs = parentVnode.data.attrs || emptyObject;
4126 vm.$listeners = listeners || emptyObject;
4127
4128 // update props
4129 if (propsData && vm.$options.props) {
4130 toggleObserving(false);
4131 const props = vm._props;
4132 const propKeys = vm.$options._propKeys || [];
4133 for (let i = 0; i < propKeys.length; i++) {
4134 const key = propKeys[i];
4135 const propOptions = vm.$options.props; // wtf flow?
4136 props[key] = validateProp(key, propOptions, propsData, vm);
4137 }
4138 toggleObserving(true);
4139 // keep a copy of raw propsData
4140 vm.$options.propsData = propsData;
4141 }
4142
4143 // update listeners
4144 listeners = listeners || emptyObject;
4145 const oldListeners = vm.$options._parentListeners;
4146 vm.$options._parentListeners = listeners;
4147 updateComponentListeners(vm, listeners, oldListeners);
4148
4149 // resolve slots + force update if has children
4150 if (needsForceUpdate) {
4151 vm.$slots = resolveSlots(renderChildren, parentVnode.context);
4152 vm.$forceUpdate();
4153 }
4154
4155 {
4156 isUpdatingChildComponent = false;
4157 }
4158}
4159
4160function isInInactiveTree (vm) {
4161 while (vm && (vm = vm.$parent)) {
4162 if (vm._inactive) return true
4163 }
4164 return false
4165}
4166
4167function activateChildComponent (vm, direct) {
4168 if (direct) {
4169 vm._directInactive = false;
4170 if (isInInactiveTree(vm)) {
4171 return
4172 }
4173 } else if (vm._directInactive) {
4174 return
4175 }
4176 if (vm._inactive || vm._inactive === null) {
4177 vm._inactive = false;
4178 for (let i = 0; i < vm.$children.length; i++) {
4179 activateChildComponent(vm.$children[i]);
4180 }
4181 callHook(vm, 'activated');
4182 }
4183}
4184
4185function deactivateChildComponent (vm, direct) {
4186 if (direct) {
4187 vm._directInactive = true;
4188 if (isInInactiveTree(vm)) {
4189 return
4190 }
4191 }
4192 if (!vm._inactive) {
4193 vm._inactive = true;
4194 for (let i = 0; i < vm.$children.length; i++) {
4195 deactivateChildComponent(vm.$children[i]);
4196 }
4197 callHook(vm, 'deactivated');
4198 }
4199}
4200
4201function callHook (vm, hook) {
4202 // #7573 disable dep collection when invoking lifecycle hooks
4203 pushTarget();
4204 const handlers = vm.$options[hook];
4205 const info = `${hook} hook`;
4206 if (handlers) {
4207 for (let i = 0, j = handlers.length; i < j; i++) {
4208 invokeWithErrorHandling(handlers[i], vm, null, vm, info);
4209 }
4210 }
4211 if (vm._hasHookEvent) {
4212 vm.$emit('hook:' + hook);
4213 }
4214 popTarget();
4215}
4216
4217/* */
4218
4219const MAX_UPDATE_COUNT = 100;
4220
4221const queue = [];
4222const activatedChildren = [];
4223let has = {};
4224let circular = {};
4225let waiting = false;
4226let flushing = false;
4227let index = 0;
4228
4229/**
4230 * Reset the scheduler's state.
4231 */
4232function resetSchedulerState () {
4233 index = queue.length = activatedChildren.length = 0;
4234 has = {};
4235 {
4236 circular = {};
4237 }
4238 waiting = flushing = false;
4239}
4240
4241// Async edge case #6566 requires saving the timestamp when event listeners are
4242// attached. However, calling performance.now() has a perf overhead especially
4243// if the page has thousands of event listeners. Instead, we take a timestamp
4244// every time the scheduler flushes and use that for all event listeners
4245// attached during that flush.
4246let currentFlushTimestamp = 0;
4247
4248// Async edge case fix requires storing an event listener's attach timestamp.
4249let getNow = Date.now;
4250
4251// Determine what event timestamp the browser is using. Annoyingly, the
4252// timestamp can either be hi-res (relative to page load) or low-res
4253// (relative to UNIX epoch), so in order to compare time we have to use the
4254// same timestamp type when saving the flush timestamp.
4255if (inBrowser && getNow() > document.createEvent('Event').timeStamp) {
4256 // if the low-res timestamp which is bigger than the event timestamp
4257 // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
4258 // and we need to use the hi-res version for event listeners as well.
4259 getNow = () => performance.now();
4260}
4261
4262/**
4263 * Flush both queues and run the watchers.
4264 */
4265function flushSchedulerQueue () {
4266 currentFlushTimestamp = getNow();
4267 flushing = true;
4268 let watcher, id;
4269
4270 // Sort queue before flush.
4271 // This ensures that:
4272 // 1. Components are updated from parent to child. (because parent is always
4273 // created before the child)
4274 // 2. A component's user watchers are run before its render watcher (because
4275 // user watchers are created before the render watcher)
4276 // 3. If a component is destroyed during a parent component's watcher run,
4277 // its watchers can be skipped.
4278 queue.sort((a, b) => a.id - b.id);
4279
4280 // do not cache length because more watchers might be pushed
4281 // as we run existing watchers
4282 for (index = 0; index < queue.length; index++) {
4283 watcher = queue[index];
4284 if (watcher.before) {
4285 watcher.before();
4286 }
4287 id = watcher.id;
4288 has[id] = null;
4289 watcher.run();
4290 // in dev build, check and stop circular updates.
4291 if (has[id] != null) {
4292 circular[id] = (circular[id] || 0) + 1;
4293 if (circular[id] > MAX_UPDATE_COUNT) {
4294 warn(
4295 'You may have an infinite update loop ' + (
4296 watcher.user
4297 ? `in watcher with expression "${watcher.expression}"`
4298 : `in a component render function.`
4299 ),
4300 watcher.vm
4301 );
4302 break
4303 }
4304 }
4305 }
4306
4307 // keep copies of post queues before resetting state
4308 const activatedQueue = activatedChildren.slice();
4309 const updatedQueue = queue.slice();
4310
4311 resetSchedulerState();
4312
4313 // call component updated and activated hooks
4314 callActivatedHooks(activatedQueue);
4315 callUpdatedHooks(updatedQueue);
4316
4317 // devtool hook
4318 /* istanbul ignore if */
4319 if (devtools && config.devtools) {
4320 devtools.emit('flush');
4321 }
4322}
4323
4324function callUpdatedHooks (queue) {
4325 let i = queue.length;
4326 while (i--) {
4327 const watcher = queue[i];
4328 const vm = watcher.vm;
4329 if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) {
4330 callHook(vm, 'updated');
4331 }
4332 }
4333}
4334
4335/**
4336 * Queue a kept-alive component that was activated during patch.
4337 * The queue will be processed after the entire tree has been patched.
4338 */
4339function queueActivatedComponent (vm) {
4340 // setting _inactive to false here so that a render function can
4341 // rely on checking whether it's in an inactive tree (e.g. router-view)
4342 vm._inactive = false;
4343 activatedChildren.push(vm);
4344}
4345
4346function callActivatedHooks (queue) {
4347 for (let i = 0; i < queue.length; i++) {
4348 queue[i]._inactive = true;
4349 activateChildComponent(queue[i], true /* true */);
4350 }
4351}
4352
4353/**
4354 * Push a watcher into the watcher queue.
4355 * Jobs with duplicate IDs will be skipped unless it's
4356 * pushed when the queue is being flushed.
4357 */
4358function queueWatcher (watcher) {
4359 const id = watcher.id;
4360 if (has[id] == null) {
4361 has[id] = true;
4362 if (!flushing) {
4363 queue.push(watcher);
4364 } else {
4365 // if already flushing, splice the watcher based on its id
4366 // if already past its id, it will be run next immediately.
4367 let i = queue.length - 1;
4368 while (i > index && queue[i].id > watcher.id) {
4369 i--;
4370 }
4371 queue.splice(i + 1, 0, watcher);
4372 }
4373 // queue the flush
4374 if (!waiting) {
4375 waiting = true;
4376
4377 if (!config.async) {
4378 flushSchedulerQueue();
4379 return
4380 }
4381 nextTick(flushSchedulerQueue);
4382 }
4383 }
4384}
4385
4386/* */
4387
4388
4389
4390let uid$2 = 0;
4391
4392/**
4393 * A watcher parses an expression, collects dependencies,
4394 * and fires callback when the expression value changes.
4395 * This is used for both the $watch() api and directives.
4396 */
4397class Watcher {
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416 constructor (
4417 vm,
4418 expOrFn,
4419 cb,
4420 options,
4421 isRenderWatcher
4422 ) {
4423 this.vm = vm;
4424 if (isRenderWatcher) {
4425 vm._watcher = this;
4426 }
4427 vm._watchers.push(this);
4428 // options
4429 if (options) {
4430 this.deep = !!options.deep;
4431 this.user = !!options.user;
4432 this.lazy = !!options.lazy;
4433 this.sync = !!options.sync;
4434 this.before = options.before;
4435 } else {
4436 this.deep = this.user = this.lazy = this.sync = false;
4437 }
4438 this.cb = cb;
4439 this.id = ++uid$2; // uid for batching
4440 this.active = true;
4441 this.dirty = this.lazy; // for lazy watchers
4442 this.deps = [];
4443 this.newDeps = [];
4444 this.depIds = new _Set();
4445 this.newDepIds = new _Set();
4446 this.expression = expOrFn.toString();
4447 // parse expression for getter
4448 if (typeof expOrFn === 'function') {
4449 this.getter = expOrFn;
4450 } else {
4451 this.getter = parsePath(expOrFn);
4452 if (!this.getter) {
4453 this.getter = noop;
4454 warn(
4455 `Failed watching path: "${expOrFn}" ` +
4456 'Watcher only accepts simple dot-delimited paths. ' +
4457 'For full control, use a function instead.',
4458 vm
4459 );
4460 }
4461 }
4462 this.value = this.lazy
4463 ? undefined
4464 : this.get();
4465 }
4466
4467 /**
4468 * Evaluate the getter, and re-collect dependencies.
4469 */
4470 get () {
4471 pushTarget(this);
4472 let value;
4473 const vm = this.vm;
4474 try {
4475 value = this.getter.call(vm, vm);
4476 } catch (e) {
4477 if (this.user) {
4478 handleError(e, vm, `getter for watcher "${this.expression}"`);
4479 } else {
4480 throw e
4481 }
4482 } finally {
4483 // "touch" every property so they are all tracked as
4484 // dependencies for deep watching
4485 if (this.deep) {
4486 traverse(value);
4487 }
4488 popTarget();
4489 this.cleanupDeps();
4490 }
4491 return value
4492 }
4493
4494 /**
4495 * Add a dependency to this directive.
4496 */
4497 addDep (dep) {
4498 const id = dep.id;
4499 if (!this.newDepIds.has(id)) {
4500 this.newDepIds.add(id);
4501 this.newDeps.push(dep);
4502 if (!this.depIds.has(id)) {
4503 dep.addSub(this);
4504 }
4505 }
4506 }
4507
4508 /**
4509 * Clean up for dependency collection.
4510 */
4511 cleanupDeps () {
4512 let i = this.deps.length;
4513 while (i--) {
4514 const dep = this.deps[i];
4515 if (!this.newDepIds.has(dep.id)) {
4516 dep.removeSub(this);
4517 }
4518 }
4519 let tmp = this.depIds;
4520 this.depIds = this.newDepIds;
4521 this.newDepIds = tmp;
4522 this.newDepIds.clear();
4523 tmp = this.deps;
4524 this.deps = this.newDeps;
4525 this.newDeps = tmp;
4526 this.newDeps.length = 0;
4527 }
4528
4529 /**
4530 * Subscriber interface.
4531 * Will be called when a dependency changes.
4532 */
4533 update () {
4534 /* istanbul ignore else */
4535 if (this.lazy) {
4536 this.dirty = true;
4537 } else if (this.sync) {
4538 this.run();
4539 } else {
4540 queueWatcher(this);
4541 }
4542 }
4543
4544 /**
4545 * Scheduler job interface.
4546 * Will be called by the scheduler.
4547 */
4548 run () {
4549 if (this.active) {
4550 const value = this.get();
4551 if (
4552 value !== this.value ||
4553 // Deep watchers and watchers on Object/Arrays should fire even
4554 // when the value is the same, because the value may
4555 // have mutated.
4556 isObject(value) ||
4557 this.deep
4558 ) {
4559 // set new value
4560 const oldValue = this.value;
4561 this.value = value;
4562 if (this.user) {
4563 try {
4564 this.cb.call(this.vm, value, oldValue);
4565 } catch (e) {
4566 handleError(e, this.vm, `callback for watcher "${this.expression}"`);
4567 }
4568 } else {
4569 this.cb.call(this.vm, value, oldValue);
4570 }
4571 }
4572 }
4573 }
4574
4575 /**
4576 * Evaluate the value of the watcher.
4577 * This only gets called for lazy watchers.
4578 */
4579 evaluate () {
4580 this.value = this.get();
4581 this.dirty = false;
4582 }
4583
4584 /**
4585 * Depend on all deps collected by this watcher.
4586 */
4587 depend () {
4588 let i = this.deps.length;
4589 while (i--) {
4590 this.deps[i].depend();
4591 }
4592 }
4593
4594 /**
4595 * Remove self from all dependencies' subscriber list.
4596 */
4597 teardown () {
4598 if (this.active) {
4599 // remove self from vm's watcher list
4600 // this is a somewhat expensive operation so we skip it
4601 // if the vm is being destroyed.
4602 if (!this.vm._isBeingDestroyed) {
4603 remove(this.vm._watchers, this);
4604 }
4605 let i = this.deps.length;
4606 while (i--) {
4607 this.deps[i].removeSub(this);
4608 }
4609 this.active = false;
4610 }
4611 }
4612}
4613
4614/* */
4615
4616const sharedPropertyDefinition = {
4617 enumerable: true,
4618 configurable: true,
4619 get: noop,
4620 set: noop
4621};
4622
4623function proxy (target, sourceKey, key) {
4624 sharedPropertyDefinition.get = function proxyGetter () {
4625 return this[sourceKey][key]
4626 };
4627 sharedPropertyDefinition.set = function proxySetter (val) {
4628 this[sourceKey][key] = val;
4629 };
4630 Object.defineProperty(target, key, sharedPropertyDefinition);
4631}
4632
4633function initState (vm) {
4634 vm._watchers = [];
4635 const opts = vm.$options;
4636 if (opts.props) initProps(vm, opts.props);
4637 if (opts.methods) initMethods(vm, opts.methods);
4638 if (opts.data) {
4639 initData(vm);
4640 } else {
4641 observe(vm._data = {}, true /* asRootData */);
4642 }
4643 if (opts.computed) initComputed(vm, opts.computed);
4644 if (opts.watch && opts.watch !== nativeWatch) {
4645 initWatch(vm, opts.watch);
4646 }
4647}
4648
4649function initProps (vm, propsOptions) {
4650 const propsData = vm.$options.propsData || {};
4651 const props = vm._props = {};
4652 // cache prop keys so that future props updates can iterate using Array
4653 // instead of dynamic object key enumeration.
4654 const keys = vm.$options._propKeys = [];
4655 const isRoot = !vm.$parent;
4656 // root instance props should be converted
4657 if (!isRoot) {
4658 toggleObserving(false);
4659 }
4660 for (const key in propsOptions) {
4661 keys.push(key);
4662 const value = validateProp(key, propsOptions, propsData, vm);
4663 /* istanbul ignore else */
4664 {
4665 const hyphenatedKey = hyphenate(key);
4666 if (isReservedAttribute(hyphenatedKey) ||
4667 config.isReservedAttr(hyphenatedKey)) {
4668 warn(
4669 `"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,
4670 vm
4671 );
4672 }
4673 defineReactive$$1(props, key, value, () => {
4674 if (!isRoot && !isUpdatingChildComponent) {
4675 warn(
4676 `Avoid mutating a prop directly since the value will be ` +
4677 `overwritten whenever the parent component re-renders. ` +
4678 `Instead, use a data or computed property based on the prop's ` +
4679 `value. Prop being mutated: "${key}"`,
4680 vm
4681 );
4682 }
4683 });
4684 }
4685 // static props are already proxied on the component's prototype
4686 // during Vue.extend(). We only need to proxy props defined at
4687 // instantiation here.
4688 if (!(key in vm)) {
4689 proxy(vm, `_props`, key);
4690 }
4691 }
4692 toggleObserving(true);
4693}
4694
4695function initData (vm) {
4696 let data = vm.$options.data;
4697 data = vm._data = typeof data === 'function'
4698 ? getData(data, vm)
4699 : data || {};
4700 if (!isPlainObject(data)) {
4701 data = {};
4702 warn(
4703 'data functions should return an object:\n' +
4704 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
4705 vm
4706 );
4707 }
4708 // proxy data on instance
4709 const keys = Object.keys(data);
4710 const props = vm.$options.props;
4711 const methods = vm.$options.methods;
4712 let i = keys.length;
4713 while (i--) {
4714 const key = keys[i];
4715 {
4716 if (methods && hasOwn(methods, key)) {
4717 warn(
4718 `Method "${key}" has already been defined as a data property.`,
4719 vm
4720 );
4721 }
4722 }
4723 if (props && hasOwn(props, key)) {
4724 warn(
4725 `The data property "${key}" is already declared as a prop. ` +
4726 `Use prop default value instead.`,
4727 vm
4728 );
4729 } else if (!isReserved(key)) {
4730 proxy(vm, `_data`, key);
4731 }
4732 }
4733 // observe data
4734 observe(data, true /* asRootData */);
4735}
4736
4737function getData (data, vm) {
4738 // #7573 disable dep collection when invoking data getters
4739 pushTarget();
4740 try {
4741 return data.call(vm, vm)
4742 } catch (e) {
4743 handleError(e, vm, `data()`);
4744 return {}
4745 } finally {
4746 popTarget();
4747 }
4748}
4749
4750const computedWatcherOptions = { lazy: true };
4751
4752function initComputed (vm, computed) {
4753 // $flow-disable-line
4754 const watchers = vm._computedWatchers = Object.create(null);
4755 // computed properties are just getters during SSR
4756 const isSSR = isServerRendering();
4757
4758 for (const key in computed) {
4759 const userDef = computed[key];
4760 const getter = typeof userDef === 'function' ? userDef : userDef.get;
4761 if (getter == null) {
4762 warn(
4763 `Getter is missing for computed property "${key}".`,
4764 vm
4765 );
4766 }
4767
4768 if (!isSSR) {
4769 // create internal watcher for the computed property.
4770 watchers[key] = new Watcher(
4771 vm,
4772 getter || noop,
4773 noop,
4774 computedWatcherOptions
4775 );
4776 }
4777
4778 // component-defined computed properties are already defined on the
4779 // component prototype. We only need to define computed properties defined
4780 // at instantiation here.
4781 if (!(key in vm)) {
4782 defineComputed(vm, key, userDef);
4783 } else {
4784 if (key in vm.$data) {
4785 warn(`The computed property "${key}" is already defined in data.`, vm);
4786 } else if (vm.$options.props && key in vm.$options.props) {
4787 warn(`The computed property "${key}" is already defined as a prop.`, vm);
4788 }
4789 }
4790 }
4791}
4792
4793function defineComputed (
4794 target,
4795 key,
4796 userDef
4797) {
4798 const shouldCache = !isServerRendering();
4799 if (typeof userDef === 'function') {
4800 sharedPropertyDefinition.get = shouldCache
4801 ? createComputedGetter(key)
4802 : createGetterInvoker(userDef);
4803 sharedPropertyDefinition.set = noop;
4804 } else {
4805 sharedPropertyDefinition.get = userDef.get
4806 ? shouldCache && userDef.cache !== false
4807 ? createComputedGetter(key)
4808 : createGetterInvoker(userDef.get)
4809 : noop;
4810 sharedPropertyDefinition.set = userDef.set || noop;
4811 }
4812 if (sharedPropertyDefinition.set === noop) {
4813 sharedPropertyDefinition.set = function () {
4814 warn(
4815 `Computed property "${key}" was assigned to but it has no setter.`,
4816 this
4817 );
4818 };
4819 }
4820 Object.defineProperty(target, key, sharedPropertyDefinition);
4821}
4822
4823function createComputedGetter (key) {
4824 return function computedGetter () {
4825 const watcher = this._computedWatchers && this._computedWatchers[key];
4826 if (watcher) {
4827 if (watcher.dirty) {
4828 watcher.evaluate();
4829 }
4830 if (Dep.target) {
4831 watcher.depend();
4832 }
4833 return watcher.value
4834 }
4835 }
4836}
4837
4838function createGetterInvoker(fn) {
4839 return function computedGetter () {
4840 return fn.call(this, this)
4841 }
4842}
4843
4844function initMethods (vm, methods) {
4845 const props = vm.$options.props;
4846 for (const key in methods) {
4847 {
4848 if (typeof methods[key] !== 'function') {
4849 warn(
4850 `Method "${key}" has type "${typeof methods[key]}" in the component definition. ` +
4851 `Did you reference the function correctly?`,
4852 vm
4853 );
4854 }
4855 if (props && hasOwn(props, key)) {
4856 warn(
4857 `Method "${key}" has already been defined as a prop.`,
4858 vm
4859 );
4860 }
4861 if ((key in vm) && isReserved(key)) {
4862 warn(
4863 `Method "${key}" conflicts with an existing Vue instance method. ` +
4864 `Avoid defining component methods that start with _ or $.`
4865 );
4866 }
4867 }
4868 vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm);
4869 }
4870}
4871
4872function initWatch (vm, watch) {
4873 for (const key in watch) {
4874 const handler = watch[key];
4875 if (Array.isArray(handler)) {
4876 for (let i = 0; i < handler.length; i++) {
4877 createWatcher(vm, key, handler[i]);
4878 }
4879 } else {
4880 createWatcher(vm, key, handler);
4881 }
4882 }
4883}
4884
4885function createWatcher (
4886 vm,
4887 expOrFn,
4888 handler,
4889 options
4890) {
4891 if (isPlainObject(handler)) {
4892 options = handler;
4893 handler = handler.handler;
4894 }
4895 if (typeof handler === 'string') {
4896 handler = vm[handler];
4897 }
4898 return vm.$watch(expOrFn, handler, options)
4899}
4900
4901function stateMixin (Vue) {
4902 // flow somehow has problems with directly declared definition object
4903 // when using Object.defineProperty, so we have to procedurally build up
4904 // the object here.
4905 const dataDef = {};
4906 dataDef.get = function () { return this._data };
4907 const propsDef = {};
4908 propsDef.get = function () { return this._props };
4909 {
4910 dataDef.set = function () {
4911 warn(
4912 'Avoid replacing instance root $data. ' +
4913 'Use nested data properties instead.',
4914 this
4915 );
4916 };
4917 propsDef.set = function () {
4918 warn(`$props is readonly.`, this);
4919 };
4920 }
4921 Object.defineProperty(Vue.prototype, '$data', dataDef);
4922 Object.defineProperty(Vue.prototype, '$props', propsDef);
4923
4924 Vue.prototype.$set = set;
4925 Vue.prototype.$delete = del;
4926
4927 Vue.prototype.$watch = function (
4928 expOrFn,
4929 cb,
4930 options
4931 ) {
4932 const vm = this;
4933 if (isPlainObject(cb)) {
4934 return createWatcher(vm, expOrFn, cb, options)
4935 }
4936 options = options || {};
4937 options.user = true;
4938 const watcher = new Watcher(vm, expOrFn, cb, options);
4939 if (options.immediate) {
4940 try {
4941 cb.call(vm, watcher.value);
4942 } catch (error) {
4943 handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`);
4944 }
4945 }
4946 return function unwatchFn () {
4947 watcher.teardown();
4948 }
4949 };
4950}
4951
4952/* */
4953
4954let uid$3 = 0;
4955
4956function initMixin (Vue) {
4957 Vue.prototype._init = function (options) {
4958 const vm = this;
4959 // a uid
4960 vm._uid = uid$3++;
4961
4962 let startTag, endTag;
4963 /* istanbul ignore if */
4964 if (config.performance && mark) {
4965 startTag = `vue-perf-start:${vm._uid}`;
4966 endTag = `vue-perf-end:${vm._uid}`;
4967 mark(startTag);
4968 }
4969
4970 // a flag to avoid this being observed
4971 vm._isVue = true;
4972 // merge options
4973 if (options && options._isComponent) {
4974 // optimize internal component instantiation
4975 // since dynamic options merging is pretty slow, and none of the
4976 // internal component options needs special treatment.
4977 initInternalComponent(vm, options);
4978 } else {
4979 vm.$options = mergeOptions(
4980 resolveConstructorOptions(vm.constructor),
4981 options || {},
4982 vm
4983 );
4984 }
4985 /* istanbul ignore else */
4986 {
4987 initProxy(vm);
4988 }
4989 // expose real self
4990 vm._self = vm;
4991 initLifecycle(vm);
4992 initEvents(vm);
4993 initRender(vm);
4994 callHook(vm, 'beforeCreate');
4995 initInjections(vm); // resolve injections before data/props
4996 initState(vm);
4997 initProvide(vm); // resolve provide after data/props
4998 callHook(vm, 'created');
4999
5000 /* istanbul ignore if */
5001 if (config.performance && mark) {
5002 vm._name = formatComponentName(vm, false);
5003 mark(endTag);
5004 measure(`vue ${vm._name} init`, startTag, endTag);
5005 }
5006
5007 if (vm.$options.el) {
5008 vm.$mount(vm.$options.el);
5009 }
5010 };
5011}
5012
5013function initInternalComponent (vm, options) {
5014 const opts = vm.$options = Object.create(vm.constructor.options);
5015 // doing this because it's faster than dynamic enumeration.
5016 const parentVnode = options._parentVnode;
5017 opts.parent = options.parent;
5018 opts._parentVnode = parentVnode;
5019
5020 const vnodeComponentOptions = parentVnode.componentOptions;
5021 opts.propsData = vnodeComponentOptions.propsData;
5022 opts._parentListeners = vnodeComponentOptions.listeners;
5023 opts._renderChildren = vnodeComponentOptions.children;
5024 opts._componentTag = vnodeComponentOptions.tag;
5025
5026 if (options.render) {
5027 opts.render = options.render;
5028 opts.staticRenderFns = options.staticRenderFns;
5029 }
5030}
5031
5032function resolveConstructorOptions (Ctor) {
5033 let options = Ctor.options;
5034 if (Ctor.super) {
5035 const superOptions = resolveConstructorOptions(Ctor.super);
5036 const cachedSuperOptions = Ctor.superOptions;
5037 if (superOptions !== cachedSuperOptions) {
5038 // super option changed,
5039 // need to resolve new options.
5040 Ctor.superOptions = superOptions;
5041 // check if there are any late-modified/attached options (#4976)
5042 const modifiedOptions = resolveModifiedOptions(Ctor);
5043 // update base extend options
5044 if (modifiedOptions) {
5045 extend(Ctor.extendOptions, modifiedOptions);
5046 }
5047 options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);
5048 if (options.name) {
5049 options.components[options.name] = Ctor;
5050 }
5051 }
5052 }
5053 return options
5054}
5055
5056function resolveModifiedOptions (Ctor) {
5057 let modified;
5058 const latest = Ctor.options;
5059 const sealed = Ctor.sealedOptions;
5060 for (const key in latest) {
5061 if (latest[key] !== sealed[key]) {
5062 if (!modified) modified = {};
5063 modified[key] = latest[key];
5064 }
5065 }
5066 return modified
5067}
5068
5069function Vue (options) {
5070 if (!(this instanceof Vue)
5071 ) {
5072 warn('Vue is a constructor and should be called with the `new` keyword');
5073 }
5074 this._init(options);
5075}
5076
5077initMixin(Vue);
5078stateMixin(Vue);
5079eventsMixin(Vue);
5080lifecycleMixin(Vue);
5081renderMixin(Vue);
5082
5083/* */
5084
5085function initUse (Vue) {
5086 Vue.use = function (plugin) {
5087 const installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
5088 if (installedPlugins.indexOf(plugin) > -1) {
5089 return this
5090 }
5091
5092 // additional parameters
5093 const args = toArray(arguments, 1);
5094 args.unshift(this);
5095 if (typeof plugin.install === 'function') {
5096 plugin.install.apply(plugin, args);
5097 } else if (typeof plugin === 'function') {
5098 plugin.apply(null, args);
5099 }
5100 installedPlugins.push(plugin);
5101 return this
5102 };
5103}
5104
5105/* */
5106
5107function initMixin$1 (Vue) {
5108 Vue.mixin = function (mixin) {
5109 this.options = mergeOptions(this.options, mixin);
5110 return this
5111 };
5112}
5113
5114/* */
5115
5116function initExtend (Vue) {
5117 /**
5118 * Each instance constructor, including Vue, has a unique
5119 * cid. This enables us to create wrapped "child
5120 * constructors" for prototypal inheritance and cache them.
5121 */
5122 Vue.cid = 0;
5123 let cid = 1;
5124
5125 /**
5126 * Class inheritance
5127 */
5128 Vue.extend = function (extendOptions) {
5129 extendOptions = extendOptions || {};
5130 const Super = this;
5131 const SuperId = Super.cid;
5132 const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
5133 if (cachedCtors[SuperId]) {
5134 return cachedCtors[SuperId]
5135 }
5136
5137 const name = extendOptions.name || Super.options.name;
5138 if (name) {
5139 validateComponentName(name);
5140 }
5141
5142 const Sub = function VueComponent (options) {
5143 this._init(options);
5144 };
5145 Sub.prototype = Object.create(Super.prototype);
5146 Sub.prototype.constructor = Sub;
5147 Sub.cid = cid++;
5148 Sub.options = mergeOptions(
5149 Super.options,
5150 extendOptions
5151 );
5152 Sub['super'] = Super;
5153
5154 // For props and computed properties, we define the proxy getters on
5155 // the Vue instances at extension time, on the extended prototype. This
5156 // avoids Object.defineProperty calls for each instance created.
5157 if (Sub.options.props) {
5158 initProps$1(Sub);
5159 }
5160 if (Sub.options.computed) {
5161 initComputed$1(Sub);
5162 }
5163
5164 // allow further extension/mixin/plugin usage
5165 Sub.extend = Super.extend;
5166 Sub.mixin = Super.mixin;
5167 Sub.use = Super.use;
5168
5169 // create asset registers, so extended classes
5170 // can have their private assets too.
5171 ASSET_TYPES.forEach(function (type) {
5172 Sub[type] = Super[type];
5173 });
5174 // enable recursive self-lookup
5175 if (name) {
5176 Sub.options.components[name] = Sub;
5177 }
5178
5179 // keep a reference to the super options at extension time.
5180 // later at instantiation we can check if Super's options have
5181 // been updated.
5182 Sub.superOptions = Super.options;
5183 Sub.extendOptions = extendOptions;
5184 Sub.sealedOptions = extend({}, Sub.options);
5185
5186 // cache constructor
5187 cachedCtors[SuperId] = Sub;
5188 return Sub
5189 };
5190}
5191
5192function initProps$1 (Comp) {
5193 const props = Comp.options.props;
5194 for (const key in props) {
5195 proxy(Comp.prototype, `_props`, key);
5196 }
5197}
5198
5199function initComputed$1 (Comp) {
5200 const computed = Comp.options.computed;
5201 for (const key in computed) {
5202 defineComputed(Comp.prototype, key, computed[key]);
5203 }
5204}
5205
5206/* */
5207
5208function initAssetRegisters (Vue) {
5209 /**
5210 * Create asset registration methods.
5211 */
5212 ASSET_TYPES.forEach(type => {
5213 Vue[type] = function (
5214 id,
5215 definition
5216 ) {
5217 if (!definition) {
5218 return this.options[type + 's'][id]
5219 } else {
5220 /* istanbul ignore if */
5221 if (type === 'component') {
5222 validateComponentName(id);
5223 }
5224 if (type === 'component' && isPlainObject(definition)) {
5225 definition.name = definition.name || id;
5226 definition = this.options._base.extend(definition);
5227 }
5228 if (type === 'directive' && typeof definition === 'function') {
5229 definition = { bind: definition, update: definition };
5230 }
5231 this.options[type + 's'][id] = definition;
5232 return definition
5233 }
5234 };
5235 });
5236}
5237
5238/* */
5239
5240
5241
5242function getComponentName (opts) {
5243 return opts && (opts.Ctor.options.name || opts.tag)
5244}
5245
5246function matches (pattern, name) {
5247 if (Array.isArray(pattern)) {
5248 return pattern.indexOf(name) > -1
5249 } else if (typeof pattern === 'string') {
5250 return pattern.split(',').indexOf(name) > -1
5251 } else if (isRegExp(pattern)) {
5252 return pattern.test(name)
5253 }
5254 /* istanbul ignore next */
5255 return false
5256}
5257
5258function pruneCache (keepAliveInstance, filter) {
5259 const { cache, keys, _vnode } = keepAliveInstance;
5260 for (const key in cache) {
5261 const cachedNode = cache[key];
5262 if (cachedNode) {
5263 const name = getComponentName(cachedNode.componentOptions);
5264 if (name && !filter(name)) {
5265 pruneCacheEntry(cache, key, keys, _vnode);
5266 }
5267 }
5268 }
5269}
5270
5271function pruneCacheEntry (
5272 cache,
5273 key,
5274 keys,
5275 current
5276) {
5277 const cached$$1 = cache[key];
5278 if (cached$$1 && (!current || cached$$1.tag !== current.tag)) {
5279 cached$$1.componentInstance.$destroy();
5280 }
5281 cache[key] = null;
5282 remove(keys, key);
5283}
5284
5285const patternTypes = [String, RegExp, Array];
5286
5287var KeepAlive = {
5288 name: 'keep-alive',
5289 abstract: true,
5290
5291 props: {
5292 include: patternTypes,
5293 exclude: patternTypes,
5294 max: [String, Number]
5295 },
5296
5297 created () {
5298 this.cache = Object.create(null);
5299 this.keys = [];
5300 },
5301
5302 destroyed () {
5303 for (const key in this.cache) {
5304 pruneCacheEntry(this.cache, key, this.keys);
5305 }
5306 },
5307
5308 mounted () {
5309 this.$watch('include', val => {
5310 pruneCache(this, name => matches(val, name));
5311 });
5312 this.$watch('exclude', val => {
5313 pruneCache(this, name => !matches(val, name));
5314 });
5315 },
5316
5317 render () {
5318 const slot = this.$slots.default;
5319 const vnode = getFirstComponentChild(slot);
5320 const componentOptions = vnode && vnode.componentOptions;
5321 if (componentOptions) {
5322 // check pattern
5323 const name = getComponentName(componentOptions);
5324 const { include, exclude } = this;
5325 if (
5326 // not included
5327 (include && (!name || !matches(include, name))) ||
5328 // excluded
5329 (exclude && name && matches(exclude, name))
5330 ) {
5331 return vnode
5332 }
5333
5334 const { cache, keys } = this;
5335 const key = vnode.key == null
5336 // same constructor may get registered as different local components
5337 // so cid alone is not enough (#3269)
5338 ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
5339 : vnode.key;
5340 if (cache[key]) {
5341 vnode.componentInstance = cache[key].componentInstance;
5342 // make current key freshest
5343 remove(keys, key);
5344 keys.push(key);
5345 } else {
5346 cache[key] = vnode;
5347 keys.push(key);
5348 // prune oldest entry
5349 if (this.max && keys.length > parseInt(this.max)) {
5350 pruneCacheEntry(cache, keys[0], keys, this._vnode);
5351 }
5352 }
5353
5354 vnode.data.keepAlive = true;
5355 }
5356 return vnode || (slot && slot[0])
5357 }
5358};
5359
5360var builtInComponents = {
5361 KeepAlive
5362};
5363
5364/* */
5365
5366function initGlobalAPI (Vue) {
5367 // config
5368 const configDef = {};
5369 configDef.get = () => config;
5370 {
5371 configDef.set = () => {
5372 warn(
5373 'Do not replace the Vue.config object, set individual fields instead.'
5374 );
5375 };
5376 }
5377 Object.defineProperty(Vue, 'config', configDef);
5378
5379 // exposed util methods.
5380 // NOTE: these are not considered part of the public API - avoid relying on
5381 // them unless you are aware of the risk.
5382 Vue.util = {
5383 warn,
5384 extend,
5385 mergeOptions,
5386 defineReactive: defineReactive$$1
5387 };
5388
5389 Vue.set = set;
5390 Vue.delete = del;
5391 Vue.nextTick = nextTick;
5392
5393 // 2.6 explicit observable API
5394 Vue.observable = (obj) => {
5395 observe(obj);
5396 return obj
5397 };
5398
5399 Vue.options = Object.create(null);
5400 ASSET_TYPES.forEach(type => {
5401 Vue.options[type + 's'] = Object.create(null);
5402 });
5403
5404 // this is used to identify the "base" constructor to extend all plain-object
5405 // components with in Weex's multi-instance scenarios.
5406 Vue.options._base = Vue;
5407
5408 extend(Vue.options.components, builtInComponents);
5409
5410 initUse(Vue);
5411 initMixin$1(Vue);
5412 initExtend(Vue);
5413 initAssetRegisters(Vue);
5414}
5415
5416initGlobalAPI(Vue);
5417
5418Object.defineProperty(Vue.prototype, '$isServer', {
5419 get: isServerRendering
5420});
5421
5422Object.defineProperty(Vue.prototype, '$ssrContext', {
5423 get () {
5424 /* istanbul ignore next */
5425 return this.$vnode && this.$vnode.ssrContext
5426 }
5427});
5428
5429// expose FunctionalRenderContext for ssr runtime helper installation
5430Object.defineProperty(Vue, 'FunctionalRenderContext', {
5431 value: FunctionalRenderContext
5432});
5433
5434Vue.version = '2.6.7';
5435
5436/* */
5437
5438// these are reserved for web because they are directly compiled away
5439// during template compilation
5440const isReservedAttr = makeMap('style,class');
5441
5442// attributes that should be using props for binding
5443const acceptValue = makeMap('input,textarea,option,select,progress');
5444const mustUseProp = (tag, type, attr) => {
5445 return (
5446 (attr === 'value' && acceptValue(tag)) && type !== 'button' ||
5447 (attr === 'selected' && tag === 'option') ||
5448 (attr === 'checked' && tag === 'input') ||
5449 (attr === 'muted' && tag === 'video')
5450 )
5451};
5452
5453const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck');
5454
5455const isValidContentEditableValue = makeMap('events,caret,typing,plaintext-only');
5456
5457const convertEnumeratedValue = (key, value) => {
5458 return isFalsyAttrValue(value) || value === 'false'
5459 ? 'false'
5460 // allow arbitrary string value for contenteditable
5461 : key === 'contenteditable' && isValidContentEditableValue(value)
5462 ? value
5463 : 'true'
5464};
5465
5466const isBooleanAttr = makeMap(
5467 'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
5468 'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
5469 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
5470 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
5471 'required,reversed,scoped,seamless,selected,sortable,translate,' +
5472 'truespeed,typemustmatch,visible'
5473);
5474
5475const xlinkNS = 'http://www.w3.org/1999/xlink';
5476
5477const isXlink = (name) => {
5478 return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'
5479};
5480
5481const getXlinkProp = (name) => {
5482 return isXlink(name) ? name.slice(6, name.length) : ''
5483};
5484
5485const isFalsyAttrValue = (val) => {
5486 return val == null || val === false
5487};
5488
5489/* */
5490
5491function genClassForVnode (vnode) {
5492 let data = vnode.data;
5493 let parentNode = vnode;
5494 let childNode = vnode;
5495 while (isDef(childNode.componentInstance)) {
5496 childNode = childNode.componentInstance._vnode;
5497 if (childNode && childNode.data) {
5498 data = mergeClassData(childNode.data, data);
5499 }
5500 }
5501 while (isDef(parentNode = parentNode.parent)) {
5502 if (parentNode && parentNode.data) {
5503 data = mergeClassData(data, parentNode.data);
5504 }
5505 }
5506 return renderClass(data.staticClass, data.class)
5507}
5508
5509function mergeClassData (child, parent) {
5510 return {
5511 staticClass: concat(child.staticClass, parent.staticClass),
5512 class: isDef(child.class)
5513 ? [child.class, parent.class]
5514 : parent.class
5515 }
5516}
5517
5518function renderClass (
5519 staticClass,
5520 dynamicClass
5521) {
5522 if (isDef(staticClass) || isDef(dynamicClass)) {
5523 return concat(staticClass, stringifyClass(dynamicClass))
5524 }
5525 /* istanbul ignore next */
5526 return ''
5527}
5528
5529function concat (a, b) {
5530 return a ? b ? (a + ' ' + b) : a : (b || '')
5531}
5532
5533function stringifyClass (value) {
5534 if (Array.isArray(value)) {
5535 return stringifyArray(value)
5536 }
5537 if (isObject(value)) {
5538 return stringifyObject(value)
5539 }
5540 if (typeof value === 'string') {
5541 return value
5542 }
5543 /* istanbul ignore next */
5544 return ''
5545}
5546
5547function stringifyArray (value) {
5548 let res = '';
5549 let stringified;
5550 for (let i = 0, l = value.length; i < l; i++) {
5551 if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') {
5552 if (res) res += ' ';
5553 res += stringified;
5554 }
5555 }
5556 return res
5557}
5558
5559function stringifyObject (value) {
5560 let res = '';
5561 for (const key in value) {
5562 if (value[key]) {
5563 if (res) res += ' ';
5564 res += key;
5565 }
5566 }
5567 return res
5568}
5569
5570/* */
5571
5572const namespaceMap = {
5573 svg: 'http://www.w3.org/2000/svg',
5574 math: 'http://www.w3.org/1998/Math/MathML'
5575};
5576
5577const isHTMLTag = makeMap(
5578 'html,body,base,head,link,meta,style,title,' +
5579 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
5580 'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
5581 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
5582 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
5583 'embed,object,param,source,canvas,script,noscript,del,ins,' +
5584 'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
5585 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
5586 'output,progress,select,textarea,' +
5587 'details,dialog,menu,menuitem,summary,' +
5588 'content,element,shadow,template,blockquote,iframe,tfoot'
5589);
5590
5591// this map is intentionally selective, only covering SVG elements that may
5592// contain child elements.
5593const isSVG = makeMap(
5594 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
5595 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
5596 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
5597 true
5598);
5599
5600const isPreTag = (tag) => tag === 'pre';
5601
5602const isReservedTag = (tag) => {
5603 return isHTMLTag(tag) || isSVG(tag)
5604};
5605
5606function getTagNamespace (tag) {
5607 if (isSVG(tag)) {
5608 return 'svg'
5609 }
5610 // basic support for MathML
5611 // note it doesn't support other MathML elements being component roots
5612 if (tag === 'math') {
5613 return 'math'
5614 }
5615}
5616
5617const unknownElementCache = Object.create(null);
5618function isUnknownElement (tag) {
5619 /* istanbul ignore if */
5620 if (!inBrowser) {
5621 return true
5622 }
5623 if (isReservedTag(tag)) {
5624 return false
5625 }
5626 tag = tag.toLowerCase();
5627 /* istanbul ignore if */
5628 if (unknownElementCache[tag] != null) {
5629 return unknownElementCache[tag]
5630 }
5631 const el = document.createElement(tag);
5632 if (tag.indexOf('-') > -1) {
5633 // http://stackoverflow.com/a/28210364/1070244
5634 return (unknownElementCache[tag] = (
5635 el.constructor === window.HTMLUnknownElement ||
5636 el.constructor === window.HTMLElement
5637 ))
5638 } else {
5639 return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString()))
5640 }
5641}
5642
5643const isTextInputType = makeMap('text,number,password,search,email,tel,url');
5644
5645/* */
5646
5647/**
5648 * Query an element selector if it's not an element already.
5649 */
5650function query (el) {
5651 if (typeof el === 'string') {
5652 const selected = document.querySelector(el);
5653 if (!selected) {
5654 warn(
5655 'Cannot find element: ' + el
5656 );
5657 return document.createElement('div')
5658 }
5659 return selected
5660 } else {
5661 return el
5662 }
5663}
5664
5665/* */
5666
5667function createElement$1 (tagName, vnode) {
5668 const elm = document.createElement(tagName);
5669 if (tagName !== 'select') {
5670 return elm
5671 }
5672 // false or null will remove the attribute but undefined will not
5673 if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) {
5674 elm.setAttribute('multiple', 'multiple');
5675 }
5676 return elm
5677}
5678
5679function createElementNS (namespace, tagName) {
5680 return document.createElementNS(namespaceMap[namespace], tagName)
5681}
5682
5683function createTextNode (text) {
5684 return document.createTextNode(text)
5685}
5686
5687function createComment (text) {
5688 return document.createComment(text)
5689}
5690
5691function insertBefore (parentNode, newNode, referenceNode) {
5692 parentNode.insertBefore(newNode, referenceNode);
5693}
5694
5695function removeChild (node, child) {
5696 node.removeChild(child);
5697}
5698
5699function appendChild (node, child) {
5700 node.appendChild(child);
5701}
5702
5703function parentNode (node) {
5704 return node.parentNode
5705}
5706
5707function nextSibling (node) {
5708 return node.nextSibling
5709}
5710
5711function tagName (node) {
5712 return node.tagName
5713}
5714
5715function setTextContent (node, text) {
5716 node.textContent = text;
5717}
5718
5719function setStyleScope (node, scopeId) {
5720 node.setAttribute(scopeId, '');
5721}
5722
5723var nodeOps = /*#__PURE__*/Object.freeze({
5724 createElement: createElement$1,
5725 createElementNS: createElementNS,
5726 createTextNode: createTextNode,
5727 createComment: createComment,
5728 insertBefore: insertBefore,
5729 removeChild: removeChild,
5730 appendChild: appendChild,
5731 parentNode: parentNode,
5732 nextSibling: nextSibling,
5733 tagName: tagName,
5734 setTextContent: setTextContent,
5735 setStyleScope: setStyleScope
5736});
5737
5738/* */
5739
5740var ref = {
5741 create (_, vnode) {
5742 registerRef(vnode);
5743 },
5744 update (oldVnode, vnode) {
5745 if (oldVnode.data.ref !== vnode.data.ref) {
5746 registerRef(oldVnode, true);
5747 registerRef(vnode);
5748 }
5749 },
5750 destroy (vnode) {
5751 registerRef(vnode, true);
5752 }
5753};
5754
5755function registerRef (vnode, isRemoval) {
5756 const key = vnode.data.ref;
5757 if (!isDef(key)) return
5758
5759 const vm = vnode.context;
5760 const ref = vnode.componentInstance || vnode.elm;
5761 const refs = vm.$refs;
5762 if (isRemoval) {
5763 if (Array.isArray(refs[key])) {
5764 remove(refs[key], ref);
5765 } else if (refs[key] === ref) {
5766 refs[key] = undefined;
5767 }
5768 } else {
5769 if (vnode.data.refInFor) {
5770 if (!Array.isArray(refs[key])) {
5771 refs[key] = [ref];
5772 } else if (refs[key].indexOf(ref) < 0) {
5773 // $flow-disable-line
5774 refs[key].push(ref);
5775 }
5776 } else {
5777 refs[key] = ref;
5778 }
5779 }
5780}
5781
5782/**
5783 * Virtual DOM patching algorithm based on Snabbdom by
5784 * Simon Friis Vindum (@paldepind)
5785 * Licensed under the MIT License
5786 * https://github.com/paldepind/snabbdom/blob/master/LICENSE
5787 *
5788 * modified by Evan You (@yyx990803)
5789 *
5790 * Not type-checking this because this file is perf-critical and the cost
5791 * of making flow understand it is not worth it.
5792 */
5793
5794const emptyNode = new VNode('', {}, []);
5795
5796const hooks = ['create', 'activate', 'update', 'remove', 'destroy'];
5797
5798function sameVnode (a, b) {
5799 return (
5800 a.key === b.key && (
5801 (
5802 a.tag === b.tag &&
5803 a.isComment === b.isComment &&
5804 isDef(a.data) === isDef(b.data) &&
5805 sameInputType(a, b)
5806 ) || (
5807 isTrue(a.isAsyncPlaceholder) &&
5808 a.asyncFactory === b.asyncFactory &&
5809 isUndef(b.asyncFactory.error)
5810 )
5811 )
5812 )
5813}
5814
5815function sameInputType (a, b) {
5816 if (a.tag !== 'input') return true
5817 let i;
5818 const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type;
5819 const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type;
5820 return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
5821}
5822
5823function createKeyToOldIdx (children, beginIdx, endIdx) {
5824 let i, key;
5825 const map = {};
5826 for (i = beginIdx; i <= endIdx; ++i) {
5827 key = children[i].key;
5828 if (isDef(key)) map[key] = i;
5829 }
5830 return map
5831}
5832
5833function createPatchFunction (backend) {
5834 let i, j;
5835 const cbs = {};
5836
5837 const { modules, nodeOps } = backend;
5838
5839 for (i = 0; i < hooks.length; ++i) {
5840 cbs[hooks[i]] = [];
5841 for (j = 0; j < modules.length; ++j) {
5842 if (isDef(modules[j][hooks[i]])) {
5843 cbs[hooks[i]].push(modules[j][hooks[i]]);
5844 }
5845 }
5846 }
5847
5848 function emptyNodeAt (elm) {
5849 return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
5850 }
5851
5852 function createRmCb (childElm, listeners) {
5853 function remove$$1 () {
5854 if (--remove$$1.listeners === 0) {
5855 removeNode(childElm);
5856 }
5857 }
5858 remove$$1.listeners = listeners;
5859 return remove$$1
5860 }
5861
5862 function removeNode (el) {
5863 const parent = nodeOps.parentNode(el);
5864 // element may have already been removed due to v-html / v-text
5865 if (isDef(parent)) {
5866 nodeOps.removeChild(parent, el);
5867 }
5868 }
5869
5870 function isUnknownElement$$1 (vnode, inVPre) {
5871 return (
5872 !inVPre &&
5873 !vnode.ns &&
5874 !(
5875 config.ignoredElements.length &&
5876 config.ignoredElements.some(ignore => {
5877 return isRegExp(ignore)
5878 ? ignore.test(vnode.tag)
5879 : ignore === vnode.tag
5880 })
5881 ) &&
5882 config.isUnknownElement(vnode.tag)
5883 )
5884 }
5885
5886 let creatingElmInVPre = 0;
5887
5888 function createElm (
5889 vnode,
5890 insertedVnodeQueue,
5891 parentElm,
5892 refElm,
5893 nested,
5894 ownerArray,
5895 index
5896 ) {
5897 if (isDef(vnode.elm) && isDef(ownerArray)) {
5898 // This vnode was used in a previous render!
5899 // now it's used as a new node, overwriting its elm would cause
5900 // potential patch errors down the road when it's used as an insertion
5901 // reference node. Instead, we clone the node on-demand before creating
5902 // associated DOM element for it.
5903 vnode = ownerArray[index] = cloneVNode(vnode);
5904 }
5905
5906 vnode.isRootInsert = !nested; // for transition enter check
5907 if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
5908 return
5909 }
5910
5911 const data = vnode.data;
5912 const children = vnode.children;
5913 const tag = vnode.tag;
5914 if (isDef(tag)) {
5915 {
5916 if (data && data.pre) {
5917 creatingElmInVPre++;
5918 }
5919 if (isUnknownElement$$1(vnode, creatingElmInVPre)) {
5920 warn(
5921 'Unknown custom element: <' + tag + '> - did you ' +
5922 'register the component correctly? For recursive components, ' +
5923 'make sure to provide the "name" option.',
5924 vnode.context
5925 );
5926 }
5927 }
5928
5929 vnode.elm = vnode.ns
5930 ? nodeOps.createElementNS(vnode.ns, tag)
5931 : nodeOps.createElement(tag, vnode);
5932 setScope(vnode);
5933
5934 /* istanbul ignore if */
5935 {
5936 createChildren(vnode, children, insertedVnodeQueue);
5937 if (isDef(data)) {
5938 invokeCreateHooks(vnode, insertedVnodeQueue);
5939 }
5940 insert(parentElm, vnode.elm, refElm);
5941 }
5942
5943 if (data && data.pre) {
5944 creatingElmInVPre--;
5945 }
5946 } else if (isTrue(vnode.isComment)) {
5947 vnode.elm = nodeOps.createComment(vnode.text);
5948 insert(parentElm, vnode.elm, refElm);
5949 } else {
5950 vnode.elm = nodeOps.createTextNode(vnode.text);
5951 insert(parentElm, vnode.elm, refElm);
5952 }
5953 }
5954
5955 function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
5956 let i = vnode.data;
5957 if (isDef(i)) {
5958 const isReactivated = isDef(vnode.componentInstance) && i.keepAlive;
5959 if (isDef(i = i.hook) && isDef(i = i.init)) {
5960 i(vnode, false /* hydrating */);
5961 }
5962 // after calling the init hook, if the vnode is a child component
5963 // it should've created a child instance and mounted it. the child
5964 // component also has set the placeholder vnode's elm.
5965 // in that case we can just return the element and be done.
5966 if (isDef(vnode.componentInstance)) {
5967 initComponent(vnode, insertedVnodeQueue);
5968 insert(parentElm, vnode.elm, refElm);
5969 if (isTrue(isReactivated)) {
5970 reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);
5971 }
5972 return true
5973 }
5974 }
5975 }
5976
5977 function initComponent (vnode, insertedVnodeQueue) {
5978 if (isDef(vnode.data.pendingInsert)) {
5979 insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);
5980 vnode.data.pendingInsert = null;
5981 }
5982 vnode.elm = vnode.componentInstance.$el;
5983 if (isPatchable(vnode)) {
5984 invokeCreateHooks(vnode, insertedVnodeQueue);
5985 setScope(vnode);
5986 } else {
5987 // empty component root.
5988 // skip all element-related modules except for ref (#3455)
5989 registerRef(vnode);
5990 // make sure to invoke the insert hook
5991 insertedVnodeQueue.push(vnode);
5992 }
5993 }
5994
5995 function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
5996 let i;
5997 // hack for #4339: a reactivated component with inner transition
5998 // does not trigger because the inner node's created hooks are not called
5999 // again. It's not ideal to involve module-specific logic in here but
6000 // there doesn't seem to be a better way to do it.
6001 let innerNode = vnode;
6002 while (innerNode.componentInstance) {
6003 innerNode = innerNode.componentInstance._vnode;
6004 if (isDef(i = innerNode.data) && isDef(i = i.transition)) {
6005 for (i = 0; i < cbs.activate.length; ++i) {
6006 cbs.activate[i](emptyNode, innerNode);
6007 }
6008 insertedVnodeQueue.push(innerNode);
6009 break
6010 }
6011 }
6012 // unlike a newly created component,
6013 // a reactivated keep-alive component doesn't insert itself
6014 insert(parentElm, vnode.elm, refElm);
6015 }
6016
6017 function insert (parent, elm, ref$$1) {
6018 if (isDef(parent)) {
6019 if (isDef(ref$$1)) {
6020 if (nodeOps.parentNode(ref$$1) === parent) {
6021 nodeOps.insertBefore(parent, elm, ref$$1);
6022 }
6023 } else {
6024 nodeOps.appendChild(parent, elm);
6025 }
6026 }
6027 }
6028
6029 function createChildren (vnode, children, insertedVnodeQueue) {
6030 if (Array.isArray(children)) {
6031 {
6032 checkDuplicateKeys(children);
6033 }
6034 for (let i = 0; i < children.length; ++i) {
6035 createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i);
6036 }
6037 } else if (isPrimitive(vnode.text)) {
6038 nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)));
6039 }
6040 }
6041
6042 function isPatchable (vnode) {
6043 while (vnode.componentInstance) {
6044 vnode = vnode.componentInstance._vnode;
6045 }
6046 return isDef(vnode.tag)
6047 }
6048
6049 function invokeCreateHooks (vnode, insertedVnodeQueue) {
6050 for (let i = 0; i < cbs.create.length; ++i) {
6051 cbs.create[i](emptyNode, vnode);
6052 }
6053 i = vnode.data.hook; // Reuse variable
6054 if (isDef(i)) {
6055 if (isDef(i.create)) i.create(emptyNode, vnode);
6056 if (isDef(i.insert)) insertedVnodeQueue.push(vnode);
6057 }
6058 }
6059
6060 // set scope id attribute for scoped CSS.
6061 // this is implemented as a special case to avoid the overhead
6062 // of going through the normal attribute patching process.
6063 function setScope (vnode) {
6064 let i;
6065 if (isDef(i = vnode.fnScopeId)) {
6066 nodeOps.setStyleScope(vnode.elm, i);
6067 } else {
6068 let ancestor = vnode;
6069 while (ancestor) {
6070 if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {
6071 nodeOps.setStyleScope(vnode.elm, i);
6072 }
6073 ancestor = ancestor.parent;
6074 }
6075 }
6076 // for slot content they should also get the scopeId from the host instance.
6077 if (isDef(i = activeInstance) &&
6078 i !== vnode.context &&
6079 i !== vnode.fnContext &&
6080 isDef(i = i.$options._scopeId)
6081 ) {
6082 nodeOps.setStyleScope(vnode.elm, i);
6083 }
6084 }
6085
6086 function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {
6087 for (; startIdx <= endIdx; ++startIdx) {
6088 createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx);
6089 }
6090 }
6091
6092 function invokeDestroyHook (vnode) {
6093 let i, j;
6094 const data = vnode.data;
6095 if (isDef(data)) {
6096 if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode);
6097 for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode);
6098 }
6099 if (isDef(i = vnode.children)) {
6100 for (j = 0; j < vnode.children.length; ++j) {
6101 invokeDestroyHook(vnode.children[j]);
6102 }
6103 }
6104 }
6105
6106 function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
6107 for (; startIdx <= endIdx; ++startIdx) {
6108 const ch = vnodes[startIdx];
6109 if (isDef(ch)) {
6110 if (isDef(ch.tag)) {
6111 removeAndInvokeRemoveHook(ch);
6112 invokeDestroyHook(ch);
6113 } else { // Text node
6114 removeNode(ch.elm);
6115 }
6116 }
6117 }
6118 }
6119
6120 function removeAndInvokeRemoveHook (vnode, rm) {
6121 if (isDef(rm) || isDef(vnode.data)) {
6122 let i;
6123 const listeners = cbs.remove.length + 1;
6124 if (isDef(rm)) {
6125 // we have a recursively passed down rm callback
6126 // increase the listeners count
6127 rm.listeners += listeners;
6128 } else {
6129 // directly removing
6130 rm = createRmCb(vnode.elm, listeners);
6131 }
6132 // recursively invoke hooks on child component root node
6133 if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {
6134 removeAndInvokeRemoveHook(i, rm);
6135 }
6136 for (i = 0; i < cbs.remove.length; ++i) {
6137 cbs.remove[i](vnode, rm);
6138 }
6139 if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {
6140 i(vnode, rm);
6141 } else {
6142 rm();
6143 }
6144 } else {
6145 removeNode(vnode.elm);
6146 }
6147 }
6148
6149 function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
6150 let oldStartIdx = 0;
6151 let newStartIdx = 0;
6152 let oldEndIdx = oldCh.length - 1;
6153 let oldStartVnode = oldCh[0];
6154 let oldEndVnode = oldCh[oldEndIdx];
6155 let newEndIdx = newCh.length - 1;
6156 let newStartVnode = newCh[0];
6157 let newEndVnode = newCh[newEndIdx];
6158 let oldKeyToIdx, idxInOld, vnodeToMove, refElm;
6159
6160 // removeOnly is a special flag used only by <transition-group>
6161 // to ensure removed elements stay in correct relative positions
6162 // during leaving transitions
6163 const canMove = !removeOnly;
6164
6165 {
6166 checkDuplicateKeys(newCh);
6167 }
6168
6169 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
6170 if (isUndef(oldStartVnode)) {
6171 oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left
6172 } else if (isUndef(oldEndVnode)) {
6173 oldEndVnode = oldCh[--oldEndIdx];
6174 } else if (sameVnode(oldStartVnode, newStartVnode)) {
6175 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
6176 oldStartVnode = oldCh[++oldStartIdx];
6177 newStartVnode = newCh[++newStartIdx];
6178 } else if (sameVnode(oldEndVnode, newEndVnode)) {
6179 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx);
6180 oldEndVnode = oldCh[--oldEndIdx];
6181 newEndVnode = newCh[--newEndIdx];
6182 } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
6183 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx);
6184 canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));
6185 oldStartVnode = oldCh[++oldStartIdx];
6186 newEndVnode = newCh[--newEndIdx];
6187 } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
6188 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
6189 canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
6190 oldEndVnode = oldCh[--oldEndIdx];
6191 newStartVnode = newCh[++newStartIdx];
6192 } else {
6193 if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
6194 idxInOld = isDef(newStartVnode.key)
6195 ? oldKeyToIdx[newStartVnode.key]
6196 : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);
6197 if (isUndef(idxInOld)) { // New element
6198 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx);
6199 } else {
6200 vnodeToMove = oldCh[idxInOld];
6201 if (sameVnode(vnodeToMove, newStartVnode)) {
6202 patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
6203 oldCh[idxInOld] = undefined;
6204 canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm);
6205 } else {
6206 // same key but different element. treat as new element
6207 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx);
6208 }
6209 }
6210 newStartVnode = newCh[++newStartIdx];
6211 }
6212 }
6213 if (oldStartIdx > oldEndIdx) {
6214 refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;
6215 addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
6216 } else if (newStartIdx > newEndIdx) {
6217 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
6218 }
6219 }
6220
6221 function checkDuplicateKeys (children) {
6222 const seenKeys = {};
6223 for (let i = 0; i < children.length; i++) {
6224 const vnode = children[i];
6225 const key = vnode.key;
6226 if (isDef(key)) {
6227 if (seenKeys[key]) {
6228 warn(
6229 `Duplicate keys detected: '${key}'. This may cause an update error.`,
6230 vnode.context
6231 );
6232 } else {
6233 seenKeys[key] = true;
6234 }
6235 }
6236 }
6237 }
6238
6239 function findIdxInOld (node, oldCh, start, end) {
6240 for (let i = start; i < end; i++) {
6241 const c = oldCh[i];
6242 if (isDef(c) && sameVnode(node, c)) return i
6243 }
6244 }
6245
6246 function patchVnode (
6247 oldVnode,
6248 vnode,
6249 insertedVnodeQueue,
6250 ownerArray,
6251 index,
6252 removeOnly
6253 ) {
6254 if (oldVnode === vnode) {
6255 return
6256 }
6257
6258 if (isDef(vnode.elm) && isDef(ownerArray)) {
6259 // clone reused vnode
6260 vnode = ownerArray[index] = cloneVNode(vnode);
6261 }
6262
6263 const elm = vnode.elm = oldVnode.elm;
6264
6265 if (isTrue(oldVnode.isAsyncPlaceholder)) {
6266 if (isDef(vnode.asyncFactory.resolved)) {
6267 hydrate(oldVnode.elm, vnode, insertedVnodeQueue);
6268 } else {
6269 vnode.isAsyncPlaceholder = true;
6270 }
6271 return
6272 }
6273
6274 // reuse element for static trees.
6275 // note we only do this if the vnode is cloned -
6276 // if the new node is not cloned it means the render functions have been
6277 // reset by the hot-reload-api and we need to do a proper re-render.
6278 if (isTrue(vnode.isStatic) &&
6279 isTrue(oldVnode.isStatic) &&
6280 vnode.key === oldVnode.key &&
6281 (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
6282 ) {
6283 vnode.componentInstance = oldVnode.componentInstance;
6284 return
6285 }
6286
6287 let i;
6288 const data = vnode.data;
6289 if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
6290 i(oldVnode, vnode);
6291 }
6292
6293 const oldCh = oldVnode.children;
6294 const ch = vnode.children;
6295 if (isDef(data) && isPatchable(vnode)) {
6296 for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode);
6297 if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode);
6298 }
6299 if (isUndef(vnode.text)) {
6300 if (isDef(oldCh) && isDef(ch)) {
6301 if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly);
6302 } else if (isDef(ch)) {
6303 {
6304 checkDuplicateKeys(ch);
6305 }
6306 if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '');
6307 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
6308 } else if (isDef(oldCh)) {
6309 removeVnodes(elm, oldCh, 0, oldCh.length - 1);
6310 } else if (isDef(oldVnode.text)) {
6311 nodeOps.setTextContent(elm, '');
6312 }
6313 } else if (oldVnode.text !== vnode.text) {
6314 nodeOps.setTextContent(elm, vnode.text);
6315 }
6316 if (isDef(data)) {
6317 if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode);
6318 }
6319 }
6320
6321 function invokeInsertHook (vnode, queue, initial) {
6322 // delay insert hooks for component root nodes, invoke them after the
6323 // element is really inserted
6324 if (isTrue(initial) && isDef(vnode.parent)) {
6325 vnode.parent.data.pendingInsert = queue;
6326 } else {
6327 for (let i = 0; i < queue.length; ++i) {
6328 queue[i].data.hook.insert(queue[i]);
6329 }
6330 }
6331 }
6332
6333 let hydrationBailed = false;
6334 // list of modules that can skip create hook during hydration because they
6335 // are already rendered on the client or has no need for initialization
6336 // Note: style is excluded because it relies on initial clone for future
6337 // deep updates (#7063).
6338 const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key');
6339
6340 // Note: this is a browser-only function so we can assume elms are DOM nodes.
6341 function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
6342 let i;
6343 const { tag, data, children } = vnode;
6344 inVPre = inVPre || (data && data.pre);
6345 vnode.elm = elm;
6346
6347 if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
6348 vnode.isAsyncPlaceholder = true;
6349 return true
6350 }
6351 // assert node match
6352 {
6353 if (!assertNodeMatch(elm, vnode, inVPre)) {
6354 return false
6355 }
6356 }
6357 if (isDef(data)) {
6358 if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */);
6359 if (isDef(i = vnode.componentInstance)) {
6360 // child component. it should have hydrated its own tree.
6361 initComponent(vnode, insertedVnodeQueue);
6362 return true
6363 }
6364 }
6365 if (isDef(tag)) {
6366 if (isDef(children)) {
6367 // empty element, allow client to pick up and populate children
6368 if (!elm.hasChildNodes()) {
6369 createChildren(vnode, children, insertedVnodeQueue);
6370 } else {
6371 // v-html and domProps: innerHTML
6372 if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
6373 if (i !== elm.innerHTML) {
6374 /* istanbul ignore if */
6375 if (typeof console !== 'undefined' &&
6376 !hydrationBailed
6377 ) {
6378 hydrationBailed = true;
6379 console.warn('Parent: ', elm);
6380 console.warn('server innerHTML: ', i);
6381 console.warn('client innerHTML: ', elm.innerHTML);
6382 }
6383 return false
6384 }
6385 } else {
6386 // iterate and compare children lists
6387 let childrenMatch = true;
6388 let childNode = elm.firstChild;
6389 for (let i = 0; i < children.length; i++) {
6390 if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {
6391 childrenMatch = false;
6392 break
6393 }
6394 childNode = childNode.nextSibling;
6395 }
6396 // if childNode is not null, it means the actual childNodes list is
6397 // longer than the virtual children list.
6398 if (!childrenMatch || childNode) {
6399 /* istanbul ignore if */
6400 if (typeof console !== 'undefined' &&
6401 !hydrationBailed
6402 ) {
6403 hydrationBailed = true;
6404 console.warn('Parent: ', elm);
6405 console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);
6406 }
6407 return false
6408 }
6409 }
6410 }
6411 }
6412 if (isDef(data)) {
6413 let fullInvoke = false;
6414 for (const key in data) {
6415 if (!isRenderedModule(key)) {
6416 fullInvoke = true;
6417 invokeCreateHooks(vnode, insertedVnodeQueue);
6418 break
6419 }
6420 }
6421 if (!fullInvoke && data['class']) {
6422 // ensure collecting deps for deep class bindings for future updates
6423 traverse(data['class']);
6424 }
6425 }
6426 } else if (elm.data !== vnode.text) {
6427 elm.data = vnode.text;
6428 }
6429 return true
6430 }
6431
6432 function assertNodeMatch (node, vnode, inVPre) {
6433 if (isDef(vnode.tag)) {
6434 return vnode.tag.indexOf('vue-component') === 0 || (
6435 !isUnknownElement$$1(vnode, inVPre) &&
6436 vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())
6437 )
6438 } else {
6439 return node.nodeType === (vnode.isComment ? 8 : 3)
6440 }
6441 }
6442
6443 return function patch (oldVnode, vnode, hydrating, removeOnly) {
6444 if (isUndef(vnode)) {
6445 if (isDef(oldVnode)) invokeDestroyHook(oldVnode);
6446 return
6447 }
6448
6449 let isInitialPatch = false;
6450 const insertedVnodeQueue = [];
6451
6452 if (isUndef(oldVnode)) {
6453 // empty mount (likely as component), create new root element
6454 isInitialPatch = true;
6455 createElm(vnode, insertedVnodeQueue);
6456 } else {
6457 const isRealElement = isDef(oldVnode.nodeType);
6458 if (!isRealElement && sameVnode(oldVnode, vnode)) {
6459 // patch existing root node
6460 patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly);
6461 } else {
6462 if (isRealElement) {
6463 // mounting to a real element
6464 // check if this is server-rendered content and if we can perform
6465 // a successful hydration.
6466 if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
6467 oldVnode.removeAttribute(SSR_ATTR);
6468 hydrating = true;
6469 }
6470 if (isTrue(hydrating)) {
6471 if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
6472 invokeInsertHook(vnode, insertedVnodeQueue, true);
6473 return oldVnode
6474 } else {
6475 warn(
6476 'The client-side rendered virtual DOM tree is not matching ' +
6477 'server-rendered content. This is likely caused by incorrect ' +
6478 'HTML markup, for example nesting block-level elements inside ' +
6479 '<p>, or missing <tbody>. Bailing hydration and performing ' +
6480 'full client-side render.'
6481 );
6482 }
6483 }
6484 // either not server-rendered, or hydration failed.
6485 // create an empty node and replace it
6486 oldVnode = emptyNodeAt(oldVnode);
6487 }
6488
6489 // replacing existing element
6490 const oldElm = oldVnode.elm;
6491 const parentElm = nodeOps.parentNode(oldElm);
6492
6493 // create new node
6494 createElm(
6495 vnode,
6496 insertedVnodeQueue,
6497 // extremely rare edge case: do not insert if old element is in a
6498 // leaving transition. Only happens when combining transition +
6499 // keep-alive + HOCs. (#4590)
6500 oldElm._leaveCb ? null : parentElm,
6501 nodeOps.nextSibling(oldElm)
6502 );
6503
6504 // update parent placeholder node element, recursively
6505 if (isDef(vnode.parent)) {
6506 let ancestor = vnode.parent;
6507 const patchable = isPatchable(vnode);
6508 while (ancestor) {
6509 for (let i = 0; i < cbs.destroy.length; ++i) {
6510 cbs.destroy[i](ancestor);
6511 }
6512 ancestor.elm = vnode.elm;
6513 if (patchable) {
6514 for (let i = 0; i < cbs.create.length; ++i) {
6515 cbs.create[i](emptyNode, ancestor);
6516 }
6517 // #6513
6518 // invoke insert hooks that may have been merged by create hooks.
6519 // e.g. for directives that uses the "inserted" hook.
6520 const insert = ancestor.data.hook.insert;
6521 if (insert.merged) {
6522 // start at index 1 to avoid re-invoking component mounted hook
6523 for (let i = 1; i < insert.fns.length; i++) {
6524 insert.fns[i]();
6525 }
6526 }
6527 } else {
6528 registerRef(ancestor);
6529 }
6530 ancestor = ancestor.parent;
6531 }
6532 }
6533
6534 // destroy old node
6535 if (isDef(parentElm)) {
6536 removeVnodes(parentElm, [oldVnode], 0, 0);
6537 } else if (isDef(oldVnode.tag)) {
6538 invokeDestroyHook(oldVnode);
6539 }
6540 }
6541 }
6542
6543 invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
6544 return vnode.elm
6545 }
6546}
6547
6548/* */
6549
6550var directives = {
6551 create: updateDirectives,
6552 update: updateDirectives,
6553 destroy: function unbindDirectives (vnode) {
6554 updateDirectives(vnode, emptyNode);
6555 }
6556};
6557
6558function updateDirectives (oldVnode, vnode) {
6559 if (oldVnode.data.directives || vnode.data.directives) {
6560 _update(oldVnode, vnode);
6561 }
6562}
6563
6564function _update (oldVnode, vnode) {
6565 const isCreate = oldVnode === emptyNode;
6566 const isDestroy = vnode === emptyNode;
6567 const oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);
6568 const newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);
6569
6570 const dirsWithInsert = [];
6571 const dirsWithPostpatch = [];
6572
6573 let key, oldDir, dir;
6574 for (key in newDirs) {
6575 oldDir = oldDirs[key];
6576 dir = newDirs[key];
6577 if (!oldDir) {
6578 // new directive, bind
6579 callHook$1(dir, 'bind', vnode, oldVnode);
6580 if (dir.def && dir.def.inserted) {
6581 dirsWithInsert.push(dir);
6582 }
6583 } else {
6584 // existing directive, update
6585 dir.oldValue = oldDir.value;
6586 dir.oldArg = oldDir.arg;
6587 callHook$1(dir, 'update', vnode, oldVnode);
6588 if (dir.def && dir.def.componentUpdated) {
6589 dirsWithPostpatch.push(dir);
6590 }
6591 }
6592 }
6593
6594 if (dirsWithInsert.length) {
6595 const callInsert = () => {
6596 for (let i = 0; i < dirsWithInsert.length; i++) {
6597 callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode);
6598 }
6599 };
6600 if (isCreate) {
6601 mergeVNodeHook(vnode, 'insert', callInsert);
6602 } else {
6603 callInsert();
6604 }
6605 }
6606
6607 if (dirsWithPostpatch.length) {
6608 mergeVNodeHook(vnode, 'postpatch', () => {
6609 for (let i = 0; i < dirsWithPostpatch.length; i++) {
6610 callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode);
6611 }
6612 });
6613 }
6614
6615 if (!isCreate) {
6616 for (key in oldDirs) {
6617 if (!newDirs[key]) {
6618 // no longer present, unbind
6619 callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy);
6620 }
6621 }
6622 }
6623}
6624
6625const emptyModifiers = Object.create(null);
6626
6627function normalizeDirectives$1 (
6628 dirs,
6629 vm
6630) {
6631 const res = Object.create(null);
6632 if (!dirs) {
6633 // $flow-disable-line
6634 return res
6635 }
6636 let i, dir;
6637 for (i = 0; i < dirs.length; i++) {
6638 dir = dirs[i];
6639 if (!dir.modifiers) {
6640 // $flow-disable-line
6641 dir.modifiers = emptyModifiers;
6642 }
6643 res[getRawDirName(dir)] = dir;
6644 dir.def = resolveAsset(vm.$options, 'directives', dir.name, true);
6645 }
6646 // $flow-disable-line
6647 return res
6648}
6649
6650function getRawDirName (dir) {
6651 return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}`
6652}
6653
6654function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) {
6655 const fn = dir.def && dir.def[hook];
6656 if (fn) {
6657 try {
6658 fn(vnode.elm, dir, vnode, oldVnode, isDestroy);
6659 } catch (e) {
6660 handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`);
6661 }
6662 }
6663}
6664
6665var baseModules = [
6666 ref,
6667 directives
6668];
6669
6670/* */
6671
6672function updateAttrs (oldVnode, vnode) {
6673 const opts = vnode.componentOptions;
6674 if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) {
6675 return
6676 }
6677 if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) {
6678 return
6679 }
6680 let key, cur, old;
6681 const elm = vnode.elm;
6682 const oldAttrs = oldVnode.data.attrs || {};
6683 let attrs = vnode.data.attrs || {};
6684 // clone observed objects, as the user probably wants to mutate it
6685 if (isDef(attrs.__ob__)) {
6686 attrs = vnode.data.attrs = extend({}, attrs);
6687 }
6688
6689 for (key in attrs) {
6690 cur = attrs[key];
6691 old = oldAttrs[key];
6692 if (old !== cur) {
6693 setAttr(elm, key, cur);
6694 }
6695 }
6696 // #4391: in IE9, setting type can reset value for input[type=radio]
6697 // #6666: IE/Edge forces progress value down to 1 before setting a max
6698 /* istanbul ignore if */
6699 if ((isIE || isEdge) && attrs.value !== oldAttrs.value) {
6700 setAttr(elm, 'value', attrs.value);
6701 }
6702 for (key in oldAttrs) {
6703 if (isUndef(attrs[key])) {
6704 if (isXlink(key)) {
6705 elm.removeAttributeNS(xlinkNS, getXlinkProp(key));
6706 } else if (!isEnumeratedAttr(key)) {
6707 elm.removeAttribute(key);
6708 }
6709 }
6710 }
6711}
6712
6713function setAttr (el, key, value) {
6714 if (el.tagName.indexOf('-') > -1) {
6715 baseSetAttr(el, key, value);
6716 } else if (isBooleanAttr(key)) {
6717 // set attribute for blank value
6718 // e.g. <option disabled>Select one</option>
6719 if (isFalsyAttrValue(value)) {
6720 el.removeAttribute(key);
6721 } else {
6722 // technically allowfullscreen is a boolean attribute for <iframe>,
6723 // but Flash expects a value of "true" when used on <embed> tag
6724 value = key === 'allowfullscreen' && el.tagName === 'EMBED'
6725 ? 'true'
6726 : key;
6727 el.setAttribute(key, value);
6728 }
6729 } else if (isEnumeratedAttr(key)) {
6730 el.setAttribute(key, convertEnumeratedValue(key, value));
6731 } else if (isXlink(key)) {
6732 if (isFalsyAttrValue(value)) {
6733 el.removeAttributeNS(xlinkNS, getXlinkProp(key));
6734 } else {
6735 el.setAttributeNS(xlinkNS, key, value);
6736 }
6737 } else {
6738 baseSetAttr(el, key, value);
6739 }
6740}
6741
6742function baseSetAttr (el, key, value) {
6743 if (isFalsyAttrValue(value)) {
6744 el.removeAttribute(key);
6745 } else {
6746 // #7138: IE10 & 11 fires input event when setting placeholder on
6747 // <textarea>... block the first input event and remove the blocker
6748 // immediately.
6749 /* istanbul ignore if */
6750 if (
6751 isIE && !isIE9 &&
6752 el.tagName === 'TEXTAREA' &&
6753 key === 'placeholder' && value !== '' && !el.__ieph
6754 ) {
6755 const blocker = e => {
6756 e.stopImmediatePropagation();
6757 el.removeEventListener('input', blocker);
6758 };
6759 el.addEventListener('input', blocker);
6760 // $flow-disable-line
6761 el.__ieph = true; /* IE placeholder patched */
6762 }
6763 el.setAttribute(key, value);
6764 }
6765}
6766
6767var attrs = {
6768 create: updateAttrs,
6769 update: updateAttrs
6770};
6771
6772/* */
6773
6774function updateClass (oldVnode, vnode) {
6775 const el = vnode.elm;
6776 const data = vnode.data;
6777 const oldData = oldVnode.data;
6778 if (
6779 isUndef(data.staticClass) &&
6780 isUndef(data.class) && (
6781 isUndef(oldData) || (
6782 isUndef(oldData.staticClass) &&
6783 isUndef(oldData.class)
6784 )
6785 )
6786 ) {
6787 return
6788 }
6789
6790 let cls = genClassForVnode(vnode);
6791
6792 // handle transition classes
6793 const transitionClass = el._transitionClasses;
6794 if (isDef(transitionClass)) {
6795 cls = concat(cls, stringifyClass(transitionClass));
6796 }
6797
6798 // set the class
6799 if (cls !== el._prevClass) {
6800 el.setAttribute('class', cls);
6801 el._prevClass = cls;
6802 }
6803}
6804
6805var klass = {
6806 create: updateClass,
6807 update: updateClass
6808};
6809
6810/* */
6811
6812const validDivisionCharRE = /[\w).+\-_$\]]/;
6813
6814function parseFilters (exp) {
6815 let inSingle = false;
6816 let inDouble = false;
6817 let inTemplateString = false;
6818 let inRegex = false;
6819 let curly = 0;
6820 let square = 0;
6821 let paren = 0;
6822 let lastFilterIndex = 0;
6823 let c, prev, i, expression, filters;
6824
6825 for (i = 0; i < exp.length; i++) {
6826 prev = c;
6827 c = exp.charCodeAt(i);
6828 if (inSingle) {
6829 if (c === 0x27 && prev !== 0x5C) inSingle = false;
6830 } else if (inDouble) {
6831 if (c === 0x22 && prev !== 0x5C) inDouble = false;
6832 } else if (inTemplateString) {
6833 if (c === 0x60 && prev !== 0x5C) inTemplateString = false;
6834 } else if (inRegex) {
6835 if (c === 0x2f && prev !== 0x5C) inRegex = false;
6836 } else if (
6837 c === 0x7C && // pipe
6838 exp.charCodeAt(i + 1) !== 0x7C &&
6839 exp.charCodeAt(i - 1) !== 0x7C &&
6840 !curly && !square && !paren
6841 ) {
6842 if (expression === undefined) {
6843 // first filter, end of expression
6844 lastFilterIndex = i + 1;
6845 expression = exp.slice(0, i).trim();
6846 } else {
6847 pushFilter();
6848 }
6849 } else {
6850 switch (c) {
6851 case 0x22: inDouble = true; break // "
6852 case 0x27: inSingle = true; break // '
6853 case 0x60: inTemplateString = true; break // `
6854 case 0x28: paren++; break // (
6855 case 0x29: paren--; break // )
6856 case 0x5B: square++; break // [
6857 case 0x5D: square--; break // ]
6858 case 0x7B: curly++; break // {
6859 case 0x7D: curly--; break // }
6860 }
6861 if (c === 0x2f) { // /
6862 let j = i - 1;
6863 let p;
6864 // find first non-whitespace prev char
6865 for (; j >= 0; j--) {
6866 p = exp.charAt(j);
6867 if (p !== ' ') break
6868 }
6869 if (!p || !validDivisionCharRE.test(p)) {
6870 inRegex = true;
6871 }
6872 }
6873 }
6874 }
6875
6876 if (expression === undefined) {
6877 expression = exp.slice(0, i).trim();
6878 } else if (lastFilterIndex !== 0) {
6879 pushFilter();
6880 }
6881
6882 function pushFilter () {
6883 (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim());
6884 lastFilterIndex = i + 1;
6885 }
6886
6887 if (filters) {
6888 for (i = 0; i < filters.length; i++) {
6889 expression = wrapFilter(expression, filters[i]);
6890 }
6891 }
6892
6893 return expression
6894}
6895
6896function wrapFilter (exp, filter) {
6897 const i = filter.indexOf('(');
6898 if (i < 0) {
6899 // _f: resolveFilter
6900 return `_f("${filter}")(${exp})`
6901 } else {
6902 const name = filter.slice(0, i);
6903 const args = filter.slice(i + 1);
6904 return `_f("${name}")(${exp}${args !== ')' ? ',' + args : args}`
6905 }
6906}
6907
6908/* */
6909
6910
6911
6912/* eslint-disable no-unused-vars */
6913function baseWarn (msg, range) {
6914 console.error(`[Vue compiler]: ${msg}`);
6915}
6916/* eslint-enable no-unused-vars */
6917
6918function pluckModuleFunction (
6919 modules,
6920 key
6921) {
6922 return modules
6923 ? modules.map(m => m[key]).filter(_ => _)
6924 : []
6925}
6926
6927function addProp (el, name, value, range, dynamic) {
6928 (el.props || (el.props = [])).push(rangeSetItem({ name, value, dynamic }, range));
6929 el.plain = false;
6930}
6931
6932function addAttr (el, name, value, range, dynamic) {
6933 const attrs = dynamic
6934 ? (el.dynamicAttrs || (el.dynamicAttrs = []))
6935 : (el.attrs || (el.attrs = []));
6936 attrs.push(rangeSetItem({ name, value, dynamic }, range));
6937 el.plain = false;
6938}
6939
6940// add a raw attr (use this in preTransforms)
6941function addRawAttr (el, name, value, range) {
6942 el.attrsMap[name] = value;
6943 el.attrsList.push(rangeSetItem({ name, value }, range));
6944}
6945
6946function addDirective (
6947 el,
6948 name,
6949 rawName,
6950 value,
6951 arg,
6952 isDynamicArg,
6953 modifiers,
6954 range
6955) {
6956 (el.directives || (el.directives = [])).push(rangeSetItem({
6957 name,
6958 rawName,
6959 value,
6960 arg,
6961 isDynamicArg,
6962 modifiers
6963 }, range));
6964 el.plain = false;
6965}
6966
6967function prependModifierMarker (symbol, name, dynamic) {
6968 return dynamic
6969 ? `_p(${name},"${symbol}")`
6970 : symbol + name // mark the event as captured
6971}
6972
6973function addHandler (
6974 el,
6975 name,
6976 value,
6977 modifiers,
6978 important,
6979 warn,
6980 range,
6981 dynamic
6982) {
6983 modifiers = modifiers || emptyObject;
6984 // warn prevent and passive modifier
6985 /* istanbul ignore if */
6986 if (
6987 warn &&
6988 modifiers.prevent && modifiers.passive
6989 ) {
6990 warn(
6991 'passive and prevent can\'t be used together. ' +
6992 'Passive handler can\'t prevent default event.',
6993 range
6994 );
6995 }
6996
6997 // normalize click.right and click.middle since they don't actually fire
6998 // this is technically browser-specific, but at least for now browsers are
6999 // the only target envs that have right/middle clicks.
7000 if (modifiers.right) {
7001 if (dynamic) {
7002 name = `(${name})==='click'?'contextmenu':(${name})`;
7003 } else if (name === 'click') {
7004 name = 'contextmenu';
7005 delete modifiers.right;
7006 }
7007 } else if (modifiers.middle) {
7008 if (dynamic) {
7009 name = `(${name})==='click'?'mouseup':(${name})`;
7010 } else if (name === 'click') {
7011 name = 'mouseup';
7012 }
7013 }
7014
7015 // check capture modifier
7016 if (modifiers.capture) {
7017 delete modifiers.capture;
7018 name = prependModifierMarker('!', name, dynamic);
7019 }
7020 if (modifiers.once) {
7021 delete modifiers.once;
7022 name = prependModifierMarker('~', name, dynamic);
7023 }
7024 /* istanbul ignore if */
7025 if (modifiers.passive) {
7026 delete modifiers.passive;
7027 name = prependModifierMarker('&', name, dynamic);
7028 }
7029
7030 let events;
7031 if (modifiers.native) {
7032 delete modifiers.native;
7033 events = el.nativeEvents || (el.nativeEvents = {});
7034 } else {
7035 events = el.events || (el.events = {});
7036 }
7037
7038 const newHandler = rangeSetItem({ value: value.trim(), dynamic }, range);
7039 if (modifiers !== emptyObject) {
7040 newHandler.modifiers = modifiers;
7041 }
7042
7043 const handlers = events[name];
7044 /* istanbul ignore if */
7045 if (Array.isArray(handlers)) {
7046 important ? handlers.unshift(newHandler) : handlers.push(newHandler);
7047 } else if (handlers) {
7048 events[name] = important ? [newHandler, handlers] : [handlers, newHandler];
7049 } else {
7050 events[name] = newHandler;
7051 }
7052
7053 el.plain = false;
7054}
7055
7056function getRawBindingAttr (
7057 el,
7058 name
7059) {
7060 return el.rawAttrsMap[':' + name] ||
7061 el.rawAttrsMap['v-bind:' + name] ||
7062 el.rawAttrsMap[name]
7063}
7064
7065function getBindingAttr (
7066 el,
7067 name,
7068 getStatic
7069) {
7070 const dynamicValue =
7071 getAndRemoveAttr(el, ':' + name) ||
7072 getAndRemoveAttr(el, 'v-bind:' + name);
7073 if (dynamicValue != null) {
7074 return parseFilters(dynamicValue)
7075 } else if (getStatic !== false) {
7076 const staticValue = getAndRemoveAttr(el, name);
7077 if (staticValue != null) {
7078 return JSON.stringify(staticValue)
7079 }
7080 }
7081}
7082
7083// note: this only removes the attr from the Array (attrsList) so that it
7084// doesn't get processed by processAttrs.
7085// By default it does NOT remove it from the map (attrsMap) because the map is
7086// needed during codegen.
7087function getAndRemoveAttr (
7088 el,
7089 name,
7090 removeFromMap
7091) {
7092 let val;
7093 if ((val = el.attrsMap[name]) != null) {
7094 const list = el.attrsList;
7095 for (let i = 0, l = list.length; i < l; i++) {
7096 if (list[i].name === name) {
7097 list.splice(i, 1);
7098 break
7099 }
7100 }
7101 }
7102 if (removeFromMap) {
7103 delete el.attrsMap[name];
7104 }
7105 return val
7106}
7107
7108function getAndRemoveAttrByRegex (
7109 el,
7110 name
7111) {
7112 const list = el.attrsList;
7113 for (let i = 0, l = list.length; i < l; i++) {
7114 const attr = list[i];
7115 if (name.test(attr.name)) {
7116 list.splice(i, 1);
7117 return attr
7118 }
7119 }
7120}
7121
7122function rangeSetItem (
7123 item,
7124 range
7125) {
7126 if (range) {
7127 if (range.start != null) {
7128 item.start = range.start;
7129 }
7130 if (range.end != null) {
7131 item.end = range.end;
7132 }
7133 }
7134 return item
7135}
7136
7137/* */
7138
7139/**
7140 * Cross-platform code generation for component v-model
7141 */
7142function genComponentModel (
7143 el,
7144 value,
7145 modifiers
7146) {
7147 const { number, trim } = modifiers || {};
7148
7149 const baseValueExpression = '$$v';
7150 let valueExpression = baseValueExpression;
7151 if (trim) {
7152 valueExpression =
7153 `(typeof ${baseValueExpression} === 'string'` +
7154 `? ${baseValueExpression}.trim()` +
7155 `: ${baseValueExpression})`;
7156 }
7157 if (number) {
7158 valueExpression = `_n(${valueExpression})`;
7159 }
7160 const assignment = genAssignmentCode(value, valueExpression);
7161
7162 el.model = {
7163 value: `(${value})`,
7164 expression: JSON.stringify(value),
7165 callback: `function (${baseValueExpression}) {${assignment}}`
7166 };
7167}
7168
7169/**
7170 * Cross-platform codegen helper for generating v-model value assignment code.
7171 */
7172function genAssignmentCode (
7173 value,
7174 assignment
7175) {
7176 const res = parseModel(value);
7177 if (res.key === null) {
7178 return `${value}=${assignment}`
7179 } else {
7180 return `$set(${res.exp}, ${res.key}, ${assignment})`
7181 }
7182}
7183
7184/**
7185 * Parse a v-model expression into a base path and a final key segment.
7186 * Handles both dot-path and possible square brackets.
7187 *
7188 * Possible cases:
7189 *
7190 * - test
7191 * - test[key]
7192 * - test[test1[key]]
7193 * - test["a"][key]
7194 * - xxx.test[a[a].test1[key]]
7195 * - test.xxx.a["asa"][test1[key]]
7196 *
7197 */
7198
7199let len, str, chr, index$1, expressionPos, expressionEndPos;
7200
7201
7202
7203function parseModel (val) {
7204 // Fix https://github.com/vuejs/vue/pull/7730
7205 // allow v-model="obj.val " (trailing whitespace)
7206 val = val.trim();
7207 len = val.length;
7208
7209 if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
7210 index$1 = val.lastIndexOf('.');
7211 if (index$1 > -1) {
7212 return {
7213 exp: val.slice(0, index$1),
7214 key: '"' + val.slice(index$1 + 1) + '"'
7215 }
7216 } else {
7217 return {
7218 exp: val,
7219 key: null
7220 }
7221 }
7222 }
7223
7224 str = val;
7225 index$1 = expressionPos = expressionEndPos = 0;
7226
7227 while (!eof()) {
7228 chr = next();
7229 /* istanbul ignore if */
7230 if (isStringStart(chr)) {
7231 parseString(chr);
7232 } else if (chr === 0x5B) {
7233 parseBracket(chr);
7234 }
7235 }
7236
7237 return {
7238 exp: val.slice(0, expressionPos),
7239 key: val.slice(expressionPos + 1, expressionEndPos)
7240 }
7241}
7242
7243function next () {
7244 return str.charCodeAt(++index$1)
7245}
7246
7247function eof () {
7248 return index$1 >= len
7249}
7250
7251function isStringStart (chr) {
7252 return chr === 0x22 || chr === 0x27
7253}
7254
7255function parseBracket (chr) {
7256 let inBracket = 1;
7257 expressionPos = index$1;
7258 while (!eof()) {
7259 chr = next();
7260 if (isStringStart(chr)) {
7261 parseString(chr);
7262 continue
7263 }
7264 if (chr === 0x5B) inBracket++;
7265 if (chr === 0x5D) inBracket--;
7266 if (inBracket === 0) {
7267 expressionEndPos = index$1;
7268 break
7269 }
7270 }
7271}
7272
7273function parseString (chr) {
7274 const stringQuote = chr;
7275 while (!eof()) {
7276 chr = next();
7277 if (chr === stringQuote) {
7278 break
7279 }
7280 }
7281}
7282
7283/* */
7284
7285let warn$1;
7286
7287// in some cases, the event used has to be determined at runtime
7288// so we used some reserved tokens during compile.
7289const RANGE_TOKEN = '__r';
7290const CHECKBOX_RADIO_TOKEN = '__c';
7291
7292function model (
7293 el,
7294 dir,
7295 _warn
7296) {
7297 warn$1 = _warn;
7298 const value = dir.value;
7299 const modifiers = dir.modifiers;
7300 const tag = el.tag;
7301 const type = el.attrsMap.type;
7302
7303 {
7304 // inputs with type="file" are read only and setting the input's
7305 // value will throw an error.
7306 if (tag === 'input' && type === 'file') {
7307 warn$1(
7308 `<${el.tag} v-model="${value}" type="file">:\n` +
7309 `File inputs are read only. Use a v-on:change listener instead.`,
7310 el.rawAttrsMap['v-model']
7311 );
7312 }
7313 }
7314
7315 if (el.component) {
7316 genComponentModel(el, value, modifiers);
7317 // component v-model doesn't need extra runtime
7318 return false
7319 } else if (tag === 'select') {
7320 genSelect(el, value, modifiers);
7321 } else if (tag === 'input' && type === 'checkbox') {
7322 genCheckboxModel(el, value, modifiers);
7323 } else if (tag === 'input' && type === 'radio') {
7324 genRadioModel(el, value, modifiers);
7325 } else if (tag === 'input' || tag === 'textarea') {
7326 genDefaultModel(el, value, modifiers);
7327 } else if (!config.isReservedTag(tag)) {
7328 genComponentModel(el, value, modifiers);
7329 // component v-model doesn't need extra runtime
7330 return false
7331 } else {
7332 warn$1(
7333 `<${el.tag} v-model="${value}">: ` +
7334 `v-model is not supported on this element type. ` +
7335 'If you are working with contenteditable, it\'s recommended to ' +
7336 'wrap a library dedicated for that purpose inside a custom component.',
7337 el.rawAttrsMap['v-model']
7338 );
7339 }
7340
7341 // ensure runtime directive metadata
7342 return true
7343}
7344
7345function genCheckboxModel (
7346 el,
7347 value,
7348 modifiers
7349) {
7350 const number = modifiers && modifiers.number;
7351 const valueBinding = getBindingAttr(el, 'value') || 'null';
7352 const trueValueBinding = getBindingAttr(el, 'true-value') || 'true';
7353 const falseValueBinding = getBindingAttr(el, 'false-value') || 'false';
7354 addProp(el, 'checked',
7355 `Array.isArray(${value})` +
7356 `?_i(${value},${valueBinding})>-1` + (
7357 trueValueBinding === 'true'
7358 ? `:(${value})`
7359 : `:_q(${value},${trueValueBinding})`
7360 )
7361 );
7362 addHandler(el, 'change',
7363 `var $$a=${value},` +
7364 '$$el=$event.target,' +
7365 `$$c=$$el.checked?(${trueValueBinding}):(${falseValueBinding});` +
7366 'if(Array.isArray($$a)){' +
7367 `var $$v=${number ? '_n(' + valueBinding + ')' : valueBinding},` +
7368 '$$i=_i($$a,$$v);' +
7369 `if($$el.checked){$$i<0&&(${genAssignmentCode(value, '$$a.concat([$$v])')})}` +
7370 `else{$$i>-1&&(${genAssignmentCode(value, '$$a.slice(0,$$i).concat($$a.slice($$i+1))')})}` +
7371 `}else{${genAssignmentCode(value, '$$c')}}`,
7372 null, true
7373 );
7374}
7375
7376function genRadioModel (
7377 el,
7378 value,
7379 modifiers
7380) {
7381 const number = modifiers && modifiers.number;
7382 let valueBinding = getBindingAttr(el, 'value') || 'null';
7383 valueBinding = number ? `_n(${valueBinding})` : valueBinding;
7384 addProp(el, 'checked', `_q(${value},${valueBinding})`);
7385 addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true);
7386}
7387
7388function genSelect (
7389 el,
7390 value,
7391 modifiers
7392) {
7393 const number = modifiers && modifiers.number;
7394 const selectedVal = `Array.prototype.filter` +
7395 `.call($event.target.options,function(o){return o.selected})` +
7396 `.map(function(o){var val = "_value" in o ? o._value : o.value;` +
7397 `return ${number ? '_n(val)' : 'val'}})`;
7398
7399 const assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';
7400 let code = `var $$selectedVal = ${selectedVal};`;
7401 code = `${code} ${genAssignmentCode(value, assignment)}`;
7402 addHandler(el, 'change', code, null, true);
7403}
7404
7405function genDefaultModel (
7406 el,
7407 value,
7408 modifiers
7409) {
7410 const type = el.attrsMap.type;
7411
7412 // warn if v-bind:value conflicts with v-model
7413 // except for inputs with v-bind:type
7414 {
7415 const value = el.attrsMap['v-bind:value'] || el.attrsMap[':value'];
7416 const typeBinding = el.attrsMap['v-bind:type'] || el.attrsMap[':type'];
7417 if (value && !typeBinding) {
7418 const binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value';
7419 warn$1(
7420 `${binding}="${value}" conflicts with v-model on the same element ` +
7421 'because the latter already expands to a value binding internally',
7422 el.rawAttrsMap[binding]
7423 );
7424 }
7425 }
7426
7427 const { lazy, number, trim } = modifiers || {};
7428 const needCompositionGuard = !lazy && type !== 'range';
7429 const event = lazy
7430 ? 'change'
7431 : type === 'range'
7432 ? RANGE_TOKEN
7433 : 'input';
7434
7435 let valueExpression = '$event.target.value';
7436 if (trim) {
7437 valueExpression = `$event.target.value.trim()`;
7438 }
7439 if (number) {
7440 valueExpression = `_n(${valueExpression})`;
7441 }
7442
7443 let code = genAssignmentCode(value, valueExpression);
7444 if (needCompositionGuard) {
7445 code = `if($event.target.composing)return;${code}`;
7446 }
7447
7448 addProp(el, 'value', `(${value})`);
7449 addHandler(el, event, code, null, true);
7450 if (trim || number) {
7451 addHandler(el, 'blur', '$forceUpdate()');
7452 }
7453}
7454
7455/* */
7456
7457// normalize v-model event tokens that can only be determined at runtime.
7458// it's important to place the event as the first in the array because
7459// the whole point is ensuring the v-model callback gets called before
7460// user-attached handlers.
7461function normalizeEvents (on) {
7462 /* istanbul ignore if */
7463 if (isDef(on[RANGE_TOKEN])) {
7464 // IE input[type=range] only supports `change` event
7465 const event = isIE ? 'change' : 'input';
7466 on[event] = [].concat(on[RANGE_TOKEN], on[event] || []);
7467 delete on[RANGE_TOKEN];
7468 }
7469 // This was originally intended to fix #4521 but no longer necessary
7470 // after 2.5. Keeping it for backwards compat with generated code from < 2.4
7471 /* istanbul ignore if */
7472 if (isDef(on[CHECKBOX_RADIO_TOKEN])) {
7473 on.change = [].concat(on[CHECKBOX_RADIO_TOKEN], on.change || []);
7474 delete on[CHECKBOX_RADIO_TOKEN];
7475 }
7476}
7477
7478let target$1;
7479
7480function createOnceHandler$1 (event, handler, capture) {
7481 const _target = target$1; // save current target element in closure
7482 return function onceHandler () {
7483 const res = handler.apply(null, arguments);
7484 if (res !== null) {
7485 remove$2(event, onceHandler, capture, _target);
7486 }
7487 }
7488}
7489
7490// #9446: Firefox <= 53 (in particular, ESR 52) has incorrect Event.timeStamp
7491// implementation and does not fire microtasks in between event propagation, so
7492// safe to exclude.
7493const useMicrotaskFix = isUsingMicroTask && !(isFF && Number(isFF[1]) <= 53);
7494
7495function add$1 (
7496 name,
7497 handler,
7498 capture,
7499 passive
7500) {
7501 // async edge case #6566: inner click event triggers patch, event handler
7502 // attached to outer element during patch, and triggered again. This
7503 // happens because browsers fire microtask ticks between event propagation.
7504 // the solution is simple: we save the timestamp when a handler is attached,
7505 // and the handler would only fire if the event passed to it was fired
7506 // AFTER it was attached.
7507 if (useMicrotaskFix) {
7508 const attachedTimestamp = currentFlushTimestamp;
7509 const original = handler;
7510 handler = original._wrapper = function (e) {
7511 if (
7512 // no bubbling, should always fire.
7513 // this is just a safety net in case event.timeStamp is unreliable in
7514 // certain weird environments...
7515 e.target === e.currentTarget ||
7516 // event is fired after handler attachment
7517 e.timeStamp >= attachedTimestamp ||
7518 // #9462 bail for iOS 9 bug: event.timeStamp is 0 after history.pushState
7519 e.timeStamp === 0 ||
7520 // #9448 bail if event is fired in another document in a multi-page
7521 // electron/nw.js app, since event.timeStamp will be using a different
7522 // starting reference
7523 e.target.ownerDocument !== document
7524 ) {
7525 return original.apply(this, arguments)
7526 }
7527 };
7528 }
7529 target$1.addEventListener(
7530 name,
7531 handler,
7532 supportsPassive
7533 ? { capture, passive }
7534 : capture
7535 );
7536}
7537
7538function remove$2 (
7539 name,
7540 handler,
7541 capture,
7542 _target
7543) {
7544 (_target || target$1).removeEventListener(
7545 name,
7546 handler._wrapper || handler,
7547 capture
7548 );
7549}
7550
7551function updateDOMListeners (oldVnode, vnode) {
7552 if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {
7553 return
7554 }
7555 const on = vnode.data.on || {};
7556 const oldOn = oldVnode.data.on || {};
7557 target$1 = vnode.elm;
7558 normalizeEvents(on);
7559 updateListeners(on, oldOn, add$1, remove$2, createOnceHandler$1, vnode.context);
7560 target$1 = undefined;
7561}
7562
7563var events = {
7564 create: updateDOMListeners,
7565 update: updateDOMListeners
7566};
7567
7568/* */
7569
7570let svgContainer;
7571
7572function updateDOMProps (oldVnode, vnode) {
7573 if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) {
7574 return
7575 }
7576 let key, cur;
7577 const elm = vnode.elm;
7578 const oldProps = oldVnode.data.domProps || {};
7579 let props = vnode.data.domProps || {};
7580 // clone observed objects, as the user probably wants to mutate it
7581 if (isDef(props.__ob__)) {
7582 props = vnode.data.domProps = extend({}, props);
7583 }
7584
7585 for (key in oldProps) {
7586 if (isUndef(props[key])) {
7587 elm[key] = '';
7588 }
7589 }
7590 for (key in props) {
7591 cur = props[key];
7592 // ignore children if the node has textContent or innerHTML,
7593 // as these will throw away existing DOM nodes and cause removal errors
7594 // on subsequent patches (#3360)
7595 if (key === 'textContent' || key === 'innerHTML') {
7596 if (vnode.children) vnode.children.length = 0;
7597 if (cur === oldProps[key]) continue
7598 // #6601 work around Chrome version <= 55 bug where single textNode
7599 // replaced by innerHTML/textContent retains its parentNode property
7600 if (elm.childNodes.length === 1) {
7601 elm.removeChild(elm.childNodes[0]);
7602 }
7603 }
7604
7605 if (key === 'value' && elm.tagName !== 'PROGRESS') {
7606 // store value as _value as well since
7607 // non-string values will be stringified
7608 elm._value = cur;
7609 // avoid resetting cursor position when value is the same
7610 const strCur = isUndef(cur) ? '' : String(cur);
7611 if (shouldUpdateValue(elm, strCur)) {
7612 elm.value = strCur;
7613 }
7614 } else if (key === 'innerHTML' && isSVG(elm.tagName) && isUndef(elm.innerHTML)) {
7615 // IE doesn't support innerHTML for SVG elements
7616 svgContainer = svgContainer || document.createElement('div');
7617 svgContainer.innerHTML = `<svg>${cur}</svg>`;
7618 const svg = svgContainer.firstChild;
7619 while (elm.firstChild) {
7620 elm.removeChild(elm.firstChild);
7621 }
7622 while (svg.firstChild) {
7623 elm.appendChild(svg.firstChild);
7624 }
7625 } else if (
7626 // skip the update if old and new VDOM state is the same.
7627 // `value` is handled separately because the DOM value may be temporarily
7628 // out of sync with VDOM state due to focus, composition and modifiers.
7629 // This #4521 by skipping the unnecesarry `checked` update.
7630 cur !== oldProps[key]
7631 ) {
7632 // some property updates can throw
7633 // e.g. `value` on <progress> w/ non-finite value
7634 try {
7635 elm[key] = cur;
7636 } catch (e) {}
7637 }
7638 }
7639}
7640
7641// check platforms/web/util/attrs.js acceptValue
7642
7643
7644function shouldUpdateValue (elm, checkVal) {
7645 return (!elm.composing && (
7646 elm.tagName === 'OPTION' ||
7647 isNotInFocusAndDirty(elm, checkVal) ||
7648 isDirtyWithModifiers(elm, checkVal)
7649 ))
7650}
7651
7652function isNotInFocusAndDirty (elm, checkVal) {
7653 // return true when textbox (.number and .trim) loses focus and its value is
7654 // not equal to the updated value
7655 let notInFocus = true;
7656 // #6157
7657 // work around IE bug when accessing document.activeElement in an iframe
7658 try { notInFocus = document.activeElement !== elm; } catch (e) {}
7659 return notInFocus && elm.value !== checkVal
7660}
7661
7662function isDirtyWithModifiers (elm, newVal) {
7663 const value = elm.value;
7664 const modifiers = elm._vModifiers; // injected by v-model runtime
7665 if (isDef(modifiers)) {
7666 if (modifiers.number) {
7667 return toNumber(value) !== toNumber(newVal)
7668 }
7669 if (modifiers.trim) {
7670 return value.trim() !== newVal.trim()
7671 }
7672 }
7673 return value !== newVal
7674}
7675
7676var domProps = {
7677 create: updateDOMProps,
7678 update: updateDOMProps
7679};
7680
7681/* */
7682
7683const parseStyleText = cached(function (cssText) {
7684 const res = {};
7685 const listDelimiter = /;(?![^(]*\))/g;
7686 const propertyDelimiter = /:(.+)/;
7687 cssText.split(listDelimiter).forEach(function (item) {
7688 if (item) {
7689 const tmp = item.split(propertyDelimiter);
7690 tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim());
7691 }
7692 });
7693 return res
7694});
7695
7696// merge static and dynamic style data on the same vnode
7697function normalizeStyleData (data) {
7698 const style = normalizeStyleBinding(data.style);
7699 // static style is pre-processed into an object during compilation
7700 // and is always a fresh object, so it's safe to merge into it
7701 return data.staticStyle
7702 ? extend(data.staticStyle, style)
7703 : style
7704}
7705
7706// normalize possible array / string values into Object
7707function normalizeStyleBinding (bindingStyle) {
7708 if (Array.isArray(bindingStyle)) {
7709 return toObject(bindingStyle)
7710 }
7711 if (typeof bindingStyle === 'string') {
7712 return parseStyleText(bindingStyle)
7713 }
7714 return bindingStyle
7715}
7716
7717/**
7718 * parent component style should be after child's
7719 * so that parent component's style could override it
7720 */
7721function getStyle (vnode, checkChild) {
7722 const res = {};
7723 let styleData;
7724
7725 if (checkChild) {
7726 let childNode = vnode;
7727 while (childNode.componentInstance) {
7728 childNode = childNode.componentInstance._vnode;
7729 if (
7730 childNode && childNode.data &&
7731 (styleData = normalizeStyleData(childNode.data))
7732 ) {
7733 extend(res, styleData);
7734 }
7735 }
7736 }
7737
7738 if ((styleData = normalizeStyleData(vnode.data))) {
7739 extend(res, styleData);
7740 }
7741
7742 let parentNode = vnode;
7743 while ((parentNode = parentNode.parent)) {
7744 if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {
7745 extend(res, styleData);
7746 }
7747 }
7748 return res
7749}
7750
7751/* */
7752
7753const cssVarRE = /^--/;
7754const importantRE = /\s*!important$/;
7755const setProp = (el, name, val) => {
7756 /* istanbul ignore if */
7757 if (cssVarRE.test(name)) {
7758 el.style.setProperty(name, val);
7759 } else if (importantRE.test(val)) {
7760 el.style.setProperty(hyphenate(name), val.replace(importantRE, ''), 'important');
7761 } else {
7762 const normalizedName = normalize(name);
7763 if (Array.isArray(val)) {
7764 // Support values array created by autoprefixer, e.g.
7765 // {display: ["-webkit-box", "-ms-flexbox", "flex"]}
7766 // Set them one by one, and the browser will only set those it can recognize
7767 for (let i = 0, len = val.length; i < len; i++) {
7768 el.style[normalizedName] = val[i];
7769 }
7770 } else {
7771 el.style[normalizedName] = val;
7772 }
7773 }
7774};
7775
7776const vendorNames = ['Webkit', 'Moz', 'ms'];
7777
7778let emptyStyle;
7779const normalize = cached(function (prop) {
7780 emptyStyle = emptyStyle || document.createElement('div').style;
7781 prop = camelize(prop);
7782 if (prop !== 'filter' && (prop in emptyStyle)) {
7783 return prop
7784 }
7785 const capName = prop.charAt(0).toUpperCase() + prop.slice(1);
7786 for (let i = 0; i < vendorNames.length; i++) {
7787 const name = vendorNames[i] + capName;
7788 if (name in emptyStyle) {
7789 return name
7790 }
7791 }
7792});
7793
7794function updateStyle (oldVnode, vnode) {
7795 const data = vnode.data;
7796 const oldData = oldVnode.data;
7797
7798 if (isUndef(data.staticStyle) && isUndef(data.style) &&
7799 isUndef(oldData.staticStyle) && isUndef(oldData.style)
7800 ) {
7801 return
7802 }
7803
7804 let cur, name;
7805 const el = vnode.elm;
7806 const oldStaticStyle = oldData.staticStyle;
7807 const oldStyleBinding = oldData.normalizedStyle || oldData.style || {};
7808
7809 // if static style exists, stylebinding already merged into it when doing normalizeStyleData
7810 const oldStyle = oldStaticStyle || oldStyleBinding;
7811
7812 const style = normalizeStyleBinding(vnode.data.style) || {};
7813
7814 // store normalized style under a different key for next diff
7815 // make sure to clone it if it's reactive, since the user likely wants
7816 // to mutate it.
7817 vnode.data.normalizedStyle = isDef(style.__ob__)
7818 ? extend({}, style)
7819 : style;
7820
7821 const newStyle = getStyle(vnode, true);
7822
7823 for (name in oldStyle) {
7824 if (isUndef(newStyle[name])) {
7825 setProp(el, name, '');
7826 }
7827 }
7828 for (name in newStyle) {
7829 cur = newStyle[name];
7830 if (cur !== oldStyle[name]) {
7831 // ie9 setting to null has no effect, must use empty string
7832 setProp(el, name, cur == null ? '' : cur);
7833 }
7834 }
7835}
7836
7837var style = {
7838 create: updateStyle,
7839 update: updateStyle
7840};
7841
7842/* */
7843
7844const whitespaceRE = /\s+/;
7845
7846/**
7847 * Add class with compatibility for SVG since classList is not supported on
7848 * SVG elements in IE
7849 */
7850function addClass (el, cls) {
7851 /* istanbul ignore if */
7852 if (!cls || !(cls = cls.trim())) {
7853 return
7854 }
7855
7856 /* istanbul ignore else */
7857 if (el.classList) {
7858 if (cls.indexOf(' ') > -1) {
7859 cls.split(whitespaceRE).forEach(c => el.classList.add(c));
7860 } else {
7861 el.classList.add(cls);
7862 }
7863 } else {
7864 const cur = ` ${el.getAttribute('class') || ''} `;
7865 if (cur.indexOf(' ' + cls + ' ') < 0) {
7866 el.setAttribute('class', (cur + cls).trim());
7867 }
7868 }
7869}
7870
7871/**
7872 * Remove class with compatibility for SVG since classList is not supported on
7873 * SVG elements in IE
7874 */
7875function removeClass (el, cls) {
7876 /* istanbul ignore if */
7877 if (!cls || !(cls = cls.trim())) {
7878 return
7879 }
7880
7881 /* istanbul ignore else */
7882 if (el.classList) {
7883 if (cls.indexOf(' ') > -1) {
7884 cls.split(whitespaceRE).forEach(c => el.classList.remove(c));
7885 } else {
7886 el.classList.remove(cls);
7887 }
7888 if (!el.classList.length) {
7889 el.removeAttribute('class');
7890 }
7891 } else {
7892 let cur = ` ${el.getAttribute('class') || ''} `;
7893 const tar = ' ' + cls + ' ';
7894 while (cur.indexOf(tar) >= 0) {
7895 cur = cur.replace(tar, ' ');
7896 }
7897 cur = cur.trim();
7898 if (cur) {
7899 el.setAttribute('class', cur);
7900 } else {
7901 el.removeAttribute('class');
7902 }
7903 }
7904}
7905
7906/* */
7907
7908function resolveTransition (def$$1) {
7909 if (!def$$1) {
7910 return
7911 }
7912 /* istanbul ignore else */
7913 if (typeof def$$1 === 'object') {
7914 const res = {};
7915 if (def$$1.css !== false) {
7916 extend(res, autoCssTransition(def$$1.name || 'v'));
7917 }
7918 extend(res, def$$1);
7919 return res
7920 } else if (typeof def$$1 === 'string') {
7921 return autoCssTransition(def$$1)
7922 }
7923}
7924
7925const autoCssTransition = cached(name => {
7926 return {
7927 enterClass: `${name}-enter`,
7928 enterToClass: `${name}-enter-to`,
7929 enterActiveClass: `${name}-enter-active`,
7930 leaveClass: `${name}-leave`,
7931 leaveToClass: `${name}-leave-to`,
7932 leaveActiveClass: `${name}-leave-active`
7933 }
7934});
7935
7936const hasTransition = inBrowser && !isIE9;
7937const TRANSITION = 'transition';
7938const ANIMATION = 'animation';
7939
7940// Transition property/event sniffing
7941let transitionProp = 'transition';
7942let transitionEndEvent = 'transitionend';
7943let animationProp = 'animation';
7944let animationEndEvent = 'animationend';
7945if (hasTransition) {
7946 /* istanbul ignore if */
7947 if (window.ontransitionend === undefined &&
7948 window.onwebkittransitionend !== undefined
7949 ) {
7950 transitionProp = 'WebkitTransition';
7951 transitionEndEvent = 'webkitTransitionEnd';
7952 }
7953 if (window.onanimationend === undefined &&
7954 window.onwebkitanimationend !== undefined
7955 ) {
7956 animationProp = 'WebkitAnimation';
7957 animationEndEvent = 'webkitAnimationEnd';
7958 }
7959}
7960
7961// binding to window is necessary to make hot reload work in IE in strict mode
7962const raf = inBrowser
7963 ? window.requestAnimationFrame
7964 ? window.requestAnimationFrame.bind(window)
7965 : setTimeout
7966 : /* istanbul ignore next */ fn => fn();
7967
7968function nextFrame (fn) {
7969 raf(() => {
7970 raf(fn);
7971 });
7972}
7973
7974function addTransitionClass (el, cls) {
7975 const transitionClasses = el._transitionClasses || (el._transitionClasses = []);
7976 if (transitionClasses.indexOf(cls) < 0) {
7977 transitionClasses.push(cls);
7978 addClass(el, cls);
7979 }
7980}
7981
7982function removeTransitionClass (el, cls) {
7983 if (el._transitionClasses) {
7984 remove(el._transitionClasses, cls);
7985 }
7986 removeClass(el, cls);
7987}
7988
7989function whenTransitionEnds (
7990 el,
7991 expectedType,
7992 cb
7993) {
7994 const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
7995 if (!type) return cb()
7996 const event = type === TRANSITION ? transitionEndEvent : animationEndEvent;
7997 let ended = 0;
7998 const end = () => {
7999 el.removeEventListener(event, onEnd);
8000 cb();
8001 };
8002 const onEnd = e => {
8003 if (e.target === el) {
8004 if (++ended >= propCount) {
8005 end();
8006 }
8007 }
8008 };
8009 setTimeout(() => {
8010 if (ended < propCount) {
8011 end();
8012 }
8013 }, timeout + 1);
8014 el.addEventListener(event, onEnd);
8015}
8016
8017const transformRE = /\b(transform|all)(,|$)/;
8018
8019function getTransitionInfo (el, expectedType) {
8020 const styles = window.getComputedStyle(el);
8021 // JSDOM may return undefined for transition properties
8022 const transitionDelays = (styles[transitionProp + 'Delay'] || '').split(', ');
8023 const transitionDurations = (styles[transitionProp + 'Duration'] || '').split(', ');
8024 const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
8025 const animationDelays = (styles[animationProp + 'Delay'] || '').split(', ');
8026 const animationDurations = (styles[animationProp + 'Duration'] || '').split(', ');
8027 const animationTimeout = getTimeout(animationDelays, animationDurations);
8028
8029 let type;
8030 let timeout = 0;
8031 let propCount = 0;
8032 /* istanbul ignore if */
8033 if (expectedType === TRANSITION) {
8034 if (transitionTimeout > 0) {
8035 type = TRANSITION;
8036 timeout = transitionTimeout;
8037 propCount = transitionDurations.length;
8038 }
8039 } else if (expectedType === ANIMATION) {
8040 if (animationTimeout > 0) {
8041 type = ANIMATION;
8042 timeout = animationTimeout;
8043 propCount = animationDurations.length;
8044 }
8045 } else {
8046 timeout = Math.max(transitionTimeout, animationTimeout);
8047 type = timeout > 0
8048 ? transitionTimeout > animationTimeout
8049 ? TRANSITION
8050 : ANIMATION
8051 : null;
8052 propCount = type
8053 ? type === TRANSITION
8054 ? transitionDurations.length
8055 : animationDurations.length
8056 : 0;
8057 }
8058 const hasTransform =
8059 type === TRANSITION &&
8060 transformRE.test(styles[transitionProp + 'Property']);
8061 return {
8062 type,
8063 timeout,
8064 propCount,
8065 hasTransform
8066 }
8067}
8068
8069function getTimeout (delays, durations) {
8070 /* istanbul ignore next */
8071 while (delays.length < durations.length) {
8072 delays = delays.concat(delays);
8073 }
8074
8075 return Math.max.apply(null, durations.map((d, i) => {
8076 return toMs(d) + toMs(delays[i])
8077 }))
8078}
8079
8080// Old versions of Chromium (below 61.0.3163.100) formats floating pointer numbers
8081// in a locale-dependent way, using a comma instead of a dot.
8082// If comma is not replaced with a dot, the input will be rounded down (i.e. acting
8083// as a floor function) causing unexpected behaviors
8084function toMs (s) {
8085 return Number(s.slice(0, -1).replace(',', '.')) * 1000
8086}
8087
8088/* */
8089
8090function enter (vnode, toggleDisplay) {
8091 const el = vnode.elm;
8092
8093 // call leave callback now
8094 if (isDef(el._leaveCb)) {
8095 el._leaveCb.cancelled = true;
8096 el._leaveCb();
8097 }
8098
8099 const data = resolveTransition(vnode.data.transition);
8100 if (isUndef(data)) {
8101 return
8102 }
8103
8104 /* istanbul ignore if */
8105 if (isDef(el._enterCb) || el.nodeType !== 1) {
8106 return
8107 }
8108
8109 const {
8110 css,
8111 type,
8112 enterClass,
8113 enterToClass,
8114 enterActiveClass,
8115 appearClass,
8116 appearToClass,
8117 appearActiveClass,
8118 beforeEnter,
8119 enter,
8120 afterEnter,
8121 enterCancelled,
8122 beforeAppear,
8123 appear,
8124 afterAppear,
8125 appearCancelled,
8126 duration
8127 } = data;
8128
8129 // activeInstance will always be the <transition> component managing this
8130 // transition. One edge case to check is when the <transition> is placed
8131 // as the root node of a child component. In that case we need to check
8132 // <transition>'s parent for appear check.
8133 let context = activeInstance;
8134 let transitionNode = activeInstance.$vnode;
8135 while (transitionNode && transitionNode.parent) {
8136 transitionNode = transitionNode.parent;
8137 context = transitionNode.context;
8138 }
8139
8140 const isAppear = !context._isMounted || !vnode.isRootInsert;
8141
8142 if (isAppear && !appear && appear !== '') {
8143 return
8144 }
8145
8146 const startClass = isAppear && appearClass
8147 ? appearClass
8148 : enterClass;
8149 const activeClass = isAppear && appearActiveClass
8150 ? appearActiveClass
8151 : enterActiveClass;
8152 const toClass = isAppear && appearToClass
8153 ? appearToClass
8154 : enterToClass;
8155
8156 const beforeEnterHook = isAppear
8157 ? (beforeAppear || beforeEnter)
8158 : beforeEnter;
8159 const enterHook = isAppear
8160 ? (typeof appear === 'function' ? appear : enter)
8161 : enter;
8162 const afterEnterHook = isAppear
8163 ? (afterAppear || afterEnter)
8164 : afterEnter;
8165 const enterCancelledHook = isAppear
8166 ? (appearCancelled || enterCancelled)
8167 : enterCancelled;
8168
8169 const explicitEnterDuration = toNumber(
8170 isObject(duration)
8171 ? duration.enter
8172 : duration
8173 );
8174
8175 if (explicitEnterDuration != null) {
8176 checkDuration(explicitEnterDuration, 'enter', vnode);
8177 }
8178
8179 const expectsCSS = css !== false && !isIE9;
8180 const userWantsControl = getHookArgumentsLength(enterHook);
8181
8182 const cb = el._enterCb = once(() => {
8183 if (expectsCSS) {
8184 removeTransitionClass(el, toClass);
8185 removeTransitionClass(el, activeClass);
8186 }
8187 if (cb.cancelled) {
8188 if (expectsCSS) {
8189 removeTransitionClass(el, startClass);
8190 }
8191 enterCancelledHook && enterCancelledHook(el);
8192 } else {
8193 afterEnterHook && afterEnterHook(el);
8194 }
8195 el._enterCb = null;
8196 });
8197
8198 if (!vnode.data.show) {
8199 // remove pending leave element on enter by injecting an insert hook
8200 mergeVNodeHook(vnode, 'insert', () => {
8201 const parent = el.parentNode;
8202 const pendingNode = parent && parent._pending && parent._pending[vnode.key];
8203 if (pendingNode &&
8204 pendingNode.tag === vnode.tag &&
8205 pendingNode.elm._leaveCb
8206 ) {
8207 pendingNode.elm._leaveCb();
8208 }
8209 enterHook && enterHook(el, cb);
8210 });
8211 }
8212
8213 // start enter transition
8214 beforeEnterHook && beforeEnterHook(el);
8215 if (expectsCSS) {
8216 addTransitionClass(el, startClass);
8217 addTransitionClass(el, activeClass);
8218 nextFrame(() => {
8219 removeTransitionClass(el, startClass);
8220 if (!cb.cancelled) {
8221 addTransitionClass(el, toClass);
8222 if (!userWantsControl) {
8223 if (isValidDuration(explicitEnterDuration)) {
8224 setTimeout(cb, explicitEnterDuration);
8225 } else {
8226 whenTransitionEnds(el, type, cb);
8227 }
8228 }
8229 }
8230 });
8231 }
8232
8233 if (vnode.data.show) {
8234 toggleDisplay && toggleDisplay();
8235 enterHook && enterHook(el, cb);
8236 }
8237
8238 if (!expectsCSS && !userWantsControl) {
8239 cb();
8240 }
8241}
8242
8243function leave (vnode, rm) {
8244 const el = vnode.elm;
8245
8246 // call enter callback now
8247 if (isDef(el._enterCb)) {
8248 el._enterCb.cancelled = true;
8249 el._enterCb();
8250 }
8251
8252 const data = resolveTransition(vnode.data.transition);
8253 if (isUndef(data) || el.nodeType !== 1) {
8254 return rm()
8255 }
8256
8257 /* istanbul ignore if */
8258 if (isDef(el._leaveCb)) {
8259 return
8260 }
8261
8262 const {
8263 css,
8264 type,
8265 leaveClass,
8266 leaveToClass,
8267 leaveActiveClass,
8268 beforeLeave,
8269 leave,
8270 afterLeave,
8271 leaveCancelled,
8272 delayLeave,
8273 duration
8274 } = data;
8275
8276 const expectsCSS = css !== false && !isIE9;
8277 const userWantsControl = getHookArgumentsLength(leave);
8278
8279 const explicitLeaveDuration = toNumber(
8280 isObject(duration)
8281 ? duration.leave
8282 : duration
8283 );
8284
8285 if (isDef(explicitLeaveDuration)) {
8286 checkDuration(explicitLeaveDuration, 'leave', vnode);
8287 }
8288
8289 const cb = el._leaveCb = once(() => {
8290 if (el.parentNode && el.parentNode._pending) {
8291 el.parentNode._pending[vnode.key] = null;
8292 }
8293 if (expectsCSS) {
8294 removeTransitionClass(el, leaveToClass);
8295 removeTransitionClass(el, leaveActiveClass);
8296 }
8297 if (cb.cancelled) {
8298 if (expectsCSS) {
8299 removeTransitionClass(el, leaveClass);
8300 }
8301 leaveCancelled && leaveCancelled(el);
8302 } else {
8303 rm();
8304 afterLeave && afterLeave(el);
8305 }
8306 el._leaveCb = null;
8307 });
8308
8309 if (delayLeave) {
8310 delayLeave(performLeave);
8311 } else {
8312 performLeave();
8313 }
8314
8315 function performLeave () {
8316 // the delayed leave may have already been cancelled
8317 if (cb.cancelled) {
8318 return
8319 }
8320 // record leaving element
8321 if (!vnode.data.show && el.parentNode) {
8322 (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode;
8323 }
8324 beforeLeave && beforeLeave(el);
8325 if (expectsCSS) {
8326 addTransitionClass(el, leaveClass);
8327 addTransitionClass(el, leaveActiveClass);
8328 nextFrame(() => {
8329 removeTransitionClass(el, leaveClass);
8330 if (!cb.cancelled) {
8331 addTransitionClass(el, leaveToClass);
8332 if (!userWantsControl) {
8333 if (isValidDuration(explicitLeaveDuration)) {
8334 setTimeout(cb, explicitLeaveDuration);
8335 } else {
8336 whenTransitionEnds(el, type, cb);
8337 }
8338 }
8339 }
8340 });
8341 }
8342 leave && leave(el, cb);
8343 if (!expectsCSS && !userWantsControl) {
8344 cb();
8345 }
8346 }
8347}
8348
8349// only used in dev mode
8350function checkDuration (val, name, vnode) {
8351 if (typeof val !== 'number') {
8352 warn(
8353 `<transition> explicit ${name} duration is not a valid number - ` +
8354 `got ${JSON.stringify(val)}.`,
8355 vnode.context
8356 );
8357 } else if (isNaN(val)) {
8358 warn(
8359 `<transition> explicit ${name} duration is NaN - ` +
8360 'the duration expression might be incorrect.',
8361 vnode.context
8362 );
8363 }
8364}
8365
8366function isValidDuration (val) {
8367 return typeof val === 'number' && !isNaN(val)
8368}
8369
8370/**
8371 * Normalize a transition hook's argument length. The hook may be:
8372 * - a merged hook (invoker) with the original in .fns
8373 * - a wrapped component method (check ._length)
8374 * - a plain function (.length)
8375 */
8376function getHookArgumentsLength (fn) {
8377 if (isUndef(fn)) {
8378 return false
8379 }
8380 const invokerFns = fn.fns;
8381 if (isDef(invokerFns)) {
8382 // invoker
8383 return getHookArgumentsLength(
8384 Array.isArray(invokerFns)
8385 ? invokerFns[0]
8386 : invokerFns
8387 )
8388 } else {
8389 return (fn._length || fn.length) > 1
8390 }
8391}
8392
8393function _enter (_, vnode) {
8394 if (vnode.data.show !== true) {
8395 enter(vnode);
8396 }
8397}
8398
8399var transition = inBrowser ? {
8400 create: _enter,
8401 activate: _enter,
8402 remove (vnode, rm) {
8403 /* istanbul ignore else */
8404 if (vnode.data.show !== true) {
8405 leave(vnode, rm);
8406 } else {
8407 rm();
8408 }
8409 }
8410} : {};
8411
8412var platformModules = [
8413 attrs,
8414 klass,
8415 events,
8416 domProps,
8417 style,
8418 transition
8419];
8420
8421/* */
8422
8423// the directive module should be applied last, after all
8424// built-in modules have been applied.
8425const modules = platformModules.concat(baseModules);
8426
8427const patch = createPatchFunction({ nodeOps, modules });
8428
8429/**
8430 * Not type checking this file because flow doesn't like attaching
8431 * properties to Elements.
8432 */
8433
8434/* istanbul ignore if */
8435if (isIE9) {
8436 // http://www.matts411.com/post/internet-explorer-9-oninput/
8437 document.addEventListener('selectionchange', () => {
8438 const el = document.activeElement;
8439 if (el && el.vmodel) {
8440 trigger(el, 'input');
8441 }
8442 });
8443}
8444
8445const directive = {
8446 inserted (el, binding, vnode, oldVnode) {
8447 if (vnode.tag === 'select') {
8448 // #6903
8449 if (oldVnode.elm && !oldVnode.elm._vOptions) {
8450 mergeVNodeHook(vnode, 'postpatch', () => {
8451 directive.componentUpdated(el, binding, vnode);
8452 });
8453 } else {
8454 setSelected(el, binding, vnode.context);
8455 }
8456 el._vOptions = [].map.call(el.options, getValue);
8457 } else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
8458 el._vModifiers = binding.modifiers;
8459 if (!binding.modifiers.lazy) {
8460 el.addEventListener('compositionstart', onCompositionStart);
8461 el.addEventListener('compositionend', onCompositionEnd);
8462 // Safari < 10.2 & UIWebView doesn't fire compositionend when
8463 // switching focus before confirming composition choice
8464 // this also fixes the issue where some browsers e.g. iOS Chrome
8465 // fires "change" instead of "input" on autocomplete.
8466 el.addEventListener('change', onCompositionEnd);
8467 /* istanbul ignore if */
8468 if (isIE9) {
8469 el.vmodel = true;
8470 }
8471 }
8472 }
8473 },
8474
8475 componentUpdated (el, binding, vnode) {
8476 if (vnode.tag === 'select') {
8477 setSelected(el, binding, vnode.context);
8478 // in case the options rendered by v-for have changed,
8479 // it's possible that the value is out-of-sync with the rendered options.
8480 // detect such cases and filter out values that no longer has a matching
8481 // option in the DOM.
8482 const prevOptions = el._vOptions;
8483 const curOptions = el._vOptions = [].map.call(el.options, getValue);
8484 if (curOptions.some((o, i) => !looseEqual(o, prevOptions[i]))) {
8485 // trigger change event if
8486 // no matching option found for at least one value
8487 const needReset = el.multiple
8488 ? binding.value.some(v => hasNoMatchingOption(v, curOptions))
8489 : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions);
8490 if (needReset) {
8491 trigger(el, 'change');
8492 }
8493 }
8494 }
8495 }
8496};
8497
8498function setSelected (el, binding, vm) {
8499 actuallySetSelected(el, binding, vm);
8500 /* istanbul ignore if */
8501 if (isIE || isEdge) {
8502 setTimeout(() => {
8503 actuallySetSelected(el, binding, vm);
8504 }, 0);
8505 }
8506}
8507
8508function actuallySetSelected (el, binding, vm) {
8509 const value = binding.value;
8510 const isMultiple = el.multiple;
8511 if (isMultiple && !Array.isArray(value)) {
8512 warn(
8513 `<select multiple v-model="${binding.expression}"> ` +
8514 `expects an Array value for its binding, but got ${
8515 Object.prototype.toString.call(value).slice(8, -1)
8516 }`,
8517 vm
8518 );
8519 return
8520 }
8521 let selected, option;
8522 for (let i = 0, l = el.options.length; i < l; i++) {
8523 option = el.options[i];
8524 if (isMultiple) {
8525 selected = looseIndexOf(value, getValue(option)) > -1;
8526 if (option.selected !== selected) {
8527 option.selected = selected;
8528 }
8529 } else {
8530 if (looseEqual(getValue(option), value)) {
8531 if (el.selectedIndex !== i) {
8532 el.selectedIndex = i;
8533 }
8534 return
8535 }
8536 }
8537 }
8538 if (!isMultiple) {
8539 el.selectedIndex = -1;
8540 }
8541}
8542
8543function hasNoMatchingOption (value, options) {
8544 return options.every(o => !looseEqual(o, value))
8545}
8546
8547function getValue (option) {
8548 return '_value' in option
8549 ? option._value
8550 : option.value
8551}
8552
8553function onCompositionStart (e) {
8554 e.target.composing = true;
8555}
8556
8557function onCompositionEnd (e) {
8558 // prevent triggering an input event for no reason
8559 if (!e.target.composing) return
8560 e.target.composing = false;
8561 trigger(e.target, 'input');
8562}
8563
8564function trigger (el, type) {
8565 const e = document.createEvent('HTMLEvents');
8566 e.initEvent(type, true, true);
8567 el.dispatchEvent(e);
8568}
8569
8570/* */
8571
8572// recursively search for possible transition defined inside the component root
8573function locateNode (vnode) {
8574 return vnode.componentInstance && (!vnode.data || !vnode.data.transition)
8575 ? locateNode(vnode.componentInstance._vnode)
8576 : vnode
8577}
8578
8579var show = {
8580 bind (el, { value }, vnode) {
8581 vnode = locateNode(vnode);
8582 const transition$$1 = vnode.data && vnode.data.transition;
8583 const originalDisplay = el.__vOriginalDisplay =
8584 el.style.display === 'none' ? '' : el.style.display;
8585 if (value && transition$$1) {
8586 vnode.data.show = true;
8587 enter(vnode, () => {
8588 el.style.display = originalDisplay;
8589 });
8590 } else {
8591 el.style.display = value ? originalDisplay : 'none';
8592 }
8593 },
8594
8595 update (el, { value, oldValue }, vnode) {
8596 /* istanbul ignore if */
8597 if (!value === !oldValue) return
8598 vnode = locateNode(vnode);
8599 const transition$$1 = vnode.data && vnode.data.transition;
8600 if (transition$$1) {
8601 vnode.data.show = true;
8602 if (value) {
8603 enter(vnode, () => {
8604 el.style.display = el.__vOriginalDisplay;
8605 });
8606 } else {
8607 leave(vnode, () => {
8608 el.style.display = 'none';
8609 });
8610 }
8611 } else {
8612 el.style.display = value ? el.__vOriginalDisplay : 'none';
8613 }
8614 },
8615
8616 unbind (
8617 el,
8618 binding,
8619 vnode,
8620 oldVnode,
8621 isDestroy
8622 ) {
8623 if (!isDestroy) {
8624 el.style.display = el.__vOriginalDisplay;
8625 }
8626 }
8627};
8628
8629var platformDirectives = {
8630 model: directive,
8631 show
8632};
8633
8634/* */
8635
8636const transitionProps = {
8637 name: String,
8638 appear: Boolean,
8639 css: Boolean,
8640 mode: String,
8641 type: String,
8642 enterClass: String,
8643 leaveClass: String,
8644 enterToClass: String,
8645 leaveToClass: String,
8646 enterActiveClass: String,
8647 leaveActiveClass: String,
8648 appearClass: String,
8649 appearActiveClass: String,
8650 appearToClass: String,
8651 duration: [Number, String, Object]
8652};
8653
8654// in case the child is also an abstract component, e.g. <keep-alive>
8655// we want to recursively retrieve the real component to be rendered
8656function getRealChild (vnode) {
8657 const compOptions = vnode && vnode.componentOptions;
8658 if (compOptions && compOptions.Ctor.options.abstract) {
8659 return getRealChild(getFirstComponentChild(compOptions.children))
8660 } else {
8661 return vnode
8662 }
8663}
8664
8665function extractTransitionData (comp) {
8666 const data = {};
8667 const options = comp.$options;
8668 // props
8669 for (const key in options.propsData) {
8670 data[key] = comp[key];
8671 }
8672 // events.
8673 // extract listeners and pass them directly to the transition methods
8674 const listeners = options._parentListeners;
8675 for (const key in listeners) {
8676 data[camelize(key)] = listeners[key];
8677 }
8678 return data
8679}
8680
8681function placeholder (h, rawChild) {
8682 if (/\d-keep-alive$/.test(rawChild.tag)) {
8683 return h('keep-alive', {
8684 props: rawChild.componentOptions.propsData
8685 })
8686 }
8687}
8688
8689function hasParentTransition (vnode) {
8690 while ((vnode = vnode.parent)) {
8691 if (vnode.data.transition) {
8692 return true
8693 }
8694 }
8695}
8696
8697function isSameChild (child, oldChild) {
8698 return oldChild.key === child.key && oldChild.tag === child.tag
8699}
8700
8701const isNotTextNode = (c) => c.tag || isAsyncPlaceholder(c);
8702
8703const isVShowDirective = d => d.name === 'show';
8704
8705var Transition = {
8706 name: 'transition',
8707 props: transitionProps,
8708 abstract: true,
8709
8710 render (h) {
8711 let children = this.$slots.default;
8712 if (!children) {
8713 return
8714 }
8715
8716 // filter out text nodes (possible whitespaces)
8717 children = children.filter(isNotTextNode);
8718 /* istanbul ignore if */
8719 if (!children.length) {
8720 return
8721 }
8722
8723 // warn multiple elements
8724 if (children.length > 1) {
8725 warn(
8726 '<transition> can only be used on a single element. Use ' +
8727 '<transition-group> for lists.',
8728 this.$parent
8729 );
8730 }
8731
8732 const mode = this.mode;
8733
8734 // warn invalid mode
8735 if (mode && mode !== 'in-out' && mode !== 'out-in'
8736 ) {
8737 warn(
8738 'invalid <transition> mode: ' + mode,
8739 this.$parent
8740 );
8741 }
8742
8743 const rawChild = children[0];
8744
8745 // if this is a component root node and the component's
8746 // parent container node also has transition, skip.
8747 if (hasParentTransition(this.$vnode)) {
8748 return rawChild
8749 }
8750
8751 // apply transition data to child
8752 // use getRealChild() to ignore abstract components e.g. keep-alive
8753 const child = getRealChild(rawChild);
8754 /* istanbul ignore if */
8755 if (!child) {
8756 return rawChild
8757 }
8758
8759 if (this._leaving) {
8760 return placeholder(h, rawChild)
8761 }
8762
8763 // ensure a key that is unique to the vnode type and to this transition
8764 // component instance. This key will be used to remove pending leaving nodes
8765 // during entering.
8766 const id = `__transition-${this._uid}-`;
8767 child.key = child.key == null
8768 ? child.isComment
8769 ? id + 'comment'
8770 : id + child.tag
8771 : isPrimitive(child.key)
8772 ? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
8773 : child.key;
8774
8775 const data = (child.data || (child.data = {})).transition = extractTransitionData(this);
8776 const oldRawChild = this._vnode;
8777 const oldChild = getRealChild(oldRawChild);
8778
8779 // mark v-show
8780 // so that the transition module can hand over the control to the directive
8781 if (child.data.directives && child.data.directives.some(isVShowDirective)) {
8782 child.data.show = true;
8783 }
8784
8785 if (
8786 oldChild &&
8787 oldChild.data &&
8788 !isSameChild(child, oldChild) &&
8789 !isAsyncPlaceholder(oldChild) &&
8790 // #6687 component root is a comment node
8791 !(oldChild.componentInstance && oldChild.componentInstance._vnode.isComment)
8792 ) {
8793 // replace old child transition data with fresh one
8794 // important for dynamic transitions!
8795 const oldData = oldChild.data.transition = extend({}, data);
8796 // handle transition mode
8797 if (mode === 'out-in') {
8798 // return placeholder node and queue update when leave finishes
8799 this._leaving = true;
8800 mergeVNodeHook(oldData, 'afterLeave', () => {
8801 this._leaving = false;
8802 this.$forceUpdate();
8803 });
8804 return placeholder(h, rawChild)
8805 } else if (mode === 'in-out') {
8806 if (isAsyncPlaceholder(child)) {
8807 return oldRawChild
8808 }
8809 let delayedLeave;
8810 const performLeave = () => { delayedLeave(); };
8811 mergeVNodeHook(data, 'afterEnter', performLeave);
8812 mergeVNodeHook(data, 'enterCancelled', performLeave);
8813 mergeVNodeHook(oldData, 'delayLeave', leave => { delayedLeave = leave; });
8814 }
8815 }
8816
8817 return rawChild
8818 }
8819};
8820
8821/* */
8822
8823const props = extend({
8824 tag: String,
8825 moveClass: String
8826}, transitionProps);
8827
8828delete props.mode;
8829
8830var TransitionGroup = {
8831 props,
8832
8833 beforeMount () {
8834 const update = this._update;
8835 this._update = (vnode, hydrating) => {
8836 const restoreActiveInstance = setActiveInstance(this);
8837 // force removing pass
8838 this.__patch__(
8839 this._vnode,
8840 this.kept,
8841 false, // hydrating
8842 true // removeOnly (!important, avoids unnecessary moves)
8843 );
8844 this._vnode = this.kept;
8845 restoreActiveInstance();
8846 update.call(this, vnode, hydrating);
8847 };
8848 },
8849
8850 render (h) {
8851 const tag = this.tag || this.$vnode.data.tag || 'span';
8852 const map = Object.create(null);
8853 const prevChildren = this.prevChildren = this.children;
8854 const rawChildren = this.$slots.default || [];
8855 const children = this.children = [];
8856 const transitionData = extractTransitionData(this);
8857
8858 for (let i = 0; i < rawChildren.length; i++) {
8859 const c = rawChildren[i];
8860 if (c.tag) {
8861 if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
8862 children.push(c);
8863 map[c.key] = c
8864 ;(c.data || (c.data = {})).transition = transitionData;
8865 } else {
8866 const opts = c.componentOptions;
8867 const name = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag;
8868 warn(`<transition-group> children must be keyed: <${name}>`);
8869 }
8870 }
8871 }
8872
8873 if (prevChildren) {
8874 const kept = [];
8875 const removed = [];
8876 for (let i = 0; i < prevChildren.length; i++) {
8877 const c = prevChildren[i];
8878 c.data.transition = transitionData;
8879 c.data.pos = c.elm.getBoundingClientRect();
8880 if (map[c.key]) {
8881 kept.push(c);
8882 } else {
8883 removed.push(c);
8884 }
8885 }
8886 this.kept = h(tag, null, kept);
8887 this.removed = removed;
8888 }
8889
8890 return h(tag, null, children)
8891 },
8892
8893 updated () {
8894 const children = this.prevChildren;
8895 const moveClass = this.moveClass || ((this.name || 'v') + '-move');
8896 if (!children.length || !this.hasMove(children[0].elm, moveClass)) {
8897 return
8898 }
8899
8900 // we divide the work into three loops to avoid mixing DOM reads and writes
8901 // in each iteration - which helps prevent layout thrashing.
8902 children.forEach(callPendingCbs);
8903 children.forEach(recordPosition);
8904 children.forEach(applyTranslation);
8905
8906 // force reflow to put everything in position
8907 // assign to this to avoid being removed in tree-shaking
8908 // $flow-disable-line
8909 this._reflow = document.body.offsetHeight;
8910
8911 children.forEach((c) => {
8912 if (c.data.moved) {
8913 const el = c.elm;
8914 const s = el.style;
8915 addTransitionClass(el, moveClass);
8916 s.transform = s.WebkitTransform = s.transitionDuration = '';
8917 el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {
8918 if (e && e.target !== el) {
8919 return
8920 }
8921 if (!e || /transform$/.test(e.propertyName)) {
8922 el.removeEventListener(transitionEndEvent, cb);
8923 el._moveCb = null;
8924 removeTransitionClass(el, moveClass);
8925 }
8926 });
8927 }
8928 });
8929 },
8930
8931 methods: {
8932 hasMove (el, moveClass) {
8933 /* istanbul ignore if */
8934 if (!hasTransition) {
8935 return false
8936 }
8937 /* istanbul ignore if */
8938 if (this._hasMove) {
8939 return this._hasMove
8940 }
8941 // Detect whether an element with the move class applied has
8942 // CSS transitions. Since the element may be inside an entering
8943 // transition at this very moment, we make a clone of it and remove
8944 // all other transition classes applied to ensure only the move class
8945 // is applied.
8946 const clone = el.cloneNode();
8947 if (el._transitionClasses) {
8948 el._transitionClasses.forEach((cls) => { removeClass(clone, cls); });
8949 }
8950 addClass(clone, moveClass);
8951 clone.style.display = 'none';
8952 this.$el.appendChild(clone);
8953 const info = getTransitionInfo(clone);
8954 this.$el.removeChild(clone);
8955 return (this._hasMove = info.hasTransform)
8956 }
8957 }
8958};
8959
8960function callPendingCbs (c) {
8961 /* istanbul ignore if */
8962 if (c.elm._moveCb) {
8963 c.elm._moveCb();
8964 }
8965 /* istanbul ignore if */
8966 if (c.elm._enterCb) {
8967 c.elm._enterCb();
8968 }
8969}
8970
8971function recordPosition (c) {
8972 c.data.newPos = c.elm.getBoundingClientRect();
8973}
8974
8975function applyTranslation (c) {
8976 const oldPos = c.data.pos;
8977 const newPos = c.data.newPos;
8978 const dx = oldPos.left - newPos.left;
8979 const dy = oldPos.top - newPos.top;
8980 if (dx || dy) {
8981 c.data.moved = true;
8982 const s = c.elm.style;
8983 s.transform = s.WebkitTransform = `translate(${dx}px,${dy}px)`;
8984 s.transitionDuration = '0s';
8985 }
8986}
8987
8988var platformComponents = {
8989 Transition,
8990 TransitionGroup
8991};
8992
8993/* */
8994
8995// install platform specific utils
8996Vue.config.mustUseProp = mustUseProp;
8997Vue.config.isReservedTag = isReservedTag;
8998Vue.config.isReservedAttr = isReservedAttr;
8999Vue.config.getTagNamespace = getTagNamespace;
9000Vue.config.isUnknownElement = isUnknownElement;
9001
9002// install platform runtime directives & components
9003extend(Vue.options.directives, platformDirectives);
9004extend(Vue.options.components, platformComponents);
9005
9006// install platform patch function
9007Vue.prototype.__patch__ = inBrowser ? patch : noop;
9008
9009// public mount method
9010Vue.prototype.$mount = function (
9011 el,
9012 hydrating
9013) {
9014 el = el && inBrowser ? query(el) : undefined;
9015 return mountComponent(this, el, hydrating)
9016};
9017
9018// devtools global hook
9019/* istanbul ignore next */
9020if (inBrowser) {
9021 setTimeout(() => {
9022 if (config.devtools) {
9023 if (devtools) {
9024 devtools.emit('init', Vue);
9025 } else {
9026 console[console.info ? 'info' : 'log'](
9027 'Download the Vue Devtools extension for a better development experience:\n' +
9028 'https://github.com/vuejs/vue-devtools'
9029 );
9030 }
9031 }
9032 if (config.productionTip !== false &&
9033 typeof console !== 'undefined'
9034 ) {
9035 console[console.info ? 'info' : 'log'](
9036 `You are running Vue in development mode.\n` +
9037 `Make sure to turn on production mode when deploying for production.\n` +
9038 `See more tips at https://vuejs.org/guide/deployment.html`
9039 );
9040 }
9041 }, 0);
9042}
9043
9044/* */
9045
9046const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;
9047const regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
9048
9049const buildRegex = cached(delimiters => {
9050 const open = delimiters[0].replace(regexEscapeRE, '\\$&');
9051 const close = delimiters[1].replace(regexEscapeRE, '\\$&');
9052 return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
9053});
9054
9055
9056
9057function parseText (
9058 text,
9059 delimiters
9060) {
9061 const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
9062 if (!tagRE.test(text)) {
9063 return
9064 }
9065 const tokens = [];
9066 const rawTokens = [];
9067 let lastIndex = tagRE.lastIndex = 0;
9068 let match, index, tokenValue;
9069 while ((match = tagRE.exec(text))) {
9070 index = match.index;
9071 // push text token
9072 if (index > lastIndex) {
9073 rawTokens.push(tokenValue = text.slice(lastIndex, index));
9074 tokens.push(JSON.stringify(tokenValue));
9075 }
9076 // tag token
9077 const exp = parseFilters(match[1].trim());
9078 tokens.push(`_s(${exp})`);
9079 rawTokens.push({ '@binding': exp });
9080 lastIndex = index + match[0].length;
9081 }
9082 if (lastIndex < text.length) {
9083 rawTokens.push(tokenValue = text.slice(lastIndex));
9084 tokens.push(JSON.stringify(tokenValue));
9085 }
9086 return {
9087 expression: tokens.join('+'),
9088 tokens: rawTokens
9089 }
9090}
9091
9092/* */
9093
9094function transformNode (el, options) {
9095 const warn = options.warn || baseWarn;
9096 const staticClass = getAndRemoveAttr(el, 'class');
9097 if (staticClass) {
9098 const res = parseText(staticClass, options.delimiters);
9099 if (res) {
9100 warn(
9101 `class="${staticClass}": ` +
9102 'Interpolation inside attributes has been removed. ' +
9103 'Use v-bind or the colon shorthand instead. For example, ' +
9104 'instead of <div class="{{ val }}">, use <div :class="val">.',
9105 el.rawAttrsMap['class']
9106 );
9107 }
9108 }
9109 if (staticClass) {
9110 el.staticClass = JSON.stringify(staticClass);
9111 }
9112 const classBinding = getBindingAttr(el, 'class', false /* getStatic */);
9113 if (classBinding) {
9114 el.classBinding = classBinding;
9115 }
9116}
9117
9118function genData (el) {
9119 let data = '';
9120 if (el.staticClass) {
9121 data += `staticClass:${el.staticClass},`;
9122 }
9123 if (el.classBinding) {
9124 data += `class:${el.classBinding},`;
9125 }
9126 return data
9127}
9128
9129var klass$1 = {
9130 staticKeys: ['staticClass'],
9131 transformNode,
9132 genData
9133};
9134
9135/* */
9136
9137function transformNode$1 (el, options) {
9138 const warn = options.warn || baseWarn;
9139 const staticStyle = getAndRemoveAttr(el, 'style');
9140 if (staticStyle) {
9141 /* istanbul ignore if */
9142 {
9143 const res = parseText(staticStyle, options.delimiters);
9144 if (res) {
9145 warn(
9146 `style="${staticStyle}": ` +
9147 'Interpolation inside attributes has been removed. ' +
9148 'Use v-bind or the colon shorthand instead. For example, ' +
9149 'instead of <div style="{{ val }}">, use <div :style="val">.',
9150 el.rawAttrsMap['style']
9151 );
9152 }
9153 }
9154 el.staticStyle = JSON.stringify(parseStyleText(staticStyle));
9155 }
9156
9157 const styleBinding = getBindingAttr(el, 'style', false /* getStatic */);
9158 if (styleBinding) {
9159 el.styleBinding = styleBinding;
9160 }
9161}
9162
9163function genData$1 (el) {
9164 let data = '';
9165 if (el.staticStyle) {
9166 data += `staticStyle:${el.staticStyle},`;
9167 }
9168 if (el.styleBinding) {
9169 data += `style:(${el.styleBinding}),`;
9170 }
9171 return data
9172}
9173
9174var style$1 = {
9175 staticKeys: ['staticStyle'],
9176 transformNode: transformNode$1,
9177 genData: genData$1
9178};
9179
9180/* */
9181
9182let decoder;
9183
9184var he = {
9185 decode (html) {
9186 decoder = decoder || document.createElement('div');
9187 decoder.innerHTML = html;
9188 return decoder.textContent
9189 }
9190};
9191
9192/* */
9193
9194const isUnaryTag = makeMap(
9195 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
9196 'link,meta,param,source,track,wbr'
9197);
9198
9199// Elements that you can, intentionally, leave open
9200// (and which close themselves)
9201const canBeLeftOpenTag = makeMap(
9202 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source'
9203);
9204
9205// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
9206// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
9207const isNonPhrasingTag = makeMap(
9208 'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
9209 'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
9210 'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
9211 'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
9212 'title,tr,track'
9213);
9214
9215/**
9216 * Not type-checking this file because it's mostly vendor code.
9217 */
9218
9219// Regular Expressions for parsing tags and attributes
9220const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9221const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9222const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeLetters}]*`;
9223const qnameCapture = `((?:${ncname}\\:)?${ncname})`;
9224const startTagOpen = new RegExp(`^<${qnameCapture}`);
9225const startTagClose = /^\s*(\/?)>/;
9226const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`);
9227const doctype = /^<!DOCTYPE [^>]+>/i;
9228// #7298: escape - to avoid being pased as HTML comment when inlined in page
9229const comment = /^<!\--/;
9230const conditionalComment = /^<!\[/;
9231
9232// Special Elements (can contain anything)
9233const isPlainTextElement = makeMap('script,style,textarea', true);
9234const reCache = {};
9235
9236const decodingMap = {
9237 '&lt;': '<',
9238 '&gt;': '>',
9239 '&quot;': '"',
9240 '&amp;': '&',
9241 '&#10;': '\n',
9242 '&#9;': '\t',
9243 '&#39;': "'"
9244};
9245const encodedAttr = /&(?:lt|gt|quot|amp|#39);/g;
9246const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#39|#10|#9);/g;
9247
9248// #5992
9249const isIgnoreNewlineTag = makeMap('pre,textarea', true);
9250const shouldIgnoreFirstNewline = (tag, html) => tag && isIgnoreNewlineTag(tag) && html[0] === '\n';
9251
9252function decodeAttr (value, shouldDecodeNewlines) {
9253 const re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr;
9254 return value.replace(re, match => decodingMap[match])
9255}
9256
9257function parseHTML (html, options) {
9258 const stack = [];
9259 const expectHTML = options.expectHTML;
9260 const isUnaryTag$$1 = options.isUnaryTag || no;
9261 const canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;
9262 let index = 0;
9263 let last, lastTag;
9264 while (html) {
9265 last = html;
9266 // Make sure we're not in a plaintext content element like script/style
9267 if (!lastTag || !isPlainTextElement(lastTag)) {
9268 let textEnd = html.indexOf('<');
9269 if (textEnd === 0) {
9270 // Comment:
9271 if (comment.test(html)) {
9272 const commentEnd = html.indexOf('-->');
9273
9274 if (commentEnd >= 0) {
9275 if (options.shouldKeepComment) {
9276 options.comment(html.substring(4, commentEnd), index, index + commentEnd + 3);
9277 }
9278 advance(commentEnd + 3);
9279 continue
9280 }
9281 }
9282
9283 // http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
9284 if (conditionalComment.test(html)) {
9285 const conditionalEnd = html.indexOf(']>');
9286
9287 if (conditionalEnd >= 0) {
9288 advance(conditionalEnd + 2);
9289 continue
9290 }
9291 }
9292
9293 // Doctype:
9294 const doctypeMatch = html.match(doctype);
9295 if (doctypeMatch) {
9296 advance(doctypeMatch[0].length);
9297 continue
9298 }
9299
9300 // End tag:
9301 const endTagMatch = html.match(endTag);
9302 if (endTagMatch) {
9303 const curIndex = index;
9304 advance(endTagMatch[0].length);
9305 parseEndTag(endTagMatch[1], curIndex, index);
9306 continue
9307 }
9308
9309 // Start tag:
9310 const startTagMatch = parseStartTag();
9311 if (startTagMatch) {
9312 handleStartTag(startTagMatch);
9313 if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
9314 advance(1);
9315 }
9316 continue
9317 }
9318 }
9319
9320 let text, rest, next;
9321 if (textEnd >= 0) {
9322 rest = html.slice(textEnd);
9323 while (
9324 !endTag.test(rest) &&
9325 !startTagOpen.test(rest) &&
9326 !comment.test(rest) &&
9327 !conditionalComment.test(rest)
9328 ) {
9329 // < in plain text, be forgiving and treat it as text
9330 next = rest.indexOf('<', 1);
9331 if (next < 0) break
9332 textEnd += next;
9333 rest = html.slice(textEnd);
9334 }
9335 text = html.substring(0, textEnd);
9336 }
9337
9338 if (textEnd < 0) {
9339 text = html;
9340 }
9341
9342 if (text) {
9343 advance(text.length);
9344 }
9345
9346 if (options.chars && text) {
9347 options.chars(text, index - text.length, index);
9348 }
9349 } else {
9350 let endTagLength = 0;
9351 const stackedTag = lastTag.toLowerCase();
9352 const reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i'));
9353 const rest = html.replace(reStackedTag, function (all, text, endTag) {
9354 endTagLength = endTag.length;
9355 if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
9356 text = text
9357 .replace(/<!\--([\s\S]*?)-->/g, '$1') // #7298
9358 .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
9359 }
9360 if (shouldIgnoreFirstNewline(stackedTag, text)) {
9361 text = text.slice(1);
9362 }
9363 if (options.chars) {
9364 options.chars(text);
9365 }
9366 return ''
9367 });
9368 index += html.length - rest.length;
9369 html = rest;
9370 parseEndTag(stackedTag, index - endTagLength, index);
9371 }
9372
9373 if (html === last) {
9374 options.chars && options.chars(html);
9375 if (!stack.length && options.warn) {
9376 options.warn(`Mal-formatted tag at end of template: "${html}"`, { start: index + html.length });
9377 }
9378 break
9379 }
9380 }
9381
9382 // Clean up any remaining tags
9383 parseEndTag();
9384
9385 function advance (n) {
9386 index += n;
9387 html = html.substring(n);
9388 }
9389
9390 function parseStartTag () {
9391 const start = html.match(startTagOpen);
9392 if (start) {
9393 const match = {
9394 tagName: start[1],
9395 attrs: [],
9396 start: index
9397 };
9398 advance(start[0].length);
9399 let end, attr;
9400 while (!(end = html.match(startTagClose)) && (attr = html.match(dynamicArgAttribute) || html.match(attribute))) {
9401 attr.start = index;
9402 advance(attr[0].length);
9403 attr.end = index;
9404 match.attrs.push(attr);
9405 }
9406 if (end) {
9407 match.unarySlash = end[1];
9408 advance(end[0].length);
9409 match.end = index;
9410 return match
9411 }
9412 }
9413 }
9414
9415 function handleStartTag (match) {
9416 const tagName = match.tagName;
9417 const unarySlash = match.unarySlash;
9418
9419 if (expectHTML) {
9420 if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
9421 parseEndTag(lastTag);
9422 }
9423 if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) {
9424 parseEndTag(tagName);
9425 }
9426 }
9427
9428 const unary = isUnaryTag$$1(tagName) || !!unarySlash;
9429
9430 const l = match.attrs.length;
9431 const attrs = new Array(l);
9432 for (let i = 0; i < l; i++) {
9433 const args = match.attrs[i];
9434 const value = args[3] || args[4] || args[5] || '';
9435 const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'
9436 ? options.shouldDecodeNewlinesForHref
9437 : options.shouldDecodeNewlines;
9438 attrs[i] = {
9439 name: args[1],
9440 value: decodeAttr(value, shouldDecodeNewlines)
9441 };
9442 if (options.outputSourceRange) {
9443 attrs[i].start = args.start + args[0].match(/^\s*/).length;
9444 attrs[i].end = args.end;
9445 }
9446 }
9447
9448 if (!unary) {
9449 stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs, start: match.start, end: match.end });
9450 lastTag = tagName;
9451 }
9452
9453 if (options.start) {
9454 options.start(tagName, attrs, unary, match.start, match.end);
9455 }
9456 }
9457
9458 function parseEndTag (tagName, start, end) {
9459 let pos, lowerCasedTagName;
9460 if (start == null) start = index;
9461 if (end == null) end = index;
9462
9463 // Find the closest opened tag of the same type
9464 if (tagName) {
9465 lowerCasedTagName = tagName.toLowerCase();
9466 for (pos = stack.length - 1; pos >= 0; pos--) {
9467 if (stack[pos].lowerCasedTag === lowerCasedTagName) {
9468 break
9469 }
9470 }
9471 } else {
9472 // If no tag name is provided, clean shop
9473 pos = 0;
9474 }
9475
9476 if (pos >= 0) {
9477 // Close all the open elements, up the stack
9478 for (let i = stack.length - 1; i >= pos; i--) {
9479 if (i > pos || !tagName &&
9480 options.warn
9481 ) {
9482 options.warn(
9483 `tag <${stack[i].tag}> has no matching end tag.`,
9484 { start: stack[i].start }
9485 );
9486 }
9487 if (options.end) {
9488 options.end(stack[i].tag, start, end);
9489 }
9490 }
9491
9492 // Remove the open elements from the stack
9493 stack.length = pos;
9494 lastTag = pos && stack[pos - 1].tag;
9495 } else if (lowerCasedTagName === 'br') {
9496 if (options.start) {
9497 options.start(tagName, [], true, start, end);
9498 }
9499 } else if (lowerCasedTagName === 'p') {
9500 if (options.start) {
9501 options.start(tagName, [], false, start, end);
9502 }
9503 if (options.end) {
9504 options.end(tagName, start, end);
9505 }
9506 }
9507 }
9508}
9509
9510/* */
9511
9512const onRE = /^@|^v-on:/;
9513const dirRE = /^v-|^@|^:/;
9514const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
9515const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
9516const stripParensRE = /^\(|\)$/g;
9517const dynamicArgRE = /^\[.*\]$/;
9518
9519const argRE = /:(.*)$/;
9520const bindRE = /^:|^\.|^v-bind:/;
9521const modifierRE = /\.[^.]+/g;
9522
9523const slotRE = /^v-slot(:|$)|^#/;
9524
9525const lineBreakRE = /[\r\n]/;
9526const whitespaceRE$1 = /\s+/g;
9527
9528const invalidAttributeRE = /[\s"'<>\/=]/;
9529
9530const decodeHTMLCached = cached(he.decode);
9531
9532const emptySlotScopeToken = `_empty_`;
9533
9534// configurable state
9535let warn$2;
9536let delimiters;
9537let transforms;
9538let preTransforms;
9539let postTransforms;
9540let platformIsPreTag;
9541let platformMustUseProp;
9542let platformGetTagNamespace;
9543let maybeComponent;
9544
9545function createASTElement (
9546 tag,
9547 attrs,
9548 parent
9549) {
9550 return {
9551 type: 1,
9552 tag,
9553 attrsList: attrs,
9554 attrsMap: makeAttrsMap(attrs),
9555 rawAttrsMap: {},
9556 parent,
9557 children: []
9558 }
9559}
9560
9561/**
9562 * Convert HTML string to AST.
9563 */
9564function parse (
9565 template,
9566 options
9567) {
9568 warn$2 = options.warn || baseWarn;
9569
9570 platformIsPreTag = options.isPreTag || no;
9571 platformMustUseProp = options.mustUseProp || no;
9572 platformGetTagNamespace = options.getTagNamespace || no;
9573 const isReservedTag = options.isReservedTag || no;
9574 maybeComponent = (el) => !!el.component || !isReservedTag(el.tag);
9575
9576 transforms = pluckModuleFunction(options.modules, 'transformNode');
9577 preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
9578 postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');
9579
9580 delimiters = options.delimiters;
9581
9582 const stack = [];
9583 const preserveWhitespace = options.preserveWhitespace !== false;
9584 const whitespaceOption = options.whitespace;
9585 let root;
9586 let currentParent;
9587 let inVPre = false;
9588 let inPre = false;
9589 let warned = false;
9590
9591 function warnOnce (msg, range) {
9592 if (!warned) {
9593 warned = true;
9594 warn$2(msg, range);
9595 }
9596 }
9597
9598 function closeElement (element) {
9599 trimEndingWhitespace(element);
9600 if (!inVPre && !element.processed) {
9601 element = processElement(element, options);
9602 }
9603 // tree management
9604 if (!stack.length && element !== root) {
9605 // allow root elements with v-if, v-else-if and v-else
9606 if (root.if && (element.elseif || element.else)) {
9607 {
9608 checkRootConstraints(element);
9609 }
9610 addIfCondition(root, {
9611 exp: element.elseif,
9612 block: element
9613 });
9614 } else {
9615 warnOnce(
9616 `Component template should contain exactly one root element. ` +
9617 `If you are using v-if on multiple elements, ` +
9618 `use v-else-if to chain them instead.`,
9619 { start: element.start }
9620 );
9621 }
9622 }
9623 if (currentParent && !element.forbidden) {
9624 if (element.elseif || element.else) {
9625 processIfConditions(element, currentParent);
9626 } else {
9627 if (element.slotScope) {
9628 // scoped slot
9629 // keep it in the children list so that v-else(-if) conditions can
9630 // find it as the prev node.
9631 const name = element.slotTarget || '"default"'
9632 ;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element;
9633 }
9634 currentParent.children.push(element);
9635 element.parent = currentParent;
9636 }
9637 }
9638
9639 // final children cleanup
9640 // filter out scoped slots
9641 element.children = element.children.filter(c => !(c).slotScope);
9642 // remove trailing whitespace node again
9643 trimEndingWhitespace(element);
9644
9645 // check pre state
9646 if (element.pre) {
9647 inVPre = false;
9648 }
9649 if (platformIsPreTag(element.tag)) {
9650 inPre = false;
9651 }
9652 // apply post-transforms
9653 for (let i = 0; i < postTransforms.length; i++) {
9654 postTransforms[i](element, options);
9655 }
9656 }
9657
9658 function trimEndingWhitespace (el) {
9659 // remove trailing whitespace node
9660 if (!inPre) {
9661 let lastNode;
9662 while (
9663 (lastNode = el.children[el.children.length - 1]) &&
9664 lastNode.type === 3 &&
9665 lastNode.text === ' '
9666 ) {
9667 el.children.pop();
9668 }
9669 }
9670 }
9671
9672 function checkRootConstraints (el) {
9673 if (el.tag === 'slot' || el.tag === 'template') {
9674 warnOnce(
9675 `Cannot use <${el.tag}> as component root element because it may ` +
9676 'contain multiple nodes.',
9677 { start: el.start }
9678 );
9679 }
9680 if (el.attrsMap.hasOwnProperty('v-for')) {
9681 warnOnce(
9682 'Cannot use v-for on stateful component root element because ' +
9683 'it renders multiple elements.',
9684 el.rawAttrsMap['v-for']
9685 );
9686 }
9687 }
9688
9689 parseHTML(template, {
9690 warn: warn$2,
9691 expectHTML: options.expectHTML,
9692 isUnaryTag: options.isUnaryTag,
9693 canBeLeftOpenTag: options.canBeLeftOpenTag,
9694 shouldDecodeNewlines: options.shouldDecodeNewlines,
9695 shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
9696 shouldKeepComment: options.comments,
9697 outputSourceRange: options.outputSourceRange,
9698 start (tag, attrs, unary, start) {
9699 // check namespace.
9700 // inherit parent ns if there is one
9701 const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);
9702
9703 // handle IE svg bug
9704 /* istanbul ignore if */
9705 if (isIE && ns === 'svg') {
9706 attrs = guardIESVGBug(attrs);
9707 }
9708
9709 let element = createASTElement(tag, attrs, currentParent);
9710 if (ns) {
9711 element.ns = ns;
9712 }
9713
9714 {
9715 if (options.outputSourceRange) {
9716 element.start = start;
9717 element.rawAttrsMap = element.attrsList.reduce((cumulated, attr) => {
9718 cumulated[attr.name] = attr;
9719 return cumulated
9720 }, {});
9721 }
9722 attrs.forEach(attr => {
9723 if (invalidAttributeRE.test(attr.name)) {
9724 warn$2(
9725 `Invalid dynamic argument expression: attribute names cannot contain ` +
9726 `spaces, quotes, <, >, / or =.`,
9727 {
9728 start: attr.start + attr.name.indexOf(`[`),
9729 end: attr.start + attr.name.length
9730 }
9731 );
9732 }
9733 });
9734 }
9735
9736 if (isForbiddenTag(element) && !isServerRendering()) {
9737 element.forbidden = true;
9738 warn$2(
9739 'Templates should only be responsible for mapping the state to the ' +
9740 'UI. Avoid placing tags with side-effects in your templates, such as ' +
9741 `<${tag}>` + ', as they will not be parsed.',
9742 { start: element.start }
9743 );
9744 }
9745
9746 // apply pre-transforms
9747 for (let i = 0; i < preTransforms.length; i++) {
9748 element = preTransforms[i](element, options) || element;
9749 }
9750
9751 if (!inVPre) {
9752 processPre(element);
9753 if (element.pre) {
9754 inVPre = true;
9755 }
9756 }
9757 if (platformIsPreTag(element.tag)) {
9758 inPre = true;
9759 }
9760 if (inVPre) {
9761 processRawAttrs(element);
9762 } else if (!element.processed) {
9763 // structural directives
9764 processFor(element);
9765 processIf(element);
9766 processOnce(element);
9767 }
9768
9769 if (!root) {
9770 root = element;
9771 {
9772 checkRootConstraints(root);
9773 }
9774 }
9775
9776 if (!unary) {
9777 currentParent = element;
9778 stack.push(element);
9779 } else {
9780 closeElement(element);
9781 }
9782 },
9783
9784 end (tag, start, end) {
9785 const element = stack[stack.length - 1];
9786 // pop stack
9787 stack.length -= 1;
9788 currentParent = stack[stack.length - 1];
9789 if (options.outputSourceRange) {
9790 element.end = end;
9791 }
9792 closeElement(element);
9793 },
9794
9795 chars (text, start, end) {
9796 if (!currentParent) {
9797 {
9798 if (text === template) {
9799 warnOnce(
9800 'Component template requires a root element, rather than just text.',
9801 { start }
9802 );
9803 } else if ((text = text.trim())) {
9804 warnOnce(
9805 `text "${text}" outside root element will be ignored.`,
9806 { start }
9807 );
9808 }
9809 }
9810 return
9811 }
9812 // IE textarea placeholder bug
9813 /* istanbul ignore if */
9814 if (isIE &&
9815 currentParent.tag === 'textarea' &&
9816 currentParent.attrsMap.placeholder === text
9817 ) {
9818 return
9819 }
9820 const children = currentParent.children;
9821 if (inPre || text.trim()) {
9822 text = isTextTag(currentParent) ? text : decodeHTMLCached(text);
9823 } else if (!children.length) {
9824 // remove the whitespace-only node right after an opening tag
9825 text = '';
9826 } else if (whitespaceOption) {
9827 if (whitespaceOption === 'condense') {
9828 // in condense mode, remove the whitespace node if it contains
9829 // line break, otherwise condense to a single space
9830 text = lineBreakRE.test(text) ? '' : ' ';
9831 } else {
9832 text = ' ';
9833 }
9834 } else {
9835 text = preserveWhitespace ? ' ' : '';
9836 }
9837 if (text) {
9838 if (whitespaceOption === 'condense') {
9839 // condense consecutive whitespaces into single space
9840 text = text.replace(whitespaceRE$1, ' ');
9841 }
9842 let res;
9843 let child;
9844 if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {
9845 child = {
9846 type: 2,
9847 expression: res.expression,
9848 tokens: res.tokens,
9849 text
9850 };
9851 } else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') {
9852 child = {
9853 type: 3,
9854 text
9855 };
9856 }
9857 if (child) {
9858 if (options.outputSourceRange) {
9859 child.start = start;
9860 child.end = end;
9861 }
9862 children.push(child);
9863 }
9864 }
9865 },
9866 comment (text, start, end) {
9867 // adding anyting as a sibling to the root node is forbidden
9868 // comments should still be allowed, but ignored
9869 if (currentParent) {
9870 const child = {
9871 type: 3,
9872 text,
9873 isComment: true
9874 };
9875 if (options.outputSourceRange) {
9876 child.start = start;
9877 child.end = end;
9878 }
9879 currentParent.children.push(child);
9880 }
9881 }
9882 });
9883 return root
9884}
9885
9886function processPre (el) {
9887 if (getAndRemoveAttr(el, 'v-pre') != null) {
9888 el.pre = true;
9889 }
9890}
9891
9892function processRawAttrs (el) {
9893 const list = el.attrsList;
9894 const len = list.length;
9895 if (len) {
9896 const attrs = el.attrs = new Array(len);
9897 for (let i = 0; i < len; i++) {
9898 attrs[i] = {
9899 name: list[i].name,
9900 value: JSON.stringify(list[i].value)
9901 };
9902 if (list[i].start != null) {
9903 attrs[i].start = list[i].start;
9904 attrs[i].end = list[i].end;
9905 }
9906 }
9907 } else if (!el.pre) {
9908 // non root node in pre blocks with no attributes
9909 el.plain = true;
9910 }
9911}
9912
9913function processElement (
9914 element,
9915 options
9916) {
9917 processKey(element);
9918
9919 // determine whether this is a plain element after
9920 // removing structural attributes
9921 element.plain = (
9922 !element.key &&
9923 !element.scopedSlots &&
9924 !element.attrsList.length
9925 );
9926
9927 processRef(element);
9928 processSlotContent(element);
9929 processSlotOutlet(element);
9930 processComponent(element);
9931 for (let i = 0; i < transforms.length; i++) {
9932 element = transforms[i](element, options) || element;
9933 }
9934 processAttrs(element);
9935 return element
9936}
9937
9938function processKey (el) {
9939 const exp = getBindingAttr(el, 'key');
9940 if (exp) {
9941 {
9942 if (el.tag === 'template') {
9943 warn$2(
9944 `<template> cannot be keyed. Place the key on real elements instead.`,
9945 getRawBindingAttr(el, 'key')
9946 );
9947 }
9948 if (el.for) {
9949 const iterator = el.iterator2 || el.iterator1;
9950 const parent = el.parent;
9951 if (iterator && iterator === exp && parent && parent.tag === 'transition-group') {
9952 warn$2(
9953 `Do not use v-for index as key on <transition-group> children, ` +
9954 `this is the same as not using keys.`,
9955 getRawBindingAttr(el, 'key'),
9956 true /* tip */
9957 );
9958 }
9959 }
9960 }
9961 el.key = exp;
9962 }
9963}
9964
9965function processRef (el) {
9966 const ref = getBindingAttr(el, 'ref');
9967 if (ref) {
9968 el.ref = ref;
9969 el.refInFor = checkInFor(el);
9970 }
9971}
9972
9973function processFor (el) {
9974 let exp;
9975 if ((exp = getAndRemoveAttr(el, 'v-for'))) {
9976 const res = parseFor(exp);
9977 if (res) {
9978 extend(el, res);
9979 } else {
9980 warn$2(
9981 `Invalid v-for expression: ${exp}`,
9982 el.rawAttrsMap['v-for']
9983 );
9984 }
9985 }
9986}
9987
9988
9989
9990function parseFor (exp) {
9991 const inMatch = exp.match(forAliasRE);
9992 if (!inMatch) return
9993 const res = {};
9994 res.for = inMatch[2].trim();
9995 const alias = inMatch[1].trim().replace(stripParensRE, '');
9996 const iteratorMatch = alias.match(forIteratorRE);
9997 if (iteratorMatch) {
9998 res.alias = alias.replace(forIteratorRE, '').trim();
9999 res.iterator1 = iteratorMatch[1].trim();
10000 if (iteratorMatch[2]) {
10001 res.iterator2 = iteratorMatch[2].trim();
10002 }
10003 } else {
10004 res.alias = alias;
10005 }
10006 return res
10007}
10008
10009function processIf (el) {
10010 const exp = getAndRemoveAttr(el, 'v-if');
10011 if (exp) {
10012 el.if = exp;
10013 addIfCondition(el, {
10014 exp: exp,
10015 block: el
10016 });
10017 } else {
10018 if (getAndRemoveAttr(el, 'v-else') != null) {
10019 el.else = true;
10020 }
10021 const elseif = getAndRemoveAttr(el, 'v-else-if');
10022 if (elseif) {
10023 el.elseif = elseif;
10024 }
10025 }
10026}
10027
10028function processIfConditions (el, parent) {
10029 const prev = findPrevElement(parent.children);
10030 if (prev && prev.if) {
10031 addIfCondition(prev, {
10032 exp: el.elseif,
10033 block: el
10034 });
10035 } else {
10036 warn$2(
10037 `v-${el.elseif ? ('else-if="' + el.elseif + '"') : 'else'} ` +
10038 `used on element <${el.tag}> without corresponding v-if.`,
10039 el.rawAttrsMap[el.elseif ? 'v-else-if' : 'v-else']
10040 );
10041 }
10042}
10043
10044function findPrevElement (children) {
10045 let i = children.length;
10046 while (i--) {
10047 if (children[i].type === 1) {
10048 return children[i]
10049 } else {
10050 if (children[i].text !== ' ') {
10051 warn$2(
10052 `text "${children[i].text.trim()}" between v-if and v-else(-if) ` +
10053 `will be ignored.`,
10054 children[i]
10055 );
10056 }
10057 children.pop();
10058 }
10059 }
10060}
10061
10062function addIfCondition (el, condition) {
10063 if (!el.ifConditions) {
10064 el.ifConditions = [];
10065 }
10066 el.ifConditions.push(condition);
10067}
10068
10069function processOnce (el) {
10070 const once$$1 = getAndRemoveAttr(el, 'v-once');
10071 if (once$$1 != null) {
10072 el.once = true;
10073 }
10074}
10075
10076// handle content being passed to a component as slot,
10077// e.g. <template slot="xxx">, <div slot-scope="xxx">
10078function processSlotContent (el) {
10079 let slotScope;
10080 if (el.tag === 'template') {
10081 slotScope = getAndRemoveAttr(el, 'scope');
10082 /* istanbul ignore if */
10083 if (slotScope) {
10084 warn$2(
10085 `the "scope" attribute for scoped slots have been deprecated and ` +
10086 `replaced by "slot-scope" since 2.5. The new "slot-scope" attribute ` +
10087 `can also be used on plain elements in addition to <template> to ` +
10088 `denote scoped slots.`,
10089 el.rawAttrsMap['scope'],
10090 true
10091 );
10092 }
10093 el.slotScope = slotScope || getAndRemoveAttr(el, 'slot-scope');
10094 } else if ((slotScope = getAndRemoveAttr(el, 'slot-scope'))) {
10095 /* istanbul ignore if */
10096 if (el.attrsMap['v-for']) {
10097 warn$2(
10098 `Ambiguous combined usage of slot-scope and v-for on <${el.tag}> ` +
10099 `(v-for takes higher priority). Use a wrapper <template> for the ` +
10100 `scoped slot to make it clearer.`,
10101 el.rawAttrsMap['slot-scope'],
10102 true
10103 );
10104 }
10105 el.slotScope = slotScope;
10106 }
10107
10108 // slot="xxx"
10109 const slotTarget = getBindingAttr(el, 'slot');
10110 if (slotTarget) {
10111 el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget;
10112 el.slotTargetDynamic = !!(el.attrsMap[':slot'] || el.attrsMap['v-bind:slot']);
10113 // preserve slot as an attribute for native shadow DOM compat
10114 // only for non-scoped slots.
10115 if (el.tag !== 'template' && !el.slotScope) {
10116 addAttr(el, 'slot', slotTarget, getRawBindingAttr(el, 'slot'));
10117 }
10118 }
10119
10120 // 2.6 v-slot syntax
10121 {
10122 if (el.tag === 'template') {
10123 // v-slot on <template>
10124 const slotBinding = getAndRemoveAttrByRegex(el, slotRE);
10125 if (slotBinding) {
10126 {
10127 if (el.slotTarget || el.slotScope) {
10128 warn$2(
10129 `Unexpected mixed usage of different slot syntaxes.`,
10130 el
10131 );
10132 }
10133 if (el.parent && !maybeComponent(el.parent)) {
10134 warn$2(
10135 `<template v-slot> can only appear at the root level inside ` +
10136 `the receiving the component`,
10137 el
10138 );
10139 }
10140 }
10141 const { name, dynamic } = getSlotName(slotBinding);
10142 el.slotTarget = name;
10143 el.slotTargetDynamic = dynamic;
10144 el.slotScope = slotBinding.value || emptySlotScopeToken; // force it into a scoped slot for perf
10145 }
10146 } else {
10147 // v-slot on component, denotes default slot
10148 const slotBinding = getAndRemoveAttrByRegex(el, slotRE);
10149 if (slotBinding) {
10150 {
10151 if (!maybeComponent(el)) {
10152 warn$2(
10153 `v-slot can only be used on components or <template>.`,
10154 slotBinding
10155 );
10156 }
10157 if (el.slotScope || el.slotTarget) {
10158 warn$2(
10159 `Unexpected mixed usage of different slot syntaxes.`,
10160 el
10161 );
10162 }
10163 if (el.scopedSlots) {
10164 warn$2(
10165 `To avoid scope ambiguity, the default slot should also use ` +
10166 `<template> syntax when there are other named slots.`,
10167 slotBinding
10168 );
10169 }
10170 }
10171 // add the component's children to its default slot
10172 const slots = el.scopedSlots || (el.scopedSlots = {});
10173 const { name, dynamic } = getSlotName(slotBinding);
10174 const slotContainer = slots[name] = createASTElement('template', [], el);
10175 slotContainer.slotTarget = name;
10176 slotContainer.slotTargetDynamic = dynamic;
10177 slotContainer.children = el.children.filter((c) => {
10178 if (!c.slotScope) {
10179 c.parent = slotContainer;
10180 return true
10181 }
10182 });
10183 slotContainer.slotScope = slotBinding.value || emptySlotScopeToken;
10184 // remove children as they are returned from scopedSlots now
10185 el.children = [];
10186 // mark el non-plain so data gets generated
10187 el.plain = false;
10188 }
10189 }
10190 }
10191}
10192
10193function getSlotName (binding) {
10194 let name = binding.name.replace(slotRE, '');
10195 if (!name) {
10196 if (binding.name[0] !== '#') {
10197 name = 'default';
10198 } else {
10199 warn$2(
10200 `v-slot shorthand syntax requires a slot name.`,
10201 binding
10202 );
10203 }
10204 }
10205 return dynamicArgRE.test(name)
10206 // dynamic [name]
10207 ? { name: name.slice(1, -1), dynamic: true }
10208 // static name
10209 : { name: `"${name}"`, dynamic: false }
10210}
10211
10212// handle <slot/> outlets
10213function processSlotOutlet (el) {
10214 if (el.tag === 'slot') {
10215 el.slotName = getBindingAttr(el, 'name');
10216 if (el.key) {
10217 warn$2(
10218 `\`key\` does not work on <slot> because slots are abstract outlets ` +
10219 `and can possibly expand into multiple elements. ` +
10220 `Use the key on a wrapping element instead.`,
10221 getRawBindingAttr(el, 'key')
10222 );
10223 }
10224 }
10225}
10226
10227function processComponent (el) {
10228 let binding;
10229 if ((binding = getBindingAttr(el, 'is'))) {
10230 el.component = binding;
10231 }
10232 if (getAndRemoveAttr(el, 'inline-template') != null) {
10233 el.inlineTemplate = true;
10234 }
10235}
10236
10237function processAttrs (el) {
10238 const list = el.attrsList;
10239 let i, l, name, rawName, value, modifiers, syncGen, isDynamic;
10240 for (i = 0, l = list.length; i < l; i++) {
10241 name = rawName = list[i].name;
10242 value = list[i].value;
10243 if (dirRE.test(name)) {
10244 // mark element as dynamic
10245 el.hasBindings = true;
10246 // modifiers
10247 modifiers = parseModifiers(name.replace(dirRE, ''));
10248 // support .foo shorthand syntax for the .prop modifier
10249 if (modifiers) {
10250 name = name.replace(modifierRE, '');
10251 }
10252 if (bindRE.test(name)) { // v-bind
10253 name = name.replace(bindRE, '');
10254 value = parseFilters(value);
10255 isDynamic = dynamicArgRE.test(name);
10256 if (isDynamic) {
10257 name = name.slice(1, -1);
10258 }
10259 if (
10260 value.trim().length === 0
10261 ) {
10262 warn$2(
10263 `The value for a v-bind expression cannot be empty. Found in "v-bind:${name}"`
10264 );
10265 }
10266 if (modifiers) {
10267 if (modifiers.prop && !isDynamic) {
10268 name = camelize(name);
10269 if (name === 'innerHtml') name = 'innerHTML';
10270 }
10271 if (modifiers.camel && !isDynamic) {
10272 name = camelize(name);
10273 }
10274 if (modifiers.sync) {
10275 syncGen = genAssignmentCode(value, `$event`);
10276 if (!isDynamic) {
10277 addHandler(
10278 el,
10279 `update:${camelize(name)}`,
10280 syncGen,
10281 null,
10282 false,
10283 warn$2,
10284 list[i]
10285 );
10286 if (hyphenate(name) !== camelize(name)) {
10287 addHandler(
10288 el,
10289 `update:${hyphenate(name)}`,
10290 syncGen,
10291 null,
10292 false,
10293 warn$2,
10294 list[i]
10295 );
10296 }
10297 } else {
10298 // handler w/ dynamic event name
10299 addHandler(
10300 el,
10301 `"update:"+(${name})`,
10302 syncGen,
10303 null,
10304 false,
10305 warn$2,
10306 list[i],
10307 true // dynamic
10308 );
10309 }
10310 }
10311 }
10312 if ((modifiers && modifiers.prop) || (
10313 !el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)
10314 )) {
10315 addProp(el, name, value, list[i], isDynamic);
10316 } else {
10317 addAttr(el, name, value, list[i], isDynamic);
10318 }
10319 } else if (onRE.test(name)) { // v-on
10320 name = name.replace(onRE, '');
10321 isDynamic = dynamicArgRE.test(name);
10322 if (isDynamic) {
10323 name = name.slice(1, -1);
10324 }
10325 addHandler(el, name, value, modifiers, false, warn$2, list[i], isDynamic);
10326 } else { // normal directives
10327 name = name.replace(dirRE, '');
10328 // parse arg
10329 const argMatch = name.match(argRE);
10330 let arg = argMatch && argMatch[1];
10331 isDynamic = false;
10332 if (arg) {
10333 name = name.slice(0, -(arg.length + 1));
10334 if (dynamicArgRE.test(arg)) {
10335 arg = arg.slice(1, -1);
10336 isDynamic = true;
10337 }
10338 }
10339 addDirective(el, name, rawName, value, arg, isDynamic, modifiers, list[i]);
10340 if (name === 'model') {
10341 checkForAliasModel(el, value);
10342 }
10343 }
10344 } else {
10345 // literal attribute
10346 {
10347 const res = parseText(value, delimiters);
10348 if (res) {
10349 warn$2(
10350 `${name}="${value}": ` +
10351 'Interpolation inside attributes has been removed. ' +
10352 'Use v-bind or the colon shorthand instead. For example, ' +
10353 'instead of <div id="{{ val }}">, use <div :id="val">.',
10354 list[i]
10355 );
10356 }
10357 }
10358 addAttr(el, name, JSON.stringify(value), list[i]);
10359 // #6887 firefox doesn't update muted state if set via attribute
10360 // even immediately after element creation
10361 if (!el.component &&
10362 name === 'muted' &&
10363 platformMustUseProp(el.tag, el.attrsMap.type, name)) {
10364 addProp(el, name, 'true', list[i]);
10365 }
10366 }
10367 }
10368}
10369
10370function checkInFor (el) {
10371 let parent = el;
10372 while (parent) {
10373 if (parent.for !== undefined) {
10374 return true
10375 }
10376 parent = parent.parent;
10377 }
10378 return false
10379}
10380
10381function parseModifiers (name) {
10382 const match = name.match(modifierRE);
10383 if (match) {
10384 const ret = {};
10385 match.forEach(m => { ret[m.slice(1)] = true; });
10386 return ret
10387 }
10388}
10389
10390function makeAttrsMap (attrs) {
10391 const map = {};
10392 for (let i = 0, l = attrs.length; i < l; i++) {
10393 if (
10394 map[attrs[i].name] && !isIE && !isEdge
10395 ) {
10396 warn$2('duplicate attribute: ' + attrs[i].name, attrs[i]);
10397 }
10398 map[attrs[i].name] = attrs[i].value;
10399 }
10400 return map
10401}
10402
10403// for script (e.g. type="x/template") or style, do not decode content
10404function isTextTag (el) {
10405 return el.tag === 'script' || el.tag === 'style'
10406}
10407
10408function isForbiddenTag (el) {
10409 return (
10410 el.tag === 'style' ||
10411 (el.tag === 'script' && (
10412 !el.attrsMap.type ||
10413 el.attrsMap.type === 'text/javascript'
10414 ))
10415 )
10416}
10417
10418const ieNSBug = /^xmlns:NS\d+/;
10419const ieNSPrefix = /^NS\d+:/;
10420
10421/* istanbul ignore next */
10422function guardIESVGBug (attrs) {
10423 const res = [];
10424 for (let i = 0; i < attrs.length; i++) {
10425 const attr = attrs[i];
10426 if (!ieNSBug.test(attr.name)) {
10427 attr.name = attr.name.replace(ieNSPrefix, '');
10428 res.push(attr);
10429 }
10430 }
10431 return res
10432}
10433
10434function checkForAliasModel (el, value) {
10435 let _el = el;
10436 while (_el) {
10437 if (_el.for && _el.alias === value) {
10438 warn$2(
10439 `<${el.tag} v-model="${value}">: ` +
10440 `You are binding v-model directly to a v-for iteration alias. ` +
10441 `This will not be able to modify the v-for source array because ` +
10442 `writing to the alias is like modifying a function local variable. ` +
10443 `Consider using an array of objects and use v-model on an object property instead.`,
10444 el.rawAttrsMap['v-model']
10445 );
10446 }
10447 _el = _el.parent;
10448 }
10449}
10450
10451/* */
10452
10453function preTransformNode (el, options) {
10454 if (el.tag === 'input') {
10455 const map = el.attrsMap;
10456 if (!map['v-model']) {
10457 return
10458 }
10459
10460 let typeBinding;
10461 if (map[':type'] || map['v-bind:type']) {
10462 typeBinding = getBindingAttr(el, 'type');
10463 }
10464 if (!map.type && !typeBinding && map['v-bind']) {
10465 typeBinding = `(${map['v-bind']}).type`;
10466 }
10467
10468 if (typeBinding) {
10469 const ifCondition = getAndRemoveAttr(el, 'v-if', true);
10470 const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``;
10471 const hasElse = getAndRemoveAttr(el, 'v-else', true) != null;
10472 const elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true);
10473 // 1. checkbox
10474 const branch0 = cloneASTElement(el);
10475 // process for on the main node
10476 processFor(branch0);
10477 addRawAttr(branch0, 'type', 'checkbox');
10478 processElement(branch0, options);
10479 branch0.processed = true; // prevent it from double-processed
10480 branch0.if = `(${typeBinding})==='checkbox'` + ifConditionExtra;
10481 addIfCondition(branch0, {
10482 exp: branch0.if,
10483 block: branch0
10484 });
10485 // 2. add radio else-if condition
10486 const branch1 = cloneASTElement(el);
10487 getAndRemoveAttr(branch1, 'v-for', true);
10488 addRawAttr(branch1, 'type', 'radio');
10489 processElement(branch1, options);
10490 addIfCondition(branch0, {
10491 exp: `(${typeBinding})==='radio'` + ifConditionExtra,
10492 block: branch1
10493 });
10494 // 3. other
10495 const branch2 = cloneASTElement(el);
10496 getAndRemoveAttr(branch2, 'v-for', true);
10497 addRawAttr(branch2, ':type', typeBinding);
10498 processElement(branch2, options);
10499 addIfCondition(branch0, {
10500 exp: ifCondition,
10501 block: branch2
10502 });
10503
10504 if (hasElse) {
10505 branch0.else = true;
10506 } else if (elseIfCondition) {
10507 branch0.elseif = elseIfCondition;
10508 }
10509
10510 return branch0
10511 }
10512 }
10513}
10514
10515function cloneASTElement (el) {
10516 return createASTElement(el.tag, el.attrsList.slice(), el.parent)
10517}
10518
10519var model$1 = {
10520 preTransformNode
10521};
10522
10523var modules$1 = [
10524 klass$1,
10525 style$1,
10526 model$1
10527];
10528
10529/* */
10530
10531function text (el, dir) {
10532 if (dir.value) {
10533 addProp(el, 'textContent', `_s(${dir.value})`, dir);
10534 }
10535}
10536
10537/* */
10538
10539function html (el, dir) {
10540 if (dir.value) {
10541 addProp(el, 'innerHTML', `_s(${dir.value})`, dir);
10542 }
10543}
10544
10545var directives$1 = {
10546 model,
10547 text,
10548 html
10549};
10550
10551/* */
10552
10553const baseOptions = {
10554 expectHTML: true,
10555 modules: modules$1,
10556 directives: directives$1,
10557 isPreTag,
10558 isUnaryTag,
10559 mustUseProp,
10560 canBeLeftOpenTag,
10561 isReservedTag,
10562 getTagNamespace,
10563 staticKeys: genStaticKeys(modules$1)
10564};
10565
10566/* */
10567
10568let isStaticKey;
10569let isPlatformReservedTag;
10570
10571const genStaticKeysCached = cached(genStaticKeys$1);
10572
10573/**
10574 * Goal of the optimizer: walk the generated template AST tree
10575 * and detect sub-trees that are purely static, i.e. parts of
10576 * the DOM that never needs to change.
10577 *
10578 * Once we detect these sub-trees, we can:
10579 *
10580 * 1. Hoist them into constants, so that we no longer need to
10581 * create fresh nodes for them on each re-render;
10582 * 2. Completely skip them in the patching process.
10583 */
10584function optimize (root, options) {
10585 if (!root) return
10586 isStaticKey = genStaticKeysCached(options.staticKeys || '');
10587 isPlatformReservedTag = options.isReservedTag || no;
10588 // first pass: mark all non-static nodes.
10589 markStatic$1(root);
10590 // second pass: mark static roots.
10591 markStaticRoots(root, false);
10592}
10593
10594function genStaticKeys$1 (keys) {
10595 return makeMap(
10596 'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +
10597 (keys ? ',' + keys : '')
10598 )
10599}
10600
10601function markStatic$1 (node) {
10602 node.static = isStatic(node);
10603 if (node.type === 1) {
10604 // do not make component slot content static. this avoids
10605 // 1. components not able to mutate slot nodes
10606 // 2. static slot content fails for hot-reloading
10607 if (
10608 !isPlatformReservedTag(node.tag) &&
10609 node.tag !== 'slot' &&
10610 node.attrsMap['inline-template'] == null
10611 ) {
10612 return
10613 }
10614 for (let i = 0, l = node.children.length; i < l; i++) {
10615 const child = node.children[i];
10616 markStatic$1(child);
10617 if (!child.static) {
10618 node.static = false;
10619 }
10620 }
10621 if (node.ifConditions) {
10622 for (let i = 1, l = node.ifConditions.length; i < l; i++) {
10623 const block = node.ifConditions[i].block;
10624 markStatic$1(block);
10625 if (!block.static) {
10626 node.static = false;
10627 }
10628 }
10629 }
10630 }
10631}
10632
10633function markStaticRoots (node, isInFor) {
10634 if (node.type === 1) {
10635 if (node.static || node.once) {
10636 node.staticInFor = isInFor;
10637 }
10638 // For a node to qualify as a static root, it should have children that
10639 // are not just static text. Otherwise the cost of hoisting out will
10640 // outweigh the benefits and it's better off to just always render it fresh.
10641 if (node.static && node.children.length && !(
10642 node.children.length === 1 &&
10643 node.children[0].type === 3
10644 )) {
10645 node.staticRoot = true;
10646 return
10647 } else {
10648 node.staticRoot = false;
10649 }
10650 if (node.children) {
10651 for (let i = 0, l = node.children.length; i < l; i++) {
10652 markStaticRoots(node.children[i], isInFor || !!node.for);
10653 }
10654 }
10655 if (node.ifConditions) {
10656 for (let i = 1, l = node.ifConditions.length; i < l; i++) {
10657 markStaticRoots(node.ifConditions[i].block, isInFor);
10658 }
10659 }
10660 }
10661}
10662
10663function isStatic (node) {
10664 if (node.type === 2) { // expression
10665 return false
10666 }
10667 if (node.type === 3) { // text
10668 return true
10669 }
10670 return !!(node.pre || (
10671 !node.hasBindings && // no dynamic bindings
10672 !node.if && !node.for && // not v-if or v-for or v-else
10673 !isBuiltInTag(node.tag) && // not a built-in
10674 isPlatformReservedTag(node.tag) && // not a component
10675 !isDirectChildOfTemplateFor(node) &&
10676 Object.keys(node).every(isStaticKey)
10677 ))
10678}
10679
10680function isDirectChildOfTemplateFor (node) {
10681 while (node.parent) {
10682 node = node.parent;
10683 if (node.tag !== 'template') {
10684 return false
10685 }
10686 if (node.for) {
10687 return true
10688 }
10689 }
10690 return false
10691}
10692
10693/* */
10694
10695const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;
10696const fnInvokeRE = /\([^)]*?\);*$/;
10697const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
10698
10699// KeyboardEvent.keyCode aliases
10700const keyCodes = {
10701 esc: 27,
10702 tab: 9,
10703 enter: 13,
10704 space: 32,
10705 up: 38,
10706 left: 37,
10707 right: 39,
10708 down: 40,
10709 'delete': [8, 46]
10710};
10711
10712// KeyboardEvent.key aliases
10713const keyNames = {
10714 // #7880: IE11 and Edge use `Esc` for Escape key name.
10715 esc: ['Esc', 'Escape'],
10716 tab: 'Tab',
10717 enter: 'Enter',
10718 // #9112: IE11 uses `Spacebar` for Space key name.
10719 space: [' ', 'Spacebar'],
10720 // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
10721 up: ['Up', 'ArrowUp'],
10722 left: ['Left', 'ArrowLeft'],
10723 right: ['Right', 'ArrowRight'],
10724 down: ['Down', 'ArrowDown'],
10725 // #9112: IE11 uses `Del` for Delete key name.
10726 'delete': ['Backspace', 'Delete', 'Del']
10727};
10728
10729// #4868: modifiers that prevent the execution of the listener
10730// need to explicitly return null so that we can determine whether to remove
10731// the listener for .once
10732const genGuard = condition => `if(${condition})return null;`;
10733
10734const modifierCode = {
10735 stop: '$event.stopPropagation();',
10736 prevent: '$event.preventDefault();',
10737 self: genGuard(`$event.target !== $event.currentTarget`),
10738 ctrl: genGuard(`!$event.ctrlKey`),
10739 shift: genGuard(`!$event.shiftKey`),
10740 alt: genGuard(`!$event.altKey`),
10741 meta: genGuard(`!$event.metaKey`),
10742 left: genGuard(`'button' in $event && $event.button !== 0`),
10743 middle: genGuard(`'button' in $event && $event.button !== 1`),
10744 right: genGuard(`'button' in $event && $event.button !== 2`)
10745};
10746
10747function genHandlers (
10748 events,
10749 isNative
10750) {
10751 const prefix = isNative ? 'nativeOn:' : 'on:';
10752 let staticHandlers = ``;
10753 let dynamicHandlers = ``;
10754 for (const name in events) {
10755 const handlerCode = genHandler(events[name]);
10756 if (events[name] && events[name].dynamic) {
10757 dynamicHandlers += `${name},${handlerCode},`;
10758 } else {
10759 staticHandlers += `"${name}":${handlerCode},`;
10760 }
10761 }
10762 staticHandlers = `{${staticHandlers.slice(0, -1)}}`;
10763 if (dynamicHandlers) {
10764 return prefix + `_d(${staticHandlers},[${dynamicHandlers.slice(0, -1)}])`
10765 } else {
10766 return prefix + staticHandlers
10767 }
10768}
10769
10770function genHandler (handler) {
10771 if (!handler) {
10772 return 'function(){}'
10773 }
10774
10775 if (Array.isArray(handler)) {
10776 return `[${handler.map(handler => genHandler(handler)).join(',')}]`
10777 }
10778
10779 const isMethodPath = simplePathRE.test(handler.value);
10780 const isFunctionExpression = fnExpRE.test(handler.value);
10781 const isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''));
10782
10783 if (!handler.modifiers) {
10784 if (isMethodPath || isFunctionExpression) {
10785 return handler.value
10786 }
10787 return `function($event){${
10788 isFunctionInvocation ? `return ${handler.value}` : handler.value
10789 }}` // inline statement
10790 } else {
10791 let code = '';
10792 let genModifierCode = '';
10793 const keys = [];
10794 for (const key in handler.modifiers) {
10795 if (modifierCode[key]) {
10796 genModifierCode += modifierCode[key];
10797 // left/right
10798 if (keyCodes[key]) {
10799 keys.push(key);
10800 }
10801 } else if (key === 'exact') {
10802 const modifiers = (handler.modifiers);
10803 genModifierCode += genGuard(
10804 ['ctrl', 'shift', 'alt', 'meta']
10805 .filter(keyModifier => !modifiers[keyModifier])
10806 .map(keyModifier => `$event.${keyModifier}Key`)
10807 .join('||')
10808 );
10809 } else {
10810 keys.push(key);
10811 }
10812 }
10813 if (keys.length) {
10814 code += genKeyFilter(keys);
10815 }
10816 // Make sure modifiers like prevent and stop get executed after key filtering
10817 if (genModifierCode) {
10818 code += genModifierCode;
10819 }
10820 const handlerCode = isMethodPath
10821 ? `return ${handler.value}($event)`
10822 : isFunctionExpression
10823 ? `return (${handler.value})($event)`
10824 : isFunctionInvocation
10825 ? `return ${handler.value}`
10826 : handler.value;
10827 return `function($event){${code}${handlerCode}}`
10828 }
10829}
10830
10831function genKeyFilter (keys) {
10832 return (
10833 // make sure the key filters only apply to KeyboardEvents
10834 // #9441: can't use 'keyCode' in $event because Chrome autofill fires fake
10835 // key events that do not have keyCode property...
10836 `if(!$event.type.indexOf('key')&&` +
10837 `${keys.map(genFilterCode).join('&&')})return null;`
10838 )
10839}
10840
10841function genFilterCode (key) {
10842 const keyVal = parseInt(key, 10);
10843 if (keyVal) {
10844 return `$event.keyCode!==${keyVal}`
10845 }
10846 const keyCode = keyCodes[key];
10847 const keyName = keyNames[key];
10848 return (
10849 `_k($event.keyCode,` +
10850 `${JSON.stringify(key)},` +
10851 `${JSON.stringify(keyCode)},` +
10852 `$event.key,` +
10853 `${JSON.stringify(keyName)}` +
10854 `)`
10855 )
10856}
10857
10858/* */
10859
10860function on (el, dir) {
10861 if (dir.modifiers) {
10862 warn(`v-on without argument does not support modifiers.`);
10863 }
10864 el.wrapListeners = (code) => `_g(${code},${dir.value})`;
10865}
10866
10867/* */
10868
10869function bind$1 (el, dir) {
10870 el.wrapData = (code) => {
10871 return `_b(${code},'${el.tag}',${dir.value},${
10872 dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
10873 }${
10874 dir.modifiers && dir.modifiers.sync ? ',true' : ''
10875 })`
10876 };
10877}
10878
10879/* */
10880
10881var baseDirectives = {
10882 on,
10883 bind: bind$1,
10884 cloak: noop
10885};
10886
10887/* */
10888
10889
10890
10891
10892
10893class CodegenState {
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904 constructor (options) {
10905 this.options = options;
10906 this.warn = options.warn || baseWarn;
10907 this.transforms = pluckModuleFunction(options.modules, 'transformCode');
10908 this.dataGenFns = pluckModuleFunction(options.modules, 'genData');
10909 this.directives = extend(extend({}, baseDirectives), options.directives);
10910 const isReservedTag = options.isReservedTag || no;
10911 this.maybeComponent = (el) => !!el.component || !isReservedTag(el.tag);
10912 this.onceId = 0;
10913 this.staticRenderFns = [];
10914 this.pre = false;
10915 }
10916}
10917
10918
10919
10920function generate (
10921 ast,
10922 options
10923) {
10924 const state = new CodegenState(options);
10925 const code = ast ? genElement(ast, state) : '_c("div")';
10926 return {
10927 render: `with(this){return ${code}}`,
10928 staticRenderFns: state.staticRenderFns
10929 }
10930}
10931
10932function genElement (el, state) {
10933 if (el.parent) {
10934 el.pre = el.pre || el.parent.pre;
10935 }
10936
10937 if (el.staticRoot && !el.staticProcessed) {
10938 return genStatic(el, state)
10939 } else if (el.once && !el.onceProcessed) {
10940 return genOnce(el, state)
10941 } else if (el.for && !el.forProcessed) {
10942 return genFor(el, state)
10943 } else if (el.if && !el.ifProcessed) {
10944 return genIf(el, state)
10945 } else if (el.tag === 'template' && !el.slotTarget && !state.pre) {
10946 return genChildren(el, state) || 'void 0'
10947 } else if (el.tag === 'slot') {
10948 return genSlot(el, state)
10949 } else {
10950 // component or element
10951 let code;
10952 if (el.component) {
10953 code = genComponent(el.component, el, state);
10954 } else {
10955 let data;
10956 if (!el.plain || (el.pre && state.maybeComponent(el))) {
10957 data = genData$2(el, state);
10958 }
10959
10960 const children = el.inlineTemplate ? null : genChildren(el, state, true);
10961 code = `_c('${el.tag}'${
10962 data ? `,${data}` : '' // data
10963 }${
10964 children ? `,${children}` : '' // children
10965 })`;
10966 }
10967 // module transforms
10968 for (let i = 0; i < state.transforms.length; i++) {
10969 code = state.transforms[i](el, code);
10970 }
10971 return code
10972 }
10973}
10974
10975// hoist static sub-trees out
10976function genStatic (el, state) {
10977 el.staticProcessed = true;
10978 // Some elements (templates) need to behave differently inside of a v-pre
10979 // node. All pre nodes are static roots, so we can use this as a location to
10980 // wrap a state change and reset it upon exiting the pre node.
10981 const originalPreState = state.pre;
10982 if (el.pre) {
10983 state.pre = el.pre;
10984 }
10985 state.staticRenderFns.push(`with(this){return ${genElement(el, state)}}`);
10986 state.pre = originalPreState;
10987 return `_m(${
10988 state.staticRenderFns.length - 1
10989 }${
10990 el.staticInFor ? ',true' : ''
10991 })`
10992}
10993
10994// v-once
10995function genOnce (el, state) {
10996 el.onceProcessed = true;
10997 if (el.if && !el.ifProcessed) {
10998 return genIf(el, state)
10999 } else if (el.staticInFor) {
11000 let key = '';
11001 let parent = el.parent;
11002 while (parent) {
11003 if (parent.for) {
11004 key = parent.key;
11005 break
11006 }
11007 parent = parent.parent;
11008 }
11009 if (!key) {
11010 state.warn(
11011 `v-once can only be used inside v-for that is keyed. `,
11012 el.rawAttrsMap['v-once']
11013 );
11014 return genElement(el, state)
11015 }
11016 return `_o(${genElement(el, state)},${state.onceId++},${key})`
11017 } else {
11018 return genStatic(el, state)
11019 }
11020}
11021
11022function genIf (
11023 el,
11024 state,
11025 altGen,
11026 altEmpty
11027) {
11028 el.ifProcessed = true; // avoid recursion
11029 return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
11030}
11031
11032function genIfConditions (
11033 conditions,
11034 state,
11035 altGen,
11036 altEmpty
11037) {
11038 if (!conditions.length) {
11039 return altEmpty || '_e()'
11040 }
11041
11042 const condition = conditions.shift();
11043 if (condition.exp) {
11044 return `(${condition.exp})?${
11045 genTernaryExp(condition.block)
11046 }:${
11047 genIfConditions(conditions, state, altGen, altEmpty)
11048 }`
11049 } else {
11050 return `${genTernaryExp(condition.block)}`
11051 }
11052
11053 // v-if with v-once should generate code like (a)?_m(0):_m(1)
11054 function genTernaryExp (el) {
11055 return altGen
11056 ? altGen(el, state)
11057 : el.once
11058 ? genOnce(el, state)
11059 : genElement(el, state)
11060 }
11061}
11062
11063function genFor (
11064 el,
11065 state,
11066 altGen,
11067 altHelper
11068) {
11069 const exp = el.for;
11070 const alias = el.alias;
11071 const iterator1 = el.iterator1 ? `,${el.iterator1}` : '';
11072 const iterator2 = el.iterator2 ? `,${el.iterator2}` : '';
11073
11074 if (state.maybeComponent(el) &&
11075 el.tag !== 'slot' &&
11076 el.tag !== 'template' &&
11077 !el.key
11078 ) {
11079 state.warn(
11080 `<${el.tag} v-for="${alias} in ${exp}">: component lists rendered with ` +
11081 `v-for should have explicit keys. ` +
11082 `See https://vuejs.org/guide/list.html#key for more info.`,
11083 el.rawAttrsMap['v-for'],
11084 true /* tip */
11085 );
11086 }
11087
11088 el.forProcessed = true; // avoid recursion
11089 return `${altHelper || '_l'}((${exp}),` +
11090 `function(${alias}${iterator1}${iterator2}){` +
11091 `return ${(altGen || genElement)(el, state)}` +
11092 '})'
11093}
11094
11095function genData$2 (el, state) {
11096 let data = '{';
11097
11098 // directives first.
11099 // directives may mutate the el's other properties before they are generated.
11100 const dirs = genDirectives(el, state);
11101 if (dirs) data += dirs + ',';
11102
11103 // key
11104 if (el.key) {
11105 data += `key:${el.key},`;
11106 }
11107 // ref
11108 if (el.ref) {
11109 data += `ref:${el.ref},`;
11110 }
11111 if (el.refInFor) {
11112 data += `refInFor:true,`;
11113 }
11114 // pre
11115 if (el.pre) {
11116 data += `pre:true,`;
11117 }
11118 // record original tag name for components using "is" attribute
11119 if (el.component) {
11120 data += `tag:"${el.tag}",`;
11121 }
11122 // module data generation functions
11123 for (let i = 0; i < state.dataGenFns.length; i++) {
11124 data += state.dataGenFns[i](el);
11125 }
11126 // attributes
11127 if (el.attrs) {
11128 data += `attrs:${genProps(el.attrs)},`;
11129 }
11130 // DOM props
11131 if (el.props) {
11132 data += `domProps:${genProps(el.props)},`;
11133 }
11134 // event handlers
11135 if (el.events) {
11136 data += `${genHandlers(el.events, false)},`;
11137 }
11138 if (el.nativeEvents) {
11139 data += `${genHandlers(el.nativeEvents, true)},`;
11140 }
11141 // slot target
11142 // only for non-scoped slots
11143 if (el.slotTarget && !el.slotScope) {
11144 data += `slot:${el.slotTarget},`;
11145 }
11146 // scoped slots
11147 if (el.scopedSlots) {
11148 data += `${genScopedSlots(el, el.scopedSlots, state)},`;
11149 }
11150 // component v-model
11151 if (el.model) {
11152 data += `model:{value:${
11153 el.model.value
11154 },callback:${
11155 el.model.callback
11156 },expression:${
11157 el.model.expression
11158 }},`;
11159 }
11160 // inline-template
11161 if (el.inlineTemplate) {
11162 const inlineTemplate = genInlineTemplate(el, state);
11163 if (inlineTemplate) {
11164 data += `${inlineTemplate},`;
11165 }
11166 }
11167 data = data.replace(/,$/, '') + '}';
11168 // v-bind dynamic argument wrap
11169 // v-bind with dynamic arguments must be applied using the same v-bind object
11170 // merge helper so that class/style/mustUseProp attrs are handled correctly.
11171 if (el.dynamicAttrs) {
11172 data = `_b(${data},"${el.tag}",${genProps(el.dynamicAttrs)})`;
11173 }
11174 // v-bind data wrap
11175 if (el.wrapData) {
11176 data = el.wrapData(data);
11177 }
11178 // v-on data wrap
11179 if (el.wrapListeners) {
11180 data = el.wrapListeners(data);
11181 }
11182 return data
11183}
11184
11185function genDirectives (el, state) {
11186 const dirs = el.directives;
11187 if (!dirs) return
11188 let res = 'directives:[';
11189 let hasRuntime = false;
11190 let i, l, dir, needRuntime;
11191 for (i = 0, l = dirs.length; i < l; i++) {
11192 dir = dirs[i];
11193 needRuntime = true;
11194 const gen = state.directives[dir.name];
11195 if (gen) {
11196 // compile-time directive that manipulates AST.
11197 // returns true if it also needs a runtime counterpart.
11198 needRuntime = !!gen(el, dir, state.warn);
11199 }
11200 if (needRuntime) {
11201 hasRuntime = true;
11202 res += `{name:"${dir.name}",rawName:"${dir.rawName}"${
11203 dir.value ? `,value:(${dir.value}),expression:${JSON.stringify(dir.value)}` : ''
11204 }${
11205 dir.arg ? `,arg:${dir.isDynamicArg ? dir.arg : `"${dir.arg}"`}` : ''
11206 }${
11207 dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
11208 }},`;
11209 }
11210 }
11211 if (hasRuntime) {
11212 return res.slice(0, -1) + ']'
11213 }
11214}
11215
11216function genInlineTemplate (el, state) {
11217 const ast = el.children[0];
11218 if (el.children.length !== 1 || ast.type !== 1) {
11219 state.warn(
11220 'Inline-template components must have exactly one child element.',
11221 { start: el.start }
11222 );
11223 }
11224 if (ast && ast.type === 1) {
11225 const inlineRenderFns = generate(ast, state.options);
11226 return `inlineTemplate:{render:function(){${
11227 inlineRenderFns.render
11228 }},staticRenderFns:[${
11229 inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',')
11230 }]}`
11231 }
11232}
11233
11234function genScopedSlots (
11235 el,
11236 slots,
11237 state
11238) {
11239 // by default scoped slots are considered "stable", this allows child
11240 // components with only scoped slots to skip forced updates from parent.
11241 // but in some cases we have to bail-out of this optimization
11242 // for example if the slot contains dynamic names, has v-if or v-for on them...
11243 let needsForceUpdate = Object.keys(slots).some(key => {
11244 const slot = slots[key];
11245 return (
11246 slot.slotTargetDynamic ||
11247 slot.if ||
11248 slot.for ||
11249 containsSlotChild(slot) // is passing down slot from parent which may be dynamic
11250 )
11251 });
11252
11253 // #9534: if a component with scoped slots is inside a conditional branch,
11254 // it's possible for the same component to be reused but with different
11255 // compiled slot content. To avoid that, we generate a unique key based on
11256 // the generated code of all the slot contents.
11257 let needsKey = !!el.if;
11258
11259 // OR when it is inside another scoped slot or v-for (the reactivity may be
11260 // disconnected due to the intermediate scope variable)
11261 // #9438, #9506
11262 // TODO: this can be further optimized by properly analyzing in-scope bindings
11263 // and skip force updating ones that do not actually use scope variables.
11264 if (!needsForceUpdate) {
11265 let parent = el.parent;
11266 while (parent) {
11267 if (
11268 (parent.slotScope && parent.slotScope !== emptySlotScopeToken) ||
11269 parent.for
11270 ) {
11271 needsForceUpdate = true;
11272 break
11273 }
11274 if (parent.if) {
11275 needsKey = true;
11276 }
11277 parent = parent.parent;
11278 }
11279 }
11280
11281 const generatedSlots = Object.keys(slots)
11282 .map(key => genScopedSlot(slots[key], state))
11283 .join(',');
11284
11285 return `scopedSlots:_u([${generatedSlots}]${
11286 needsForceUpdate ? `,null,true` : ``
11287 }${
11288 !needsForceUpdate && needsKey ? `,null,false,${hash(generatedSlots)}` : ``
11289 })`
11290}
11291
11292function hash(str) {
11293 let hash = 5381;
11294 let i = str.length;
11295 while(i) {
11296 hash = (hash * 33) ^ str.charCodeAt(--i);
11297 }
11298 return hash >>> 0
11299}
11300
11301function containsSlotChild (el) {
11302 if (el.type === 1) {
11303 if (el.tag === 'slot') {
11304 return true
11305 }
11306 return el.children.some(containsSlotChild)
11307 }
11308 return false
11309}
11310
11311function genScopedSlot (
11312 el,
11313 state
11314) {
11315 const isLegacySyntax = el.attrsMap['slot-scope'];
11316 if (el.if && !el.ifProcessed && !isLegacySyntax) {
11317 return genIf(el, state, genScopedSlot, `null`)
11318 }
11319 if (el.for && !el.forProcessed) {
11320 return genFor(el, state, genScopedSlot)
11321 }
11322 const slotScope = el.slotScope === emptySlotScopeToken
11323 ? ``
11324 : String(el.slotScope);
11325 const fn = `function(${slotScope}){` +
11326 `return ${el.tag === 'template'
11327 ? el.if && isLegacySyntax
11328 ? `(${el.if})?${genChildren(el, state) || 'undefined'}:undefined`
11329 : genChildren(el, state) || 'undefined'
11330 : genElement(el, state)
11331 }}`;
11332 // reverse proxy v-slot without scope on this.$slots
11333 const reverseProxy = slotScope ? `` : `,proxy:true`;
11334 return `{key:${el.slotTarget || `"default"`},fn:${fn}${reverseProxy}}`
11335}
11336
11337function genChildren (
11338 el,
11339 state,
11340 checkSkip,
11341 altGenElement,
11342 altGenNode
11343) {
11344 const children = el.children;
11345 if (children.length) {
11346 const el = children[0];
11347 // optimize single v-for
11348 if (children.length === 1 &&
11349 el.for &&
11350 el.tag !== 'template' &&
11351 el.tag !== 'slot'
11352 ) {
11353 const normalizationType = checkSkip
11354 ? state.maybeComponent(el) ? `,1` : `,0`
11355 : ``;
11356 return `${(altGenElement || genElement)(el, state)}${normalizationType}`
11357 }
11358 const normalizationType = checkSkip
11359 ? getNormalizationType(children, state.maybeComponent)
11360 : 0;
11361 const gen = altGenNode || genNode;
11362 return `[${children.map(c => gen(c, state)).join(',')}]${
11363 normalizationType ? `,${normalizationType}` : ''
11364 }`
11365 }
11366}
11367
11368// determine the normalization needed for the children array.
11369// 0: no normalization needed
11370// 1: simple normalization needed (possible 1-level deep nested array)
11371// 2: full normalization needed
11372function getNormalizationType (
11373 children,
11374 maybeComponent
11375) {
11376 let res = 0;
11377 for (let i = 0; i < children.length; i++) {
11378 const el = children[i];
11379 if (el.type !== 1) {
11380 continue
11381 }
11382 if (needsNormalization(el) ||
11383 (el.ifConditions && el.ifConditions.some(c => needsNormalization(c.block)))) {
11384 res = 2;
11385 break
11386 }
11387 if (maybeComponent(el) ||
11388 (el.ifConditions && el.ifConditions.some(c => maybeComponent(c.block)))) {
11389 res = 1;
11390 }
11391 }
11392 return res
11393}
11394
11395function needsNormalization (el) {
11396 return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'
11397}
11398
11399function genNode (node, state) {
11400 if (node.type === 1) {
11401 return genElement(node, state)
11402 } else if (node.type === 3 && node.isComment) {
11403 return genComment(node)
11404 } else {
11405 return genText(node)
11406 }
11407}
11408
11409function genText (text) {
11410 return `_v(${text.type === 2
11411 ? text.expression // no need for () because already wrapped in _s()
11412 : transformSpecialNewlines(JSON.stringify(text.text))
11413 })`
11414}
11415
11416function genComment (comment) {
11417 return `_e(${JSON.stringify(comment.text)})`
11418}
11419
11420function genSlot (el, state) {
11421 const slotName = el.slotName || '"default"';
11422 const children = genChildren(el, state);
11423 let res = `_t(${slotName}${children ? `,${children}` : ''}`;
11424 const attrs = el.attrs || el.dynamicAttrs
11425 ? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
11426 // slot props are camelized
11427 name: camelize(attr.name),
11428 value: attr.value,
11429 dynamic: attr.dynamic
11430 })))
11431 : null;
11432 const bind$$1 = el.attrsMap['v-bind'];
11433 if ((attrs || bind$$1) && !children) {
11434 res += `,null`;
11435 }
11436 if (attrs) {
11437 res += `,${attrs}`;
11438 }
11439 if (bind$$1) {
11440 res += `${attrs ? '' : ',null'},${bind$$1}`;
11441 }
11442 return res + ')'
11443}
11444
11445// componentName is el.component, take it as argument to shun flow's pessimistic refinement
11446function genComponent (
11447 componentName,
11448 el,
11449 state
11450) {
11451 const children = el.inlineTemplate ? null : genChildren(el, state, true);
11452 return `_c(${componentName},${genData$2(el, state)}${
11453 children ? `,${children}` : ''
11454 })`
11455}
11456
11457function genProps (props) {
11458 let staticProps = ``;
11459 let dynamicProps = ``;
11460 for (let i = 0; i < props.length; i++) {
11461 const prop = props[i];
11462 const value = transformSpecialNewlines(prop.value);
11463 if (prop.dynamic) {
11464 dynamicProps += `${prop.name},${value},`;
11465 } else {
11466 staticProps += `"${prop.name}":${value},`;
11467 }
11468 }
11469 staticProps = `{${staticProps.slice(0, -1)}}`;
11470 if (dynamicProps) {
11471 return `_d(${staticProps},[${dynamicProps.slice(0, -1)}])`
11472 } else {
11473 return staticProps
11474 }
11475}
11476
11477// #3895, #4268
11478function transformSpecialNewlines (text) {
11479 return text
11480 .replace(/\u2028/g, '\\u2028')
11481 .replace(/\u2029/g, '\\u2029')
11482}
11483
11484/* */
11485
11486
11487
11488// these keywords should not appear inside expressions, but operators like
11489// typeof, instanceof and in are allowed
11490const prohibitedKeywordRE = new RegExp('\\b' + (
11491 'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
11492 'super,throw,while,yield,delete,export,import,return,switch,default,' +
11493 'extends,finally,continue,debugger,function,arguments'
11494).split(',').join('\\b|\\b') + '\\b');
11495
11496// these unary operators should not be used as property/method names
11497const unaryOperatorsRE = new RegExp('\\b' + (
11498 'delete,typeof,void'
11499).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)');
11500
11501// strip strings in expressions
11502const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
11503
11504// detect problematic expressions in a template
11505function detectErrors (ast, warn) {
11506 if (ast) {
11507 checkNode(ast, warn);
11508 }
11509}
11510
11511function checkNode (node, warn) {
11512 if (node.type === 1) {
11513 for (const name in node.attrsMap) {
11514 if (dirRE.test(name)) {
11515 const value = node.attrsMap[name];
11516 if (value) {
11517 const range = node.rawAttrsMap[name];
11518 if (name === 'v-for') {
11519 checkFor(node, `v-for="${value}"`, warn, range);
11520 } else if (onRE.test(name)) {
11521 checkEvent(value, `${name}="${value}"`, warn, range);
11522 } else {
11523 checkExpression(value, `${name}="${value}"`, warn, range);
11524 }
11525 }
11526 }
11527 }
11528 if (node.children) {
11529 for (let i = 0; i < node.children.length; i++) {
11530 checkNode(node.children[i], warn);
11531 }
11532 }
11533 } else if (node.type === 2) {
11534 checkExpression(node.expression, node.text, warn, node);
11535 }
11536}
11537
11538function checkEvent (exp, text, warn, range) {
11539 const stipped = exp.replace(stripStringRE, '');
11540 const keywordMatch = stipped.match(unaryOperatorsRE);
11541 if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {
11542 warn(
11543 `avoid using JavaScript unary operator as property name: ` +
11544 `"${keywordMatch[0]}" in expression ${text.trim()}`,
11545 range
11546 );
11547 }
11548 checkExpression(exp, text, warn, range);
11549}
11550
11551function checkFor (node, text, warn, range) {
11552 checkExpression(node.for || '', text, warn, range);
11553 checkIdentifier(node.alias, 'v-for alias', text, warn, range);
11554 checkIdentifier(node.iterator1, 'v-for iterator', text, warn, range);
11555 checkIdentifier(node.iterator2, 'v-for iterator', text, warn, range);
11556}
11557
11558function checkIdentifier (
11559 ident,
11560 type,
11561 text,
11562 warn,
11563 range
11564) {
11565 if (typeof ident === 'string') {
11566 try {
11567 new Function(`var ${ident}=_`);
11568 } catch (e) {
11569 warn(`invalid ${type} "${ident}" in expression: ${text.trim()}`, range);
11570 }
11571 }
11572}
11573
11574function checkExpression (exp, text, warn, range) {
11575 try {
11576 new Function(`return ${exp}`);
11577 } catch (e) {
11578 const keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);
11579 if (keywordMatch) {
11580 warn(
11581 `avoid using JavaScript keyword as property name: ` +
11582 `"${keywordMatch[0]}"\n Raw expression: ${text.trim()}`,
11583 range
11584 );
11585 } else {
11586 warn(
11587 `invalid expression: ${e.message} in\n\n` +
11588 ` ${exp}\n\n` +
11589 ` Raw expression: ${text.trim()}\n`,
11590 range
11591 );
11592 }
11593 }
11594}
11595
11596/* */
11597
11598const range = 2;
11599
11600function generateCodeFrame (
11601 source,
11602 start = 0,
11603 end = source.length
11604) {
11605 const lines = source.split(/\r?\n/);
11606 let count = 0;
11607 const res = [];
11608 for (let i = 0; i < lines.length; i++) {
11609 count += lines[i].length + 1;
11610 if (count >= start) {
11611 for (let j = i - range; j <= i + range || end > count; j++) {
11612 if (j < 0 || j >= lines.length) continue
11613 res.push(`${j + 1}${repeat(` `, 3 - String(j + 1).length)}| ${lines[j]}`);
11614 const lineLength = lines[j].length;
11615 if (j === i) {
11616 // push underline
11617 const pad = start - (count - lineLength) + 1;
11618 const length = end > count ? lineLength - pad : end - start;
11619 res.push(` | ` + repeat(` `, pad) + repeat(`^`, length));
11620 } else if (j > i) {
11621 if (end > count) {
11622 const length = Math.min(end - count, lineLength);
11623 res.push(` | ` + repeat(`^`, length));
11624 }
11625 count += lineLength + 1;
11626 }
11627 }
11628 break
11629 }
11630 }
11631 return res.join('\n')
11632}
11633
11634function repeat (str, n) {
11635 let result = '';
11636 if (n > 0) {
11637 while (true) { // eslint-disable-line
11638 if (n & 1) result += str;
11639 n >>>= 1;
11640 if (n <= 0) break
11641 str += str;
11642 }
11643 }
11644 return result
11645}
11646
11647/* */
11648
11649
11650
11651function createFunction (code, errors) {
11652 try {
11653 return new Function(code)
11654 } catch (err) {
11655 errors.push({ err, code });
11656 return noop
11657 }
11658}
11659
11660function createCompileToFunctionFn (compile) {
11661 const cache = Object.create(null);
11662
11663 return function compileToFunctions (
11664 template,
11665 options,
11666 vm
11667 ) {
11668 options = extend({}, options);
11669 const warn$$1 = options.warn || warn;
11670 delete options.warn;
11671
11672 /* istanbul ignore if */
11673 {
11674 // detect possible CSP restriction
11675 try {
11676 new Function('return 1');
11677 } catch (e) {
11678 if (e.toString().match(/unsafe-eval|CSP/)) {
11679 warn$$1(
11680 'It seems you are using the standalone build of Vue.js in an ' +
11681 'environment with Content Security Policy that prohibits unsafe-eval. ' +
11682 'The template compiler cannot work in this environment. Consider ' +
11683 'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
11684 'templates into render functions.'
11685 );
11686 }
11687 }
11688 }
11689
11690 // check cache
11691 const key = options.delimiters
11692 ? String(options.delimiters) + template
11693 : template;
11694 if (cache[key]) {
11695 return cache[key]
11696 }
11697
11698 // compile
11699 const compiled = compile(template, options);
11700
11701 // check compilation errors/tips
11702 {
11703 if (compiled.errors && compiled.errors.length) {
11704 if (options.outputSourceRange) {
11705 compiled.errors.forEach(e => {
11706 warn$$1(
11707 `Error compiling template:\n\n${e.msg}\n\n` +
11708 generateCodeFrame(template, e.start, e.end),
11709 vm
11710 );
11711 });
11712 } else {
11713 warn$$1(
11714 `Error compiling template:\n\n${template}\n\n` +
11715 compiled.errors.map(e => `- ${e}`).join('\n') + '\n',
11716 vm
11717 );
11718 }
11719 }
11720 if (compiled.tips && compiled.tips.length) {
11721 if (options.outputSourceRange) {
11722 compiled.tips.forEach(e => tip(e.msg, vm));
11723 } else {
11724 compiled.tips.forEach(msg => tip(msg, vm));
11725 }
11726 }
11727 }
11728
11729 // turn code into functions
11730 const res = {};
11731 const fnGenErrors = [];
11732 res.render = createFunction(compiled.render, fnGenErrors);
11733 res.staticRenderFns = compiled.staticRenderFns.map(code => {
11734 return createFunction(code, fnGenErrors)
11735 });
11736
11737 // check function generation errors.
11738 // this should only happen if there is a bug in the compiler itself.
11739 // mostly for codegen development use
11740 /* istanbul ignore if */
11741 {
11742 if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {
11743 warn$$1(
11744 `Failed to generate render function:\n\n` +
11745 fnGenErrors.map(({ err, code }) => `${err.toString()} in\n\n${code}\n`).join('\n'),
11746 vm
11747 );
11748 }
11749 }
11750
11751 return (cache[key] = res)
11752 }
11753}
11754
11755/* */
11756
11757function createCompilerCreator (baseCompile) {
11758 return function createCompiler (baseOptions) {
11759 function compile (
11760 template,
11761 options
11762 ) {
11763 const finalOptions = Object.create(baseOptions);
11764 const errors = [];
11765 const tips = [];
11766
11767 let warn = (msg, range, tip) => {
11768 (tip ? tips : errors).push(msg);
11769 };
11770
11771 if (options) {
11772 if (options.outputSourceRange) {
11773 // $flow-disable-line
11774 const leadingSpaceLength = template.match(/^\s*/)[0].length;
11775
11776 warn = (msg, range, tip) => {
11777 const data = { msg };
11778 if (range) {
11779 if (range.start != null) {
11780 data.start = range.start + leadingSpaceLength;
11781 }
11782 if (range.end != null) {
11783 data.end = range.end + leadingSpaceLength;
11784 }
11785 }
11786 (tip ? tips : errors).push(data);
11787 };
11788 }
11789 // merge custom modules
11790 if (options.modules) {
11791 finalOptions.modules =
11792 (baseOptions.modules || []).concat(options.modules);
11793 }
11794 // merge custom directives
11795 if (options.directives) {
11796 finalOptions.directives = extend(
11797 Object.create(baseOptions.directives || null),
11798 options.directives
11799 );
11800 }
11801 // copy other options
11802 for (const key in options) {
11803 if (key !== 'modules' && key !== 'directives') {
11804 finalOptions[key] = options[key];
11805 }
11806 }
11807 }
11808
11809 finalOptions.warn = warn;
11810
11811 const compiled = baseCompile(template.trim(), finalOptions);
11812 {
11813 detectErrors(compiled.ast, warn);
11814 }
11815 compiled.errors = errors;
11816 compiled.tips = tips;
11817 return compiled
11818 }
11819
11820 return {
11821 compile,
11822 compileToFunctions: createCompileToFunctionFn(compile)
11823 }
11824 }
11825}
11826
11827/* */
11828
11829// `createCompilerCreator` allows creating compilers that use alternative
11830// parser/optimizer/codegen, e.g the SSR optimizing compiler.
11831// Here we just export a default compiler using the default parts.
11832const createCompiler = createCompilerCreator(function baseCompile (
11833 template,
11834 options
11835) {
11836 const ast = parse(template.trim(), options);
11837 if (options.optimize !== false) {
11838 optimize(ast, options);
11839 }
11840 const code = generate(ast, options);
11841 return {
11842 ast,
11843 render: code.render,
11844 staticRenderFns: code.staticRenderFns
11845 }
11846});
11847
11848/* */
11849
11850const { compile, compileToFunctions } = createCompiler(baseOptions);
11851
11852/* */
11853
11854// check whether current browser encodes a char inside attribute values
11855let div;
11856function getShouldDecode (href) {
11857 div = div || document.createElement('div');
11858 div.innerHTML = href ? `<a href="\n"/>` : `<div a="\n"/>`;
11859 return div.innerHTML.indexOf('&#10;') > 0
11860}
11861
11862// #3663: IE encodes newlines inside attribute values while other browsers don't
11863const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false;
11864// #6828: chrome encodes content in a[href]
11865const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false;
11866
11867/* */
11868
11869const idToTemplate = cached(id => {
11870 const el = query(id);
11871 return el && el.innerHTML
11872});
11873
11874const mount = Vue.prototype.$mount;
11875Vue.prototype.$mount = function (
11876 el,
11877 hydrating
11878) {
11879 el = el && query(el);
11880
11881 /* istanbul ignore if */
11882 if (el === document.body || el === document.documentElement) {
11883 warn(
11884 `Do not mount Vue to <html> or <body> - mount to normal elements instead.`
11885 );
11886 return this
11887 }
11888
11889 const options = this.$options;
11890 // resolve template/el and convert to render function
11891 if (!options.render) {
11892 let template = options.template;
11893 if (template) {
11894 if (typeof template === 'string') {
11895 if (template.charAt(0) === '#') {
11896 template = idToTemplate(template);
11897 /* istanbul ignore if */
11898 if (!template) {
11899 warn(
11900 `Template element not found or is empty: ${options.template}`,
11901 this
11902 );
11903 }
11904 }
11905 } else if (template.nodeType) {
11906 template = template.innerHTML;
11907 } else {
11908 {
11909 warn('invalid template option:' + template, this);
11910 }
11911 return this
11912 }
11913 } else if (el) {
11914 template = getOuterHTML(el);
11915 }
11916 if (template) {
11917 /* istanbul ignore if */
11918 if (config.performance && mark) {
11919 mark('compile');
11920 }
11921
11922 const { render, staticRenderFns } = compileToFunctions(template, {
11923 outputSourceRange: "development" !== 'production',
11924 shouldDecodeNewlines,
11925 shouldDecodeNewlinesForHref,
11926 delimiters: options.delimiters,
11927 comments: options.comments
11928 }, this);
11929 options.render = render;
11930 options.staticRenderFns = staticRenderFns;
11931
11932 /* istanbul ignore if */
11933 if (config.performance && mark) {
11934 mark('compile end');
11935 measure(`vue ${this._name} compile`, 'compile', 'compile end');
11936 }
11937 }
11938 }
11939 return mount.call(this, el, hydrating)
11940};
11941
11942/**
11943 * Get outerHTML of elements, taking care
11944 * of SVG elements in IE as well.
11945 */
11946function getOuterHTML (el) {
11947 if (el.outerHTML) {
11948 return el.outerHTML
11949 } else {
11950 const container = document.createElement('div');
11951 container.appendChild(el.cloneNode(true));
11952 return container.innerHTML
11953 }
11954}
11955
11956Vue.compile = compileToFunctions;
11957
11958export default Vue;