or
+ *
+ * - dynamic:
+ *
+ */
+
+ bind: function bind() {
+ if (!this.el.__vue__) {
+ // keep-alive cache
+ this.keepAlive = this.params.keepAlive;
+ if (this.keepAlive) {
+ this.cache = {};
+ }
+ // check inline-template
+ if (this.params.inlineTemplate) {
+ // extract inline template as a DocumentFragment
+ this.inlineTemplate = extractContent(this.el, true);
+ }
+ // component resolution related state
+ this.pendingComponentCb = this.Component = null;
+ // transition related state
+ this.pendingRemovals = 0;
+ this.pendingRemovalCb = null;
+ // create a ref anchor
+ this.anchor = createAnchor('v-component');
+ replace(this.el, this.anchor);
+ // remove is attribute.
+ // this is removed during compilation, but because compilation is
+ // cached, when the component is used elsewhere this attribute
+ // will remain at link time.
+ this.el.removeAttribute('is');
+ this.el.removeAttribute(':is');
+ // remove ref, same as above
+ if (this.descriptor.ref) {
+ this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref));
+ }
+ // if static, build right now.
+ if (this.literal) {
+ this.setComponent(this.expression);
+ }
+ } else {
+ ("production") !== 'production' && warn('cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el);
+ }
+ },
+
+ /**
+ * Public update, called by the watcher in the dynamic
+ * literal scenario, e.g.
+ */
+
+ update: function update(value) {
+ if (!this.literal) {
+ this.setComponent(value);
+ }
+ },
+
+ /**
+ * Switch dynamic components. May resolve the component
+ * asynchronously, and perform transition based on
+ * specified transition mode. Accepts a few additional
+ * arguments specifically for vue-router.
+ *
+ * The callback is called when the full transition is
+ * finished.
+ *
+ * @param {String} value
+ * @param {Function} [cb]
+ */
+
+ setComponent: function setComponent(value, cb) {
+ this.invalidatePending();
+ if (!value) {
+ // just remove current
+ this.unbuild(true);
+ this.remove(this.childVM, cb);
+ this.childVM = null;
+ } else {
+ var self = this;
+ this.resolveComponent(value, function () {
+ self.mountComponent(cb);
+ });
+ }
+ },
+
+ /**
+ * Resolve the component constructor to use when creating
+ * the child vm.
+ *
+ * @param {String|Function} value
+ * @param {Function} cb
+ */
+
+ resolveComponent: function resolveComponent(value, cb) {
+ var self = this;
+ this.pendingComponentCb = cancellable(function (Component) {
+ self.ComponentName = Component.options.name || (typeof value === 'string' ? value : null);
+ self.Component = Component;
+ cb();
+ });
+ this.vm._resolveComponent(value, this.pendingComponentCb);
+ },
+
+ /**
+ * Create a new instance using the current constructor and
+ * replace the existing instance. This method doesn't care
+ * whether the new component and the old one are actually
+ * the same.
+ *
+ * @param {Function} [cb]
+ */
+
+ mountComponent: function mountComponent(cb) {
+ // actual mount
+ this.unbuild(true);
+ var self = this;
+ var activateHooks = this.Component.options.activate;
+ var cached = this.getCached();
+ var newComponent = this.build();
+ if (activateHooks && !cached) {
+ this.waitingFor = newComponent;
+ callActivateHooks(activateHooks, newComponent, function () {
+ if (self.waitingFor !== newComponent) {
+ return;
+ }
+ self.waitingFor = null;
+ self.transition(newComponent, cb);
+ });
+ } else {
+ // update ref for kept-alive component
+ if (cached) {
+ newComponent._updateRef();
+ }
+ this.transition(newComponent, cb);
+ }
+ },
+
+ /**
+ * When the component changes or unbinds before an async
+ * constructor is resolved, we need to invalidate its
+ * pending callback.
+ */
+
+ invalidatePending: function invalidatePending() {
+ if (this.pendingComponentCb) {
+ this.pendingComponentCb.cancel();
+ this.pendingComponentCb = null;
+ }
+ },
+
+ /**
+ * Instantiate/insert a new child vm.
+ * If keep alive and has cached instance, insert that
+ * instance; otherwise build a new one and cache it.
+ *
+ * @param {Object} [extraOptions]
+ * @return {Vue} - the created instance
+ */
+
+ build: function build(extraOptions) {
+ var cached = this.getCached();
+ if (cached) {
+ return cached;
+ }
+ if (this.Component) {
+ // default options
+ var options = {
+ name: this.ComponentName,
+ el: cloneNode(this.el),
+ template: this.inlineTemplate,
+ // make sure to add the child with correct parent
+ // if this is a transcluded component, its parent
+ // should be the transclusion host.
+ parent: this._host || this.vm,
+ // if no inline-template, then the compiled
+ // linker can be cached for better performance.
+ _linkerCachable: !this.inlineTemplate,
+ _ref: this.descriptor.ref,
+ _asComponent: true,
+ _isRouterView: this._isRouterView,
+ // if this is a transcluded component, context
+ // will be the common parent vm of this instance
+ // and its host.
+ _context: this.vm,
+ // if this is inside an inline v-for, the scope
+ // will be the intermediate scope created for this
+ // repeat fragment. this is used for linking props
+ // and container directives.
+ _scope: this._scope,
+ // pass in the owner fragment of this component.
+ // this is necessary so that the fragment can keep
+ // track of its contained components in order to
+ // call attach/detach hooks for them.
+ _frag: this._frag
+ };
+ // extra options
+ // in 1.0.0 this is used by vue-router only
+ /* istanbul ignore if */
+ if (extraOptions) {
+ extend(options, extraOptions);
+ }
+ var child = new this.Component(options);
+ if (this.keepAlive) {
+ this.cache[this.Component.cid] = child;
+ }
+ /* istanbul ignore if */
+ if (false) {
+ warn('Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template, child);
+ }
+ return child;
+ }
+ },
+
+ /**
+ * Try to get a cached instance of the current component.
+ *
+ * @return {Vue|undefined}
+ */
+
+ getCached: function getCached() {
+ return this.keepAlive && this.cache[this.Component.cid];
+ },
+
+ /**
+ * Teardown the current child, but defers cleanup so
+ * that we can separate the destroy and removal steps.
+ *
+ * @param {Boolean} defer
+ */
+
+ unbuild: function unbuild(defer) {
+ if (this.waitingFor) {
+ if (!this.keepAlive) {
+ this.waitingFor.$destroy();
+ }
+ this.waitingFor = null;
+ }
+ var child = this.childVM;
+ if (!child || this.keepAlive) {
+ if (child) {
+ // remove ref
+ child._inactive = true;
+ child._updateRef(true);
+ }
+ return;
+ }
+ // the sole purpose of `deferCleanup` is so that we can
+ // "deactivate" the vm right now and perform DOM removal
+ // later.
+ child.$destroy(false, defer);
+ },
+
+ /**
+ * Remove current destroyed child and manually do
+ * the cleanup after removal.
+ *
+ * @param {Function} cb
+ */
+
+ remove: function remove(child, cb) {
+ var keepAlive = this.keepAlive;
+ if (child) {
+ // we may have a component switch when a previous
+ // component is still being transitioned out.
+ // we want to trigger only one lastest insertion cb
+ // when the existing transition finishes. (#1119)
+ this.pendingRemovals++;
+ this.pendingRemovalCb = cb;
+ var self = this;
+ child.$remove(function () {
+ self.pendingRemovals--;
+ if (!keepAlive) child._cleanup();
+ if (!self.pendingRemovals && self.pendingRemovalCb) {
+ self.pendingRemovalCb();
+ self.pendingRemovalCb = null;
+ }
+ });
+ } else if (cb) {
+ cb();
+ }
+ },
+
+ /**
+ * Actually swap the components, depending on the
+ * transition mode. Defaults to simultaneous.
+ *
+ * @param {Vue} target
+ * @param {Function} [cb]
+ */
+
+ transition: function transition(target, cb) {
+ var self = this;
+ var current = this.childVM;
+ // for devtool inspection
+ if (current) current._inactive = true;
+ target._inactive = false;
+ this.childVM = target;
+ switch (self.params.transitionMode) {
+ case 'in-out':
+ target.$before(self.anchor, function () {
+ self.remove(current, cb);
+ });
+ break;
+ case 'out-in':
+ self.remove(current, function () {
+ target.$before(self.anchor, cb);
+ });
+ break;
+ default:
+ self.remove(current);
+ target.$before(self.anchor, cb);
+ }
+ },
+
+ /**
+ * Unbind.
+ */
+
+ unbind: function unbind() {
+ this.invalidatePending();
+ // Do not defer cleanup when unbinding
+ this.unbuild();
+ // destroy all keep-alive cached instances
+ if (this.cache) {
+ for (var key in this.cache) {
+ this.cache[key].$destroy();
+ }
+ this.cache = null;
+ }
+ }
+ };
+
+ /**
+ * Call activate hooks in order (asynchronous)
+ *
+ * @param {Array} hooks
+ * @param {Vue} vm
+ * @param {Function} cb
+ */
+
+ function callActivateHooks(hooks, vm, cb) {
+ var total = hooks.length;
+ var called = 0;
+ hooks[0].call(vm, next);
+ function next() {
+ if (++called >= total) {
+ cb();
+ } else {
+ hooks[called].call(vm, next);
+ }
+ }
+ }
+
+ var propBindingModes = config._propBindingModes;
+ var empty = {};
+
+ // regexes
+ var identRE$1 = /^[$_a-zA-Z]+[\w$]*$/;
+ var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/;
+
+ /**
+ * Compile props on a root element and return
+ * a props link function.
+ *
+ * @param {Element|DocumentFragment} el
+ * @param {Array} propOptions
+ * @param {Vue} vm
+ * @return {Function} propsLinkFn
+ */
+
+ function compileProps(el, propOptions, vm) {
+ var props = [];
+ var names = Object.keys(propOptions);
+ var i = names.length;
+ var options, name, attr, value, path, parsed, prop;
+ while (i--) {
+ name = names[i];
+ options = propOptions[name] || empty;
+
+ if (false) {
+ warn('Do not use $data as prop.', vm);
+ continue;
+ }
+
+ // props could contain dashes, which will be
+ // interpreted as minus calculations by the parser
+ // so we need to camelize the path here
+ path = camelize(name);
+ if (!identRE$1.test(path)) {
+ ("production") !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.', vm);
+ continue;
+ }
+
+ prop = {
+ name: name,
+ path: path,
+ options: options,
+ mode: propBindingModes.ONE_WAY,
+ raw: null
+ };
+
+ attr = hyphenate(name);
+ // first check dynamic version
+ if ((value = getBindAttr(el, attr)) === null) {
+ if ((value = getBindAttr(el, attr + '.sync')) !== null) {
+ prop.mode = propBindingModes.TWO_WAY;
+ } else if ((value = getBindAttr(el, attr + '.once')) !== null) {
+ prop.mode = propBindingModes.ONE_TIME;
+ }
+ }
+ if (value !== null) {
+ // has dynamic binding!
+ prop.raw = value;
+ parsed = parseDirective(value);
+ value = parsed.expression;
+ prop.filters = parsed.filters;
+ // check binding type
+ if (isLiteral(value) && !parsed.filters) {
+ // for expressions containing literal numbers and
+ // booleans, there's no need to setup a prop binding,
+ // so we can optimize them as a one-time set.
+ prop.optimizedLiteral = true;
+ } else {
+ prop.dynamic = true;
+ // check non-settable path for two-way bindings
+ if (false) {
+ prop.mode = propBindingModes.ONE_WAY;
+ warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value, vm);
+ }
+ }
+ prop.parentPath = value;
+
+ // warn required two-way
+ if (false) {
+ warn('Prop "' + name + '" expects a two-way binding type.', vm);
+ }
+ } else if ((value = getAttr(el, attr)) !== null) {
+ // has literal binding!
+ prop.raw = value;
+ } else if (false) {
+ // check possible camelCase prop usage
+ var lowerCaseName = path.toLowerCase();
+ value = /[A-Z\-]/.test(name) && (el.getAttribute(lowerCaseName) || el.getAttribute(':' + lowerCaseName) || el.getAttribute('v-bind:' + lowerCaseName) || el.getAttribute(':' + lowerCaseName + '.once') || el.getAttribute('v-bind:' + lowerCaseName + '.once') || el.getAttribute(':' + lowerCaseName + '.sync') || el.getAttribute('v-bind:' + lowerCaseName + '.sync'));
+ if (value) {
+ warn('Possible usage error for prop `' + lowerCaseName + '` - ' + 'did you mean `' + attr + '`? HTML is case-insensitive, remember to use ' + 'kebab-case for props in templates.', vm);
+ } else if (options.required) {
+ // warn missing required
+ warn('Missing required prop: ' + name, vm);
+ }
+ }
+ // push prop
+ props.push(prop);
+ }
+ return makePropsLinkFn(props);
+ }
+
+ /**
+ * Build a function that applies props to a vm.
+ *
+ * @param {Array} props
+ * @return {Function} propsLinkFn
+ */
+
+ function makePropsLinkFn(props) {
+ return function propsLinkFn(vm, scope) {
+ // store resolved props info
+ vm._props = {};
+ var inlineProps = vm.$options.propsData;
+ var i = props.length;
+ var prop, path, options, value, raw;
+ while (i--) {
+ prop = props[i];
+ raw = prop.raw;
+ path = prop.path;
+ options = prop.options;
+ vm._props[path] = prop;
+ if (inlineProps && hasOwn(inlineProps, path)) {
+ initProp(vm, prop, inlineProps[path]);
+ }if (raw === null) {
+ // initialize absent prop
+ initProp(vm, prop, undefined);
+ } else if (prop.dynamic) {
+ // dynamic prop
+ if (prop.mode === propBindingModes.ONE_TIME) {
+ // one time binding
+ value = (scope || vm._context || vm).$get(prop.parentPath);
+ initProp(vm, prop, value);
+ } else {
+ if (vm._context) {
+ // dynamic binding
+ vm._bindDir({
+ name: 'prop',
+ def: propDef,
+ prop: prop
+ }, null, null, scope); // el, host, scope
+ } else {
+ // root instance
+ initProp(vm, prop, vm.$get(prop.parentPath));
+ }
+ }
+ } else if (prop.optimizedLiteral) {
+ // optimized literal, cast it and just set once
+ var stripped = stripQuotes(raw);
+ value = stripped === raw ? toBoolean(toNumber(raw)) : stripped;
+ initProp(vm, prop, value);
+ } else {
+ // string literal, but we need to cater for
+ // Boolean props with no value, or with same
+ // literal value (e.g. disabled="disabled")
+ // see https://github.com/vuejs/vue-loader/issues/182
+ value = options.type === Boolean && (raw === '' || raw === hyphenate(prop.name)) ? true : raw;
+ initProp(vm, prop, value);
+ }
+ }
+ };
+ }
+
+ /**
+ * Process a prop with a rawValue, applying necessary coersions,
+ * default values & assertions and call the given callback with
+ * processed value.
+ *
+ * @param {Vue} vm
+ * @param {Object} prop
+ * @param {*} rawValue
+ * @param {Function} fn
+ */
+
+ function processPropValue(vm, prop, rawValue, fn) {
+ var isSimple = prop.dynamic && isSimplePath(prop.parentPath);
+ var value = rawValue;
+ if (value === undefined) {
+ value = getPropDefaultValue(vm, prop);
+ }
+ value = coerceProp(prop, value);
+ var coerced = value !== rawValue;
+ if (!assertProp(prop, value, vm)) {
+ value = undefined;
+ }
+ if (isSimple && !coerced) {
+ withoutConversion(function () {
+ fn(value);
+ });
+ } else {
+ fn(value);
+ }
+ }
+
+ /**
+ * Set a prop's initial value on a vm and its data object.
+ *
+ * @param {Vue} vm
+ * @param {Object} prop
+ * @param {*} value
+ */
+
+ function initProp(vm, prop, value) {
+ processPropValue(vm, prop, value, function (value) {
+ defineReactive(vm, prop.path, value);
+ });
+ }
+
+ /**
+ * Update a prop's value on a vm.
+ *
+ * @param {Vue} vm
+ * @param {Object} prop
+ * @param {*} value
+ */
+
+ function updateProp(vm, prop, value) {
+ processPropValue(vm, prop, value, function (value) {
+ vm[prop.path] = value;
+ });
+ }
+
+ /**
+ * Get the default value of a prop.
+ *
+ * @param {Vue} vm
+ * @param {Object} prop
+ * @return {*}
+ */
+
+ function getPropDefaultValue(vm, prop) {
+ // no default, return undefined
+ var options = prop.options;
+ if (!hasOwn(options, 'default')) {
+ // absent boolean value defaults to false
+ return options.type === Boolean ? false : undefined;
+ }
+ var def = options['default'];
+ // warn against non-factory defaults for Object & Array
+ if (isObject(def)) {
+ ("production") !== 'production' && warn('Invalid default value for prop "' + prop.name + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm);
+ }
+ // call factory function for non-Function types
+ return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
+ }
+
+ /**
+ * Assert whether a prop is valid.
+ *
+ * @param {Object} prop
+ * @param {*} value
+ * @param {Vue} vm
+ */
+
+ function assertProp(prop, value, vm) {
+ if (!prop.options.required && ( // non-required
+ prop.raw === null || // abscent
+ value == null) // null or undefined
+ ) {
+ return true;
+ }
+ var options = prop.options;
+ var type = options.type;
+ var valid = !type;
+ var expectedTypes = [];
+ if (type) {
+ if (!isArray(type)) {
+ type = [type];
+ }
+ for (var i = 0; i < type.length && !valid; i++) {
+ var assertedType = assertType(value, type[i]);
+ expectedTypes.push(assertedType.expectedType);
+ valid = assertedType.valid;
+ }
+ }
+ if (!valid) {
+ if (false) {
+ warn('Invalid prop: type check failed for prop "' + prop.name + '".' + ' Expected ' + expectedTypes.map(formatType).join(', ') + ', got ' + formatValue(value) + '.', vm);
+ }
+ return false;
+ }
+ var validator = options.validator;
+ if (validator) {
+ if (!validator(value)) {
+ ("production") !== 'production' && warn('Invalid prop: custom validator check failed for prop "' + prop.name + '".', vm);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Force parsing value with coerce option.
+ *
+ * @param {*} value
+ * @param {Object} options
+ * @return {*}
+ */
+
+ function coerceProp(prop, value) {
+ var coerce = prop.options.coerce;
+ if (!coerce) {
+ return value;
+ }
+ // coerce is a function
+ return coerce(value);
+ }
+
+ /**
+ * Assert the type of a value
+ *
+ * @param {*} value
+ * @param {Function} type
+ * @return {Object}
+ */
+
+ function assertType(value, type) {
+ var valid;
+ var expectedType;
+ if (type === String) {
+ expectedType = 'string';
+ valid = typeof value === expectedType;
+ } else if (type === Number) {
+ expectedType = 'number';
+ valid = typeof value === expectedType;
+ } else if (type === Boolean) {
+ expectedType = 'boolean';
+ valid = typeof value === expectedType;
+ } else if (type === Function) {
+ expectedType = 'function';
+ valid = typeof value === expectedType;
+ } else if (type === Object) {
+ expectedType = 'object';
+ valid = isPlainObject(value);
+ } else if (type === Array) {
+ expectedType = 'array';
+ valid = isArray(value);
+ } else {
+ valid = value instanceof type;
+ }
+ return {
+ valid: valid,
+ expectedType: expectedType
+ };
+ }
+
+ /**
+ * Format type for output
+ *
+ * @param {String} type
+ * @return {String}
+ */
+
+ function formatType(type) {
+ return type ? type.charAt(0).toUpperCase() + type.slice(1) : 'custom type';
+ }
+
+ /**
+ * Format value
+ *
+ * @param {*} value
+ * @return {String}
+ */
+
+ function formatValue(val) {
+ return Object.prototype.toString.call(val).slice(8, -1);
+ }
+
+ var bindingModes = config._propBindingModes;
+
+ var propDef = {
+
+ bind: function bind() {
+ var child = this.vm;
+ var parent = child._context;
+ // passed in from compiler directly
+ var prop = this.descriptor.prop;
+ var childKey = prop.path;
+ var parentKey = prop.parentPath;
+ var twoWay = prop.mode === bindingModes.TWO_WAY;
+
+ var parentWatcher = this.parentWatcher = new Watcher(parent, parentKey, function (val) {
+ updateProp(child, prop, val);
+ }, {
+ twoWay: twoWay,
+ filters: prop.filters,
+ // important: props need to be observed on the
+ // v-for scope if present
+ scope: this._scope
+ });
+
+ // set the child initial value.
+ initProp(child, prop, parentWatcher.value);
+
+ // setup two-way binding
+ if (twoWay) {
+ // important: defer the child watcher creation until
+ // the created hook (after data observation)
+ var self = this;
+ child.$once('pre-hook:created', function () {
+ self.childWatcher = new Watcher(child, childKey, function (val) {
+ parentWatcher.set(val);
+ }, {
+ // ensure sync upward before parent sync down.
+ // this is necessary in cases e.g. the child
+ // mutates a prop array, then replaces it. (#1683)
+ sync: true
+ });
+ });
+ }
+ },
+
+ unbind: function unbind() {
+ this.parentWatcher.teardown();
+ if (this.childWatcher) {
+ this.childWatcher.teardown();
+ }
+ }
+ };
+
+ var queue$1 = [];
+ var queued = false;
+
+ /**
+ * Push a job into the queue.
+ *
+ * @param {Function} job
+ */
+
+ function pushJob(job) {
+ queue$1.push(job);
+ if (!queued) {
+ queued = true;
+ nextTick(flush);
+ }
+ }
+
+ /**
+ * Flush the queue, and do one forced reflow before
+ * triggering transitions.
+ */
+
+ function flush() {
+ // Force layout
+ var f = document.documentElement.offsetHeight;
+ for (var i = 0; i < queue$1.length; i++) {
+ queue$1[i]();
+ }
+ queue$1 = [];
+ queued = false;
+ // dummy return, so js linters don't complain about
+ // unused variable f
+ return f;
+ }
+
+ var TYPE_TRANSITION = 'transition';
+ var TYPE_ANIMATION = 'animation';
+ var transDurationProp = transitionProp + 'Duration';
+ var animDurationProp = animationProp + 'Duration';
+
+ /**
+ * If a just-entered element is applied the
+ * leave class while its enter transition hasn't started yet,
+ * and the transitioned property has the same value for both
+ * enter/leave, then the leave transition will be skipped and
+ * the transitionend event never fires. This function ensures
+ * its callback to be called after a transition has started
+ * by waiting for double raf.
+ *
+ * It falls back to setTimeout on devices that support CSS
+ * transitions but not raf (e.g. Android 4.2 browser) - since
+ * these environments are usually slow, we are giving it a
+ * relatively large timeout.
+ */
+
+ var raf = inBrowser && window.requestAnimationFrame;
+ var waitForTransitionStart = raf
+ /* istanbul ignore next */
+ ? function (fn) {
+ raf(function () {
+ raf(fn);
+ });
+ } : function (fn) {
+ setTimeout(fn, 50);
+ };
+
+ /**
+ * A Transition object that encapsulates the state and logic
+ * of the transition.
+ *
+ * @param {Element} el
+ * @param {String} id
+ * @param {Object} hooks
+ * @param {Vue} vm
+ */
+ function Transition(el, id, hooks, vm) {
+ this.id = id;
+ this.el = el;
+ this.enterClass = hooks && hooks.enterClass || id + '-enter';
+ this.leaveClass = hooks && hooks.leaveClass || id + '-leave';
+ this.hooks = hooks;
+ this.vm = vm;
+ // async state
+ this.pendingCssEvent = this.pendingCssCb = this.cancel = this.pendingJsCb = this.op = this.cb = null;
+ this.justEntered = false;
+ this.entered = this.left = false;
+ this.typeCache = {};
+ // check css transition type
+ this.type = hooks && hooks.type;
+ /* istanbul ignore if */
+ if (false) {
+ if (this.type && this.type !== TYPE_TRANSITION && this.type !== TYPE_ANIMATION) {
+ warn('invalid CSS transition type for transition="' + this.id + '": ' + this.type, vm);
+ }
+ }
+ // bind
+ var self = this;['enterNextTick', 'enterDone', 'leaveNextTick', 'leaveDone'].forEach(function (m) {
+ self[m] = bind(self[m], self);
+ });
+ }
+
+ var p$1 = Transition.prototype;
+
+ /**
+ * Start an entering transition.
+ *
+ * 1. enter transition triggered
+ * 2. call beforeEnter hook
+ * 3. add enter class
+ * 4. insert/show element
+ * 5. call enter hook (with possible explicit js callback)
+ * 6. reflow
+ * 7. based on transition type:
+ * - transition:
+ * remove class now, wait for transitionend,
+ * then done if there's no explicit js callback.
+ * - animation:
+ * wait for animationend, remove class,
+ * then done if there's no explicit js callback.
+ * - no css transition:
+ * done now if there's no explicit js callback.
+ * 8. wait for either done or js callback, then call
+ * afterEnter hook.
+ *
+ * @param {Function} op - insert/show the element
+ * @param {Function} [cb]
+ */
+
+ p$1.enter = function (op, cb) {
+ this.cancelPending();
+ this.callHook('beforeEnter');
+ this.cb = cb;
+ addClass(this.el, this.enterClass);
+ op();
+ this.entered = false;
+ this.callHookWithCb('enter');
+ if (this.entered) {
+ return; // user called done synchronously.
+ }
+ this.cancel = this.hooks && this.hooks.enterCancelled;
+ pushJob(this.enterNextTick);
+ };
+
+ /**
+ * The "nextTick" phase of an entering transition, which is
+ * to be pushed into a queue and executed after a reflow so
+ * that removing the class can trigger a CSS transition.
+ */
+
+ p$1.enterNextTick = function () {
+ var _this = this;
+
+ // prevent transition skipping
+ this.justEntered = true;
+ waitForTransitionStart(function () {
+ _this.justEntered = false;
+ });
+ var enterDone = this.enterDone;
+ var type = this.getCssTransitionType(this.enterClass);
+ if (!this.pendingJsCb) {
+ if (type === TYPE_TRANSITION) {
+ // trigger transition by removing enter class now
+ removeClass(this.el, this.enterClass);
+ this.setupCssCb(transitionEndEvent, enterDone);
+ } else if (type === TYPE_ANIMATION) {
+ this.setupCssCb(animationEndEvent, enterDone);
+ } else {
+ enterDone();
+ }
+ } else if (type === TYPE_TRANSITION) {
+ removeClass(this.el, this.enterClass);
+ }
+ };
+
+ /**
+ * The "cleanup" phase of an entering transition.
+ */
+
+ p$1.enterDone = function () {
+ this.entered = true;
+ this.cancel = this.pendingJsCb = null;
+ removeClass(this.el, this.enterClass);
+ this.callHook('afterEnter');
+ if (this.cb) this.cb();
+ };
+
+ /**
+ * Start a leaving transition.
+ *
+ * 1. leave transition triggered.
+ * 2. call beforeLeave hook
+ * 3. add leave class (trigger css transition)
+ * 4. call leave hook (with possible explicit js callback)
+ * 5. reflow if no explicit js callback is provided
+ * 6. based on transition type:
+ * - transition or animation:
+ * wait for end event, remove class, then done if
+ * there's no explicit js callback.
+ * - no css transition:
+ * done if there's no explicit js callback.
+ * 7. wait for either done or js callback, then call
+ * afterLeave hook.
+ *
+ * @param {Function} op - remove/hide the element
+ * @param {Function} [cb]
+ */
+
+ p$1.leave = function (op, cb) {
+ this.cancelPending();
+ this.callHook('beforeLeave');
+ this.op = op;
+ this.cb = cb;
+ addClass(this.el, this.leaveClass);
+ this.left = false;
+ this.callHookWithCb('leave');
+ if (this.left) {
+ return; // user called done synchronously.
+ }
+ this.cancel = this.hooks && this.hooks.leaveCancelled;
+ // only need to handle leaveDone if
+ // 1. the transition is already done (synchronously called
+ // by the user, which causes this.op set to null)
+ // 2. there's no explicit js callback
+ if (this.op && !this.pendingJsCb) {
+ // if a CSS transition leaves immediately after enter,
+ // the transitionend event never fires. therefore we
+ // detect such cases and end the leave immediately.
+ if (this.justEntered) {
+ this.leaveDone();
+ } else {
+ pushJob(this.leaveNextTick);
+ }
+ }
+ };
+
+ /**
+ * The "nextTick" phase of a leaving transition.
+ */
+
+ p$1.leaveNextTick = function () {
+ var type = this.getCssTransitionType(this.leaveClass);
+ if (type) {
+ var event = type === TYPE_TRANSITION ? transitionEndEvent : animationEndEvent;
+ this.setupCssCb(event, this.leaveDone);
+ } else {
+ this.leaveDone();
+ }
+ };
+
+ /**
+ * The "cleanup" phase of a leaving transition.
+ */
+
+ p$1.leaveDone = function () {
+ this.left = true;
+ this.cancel = this.pendingJsCb = null;
+ this.op();
+ removeClass(this.el, this.leaveClass);
+ this.callHook('afterLeave');
+ if (this.cb) this.cb();
+ this.op = null;
+ };
+
+ /**
+ * Cancel any pending callbacks from a previously running
+ * but not finished transition.
+ */
+
+ p$1.cancelPending = function () {
+ this.op = this.cb = null;
+ var hasPending = false;
+ if (this.pendingCssCb) {
+ hasPending = true;
+ off(this.el, this.pendingCssEvent, this.pendingCssCb);
+ this.pendingCssEvent = this.pendingCssCb = null;
+ }
+ if (this.pendingJsCb) {
+ hasPending = true;
+ this.pendingJsCb.cancel();
+ this.pendingJsCb = null;
+ }
+ if (hasPending) {
+ removeClass(this.el, this.enterClass);
+ removeClass(this.el, this.leaveClass);
+ }
+ if (this.cancel) {
+ this.cancel.call(this.vm, this.el);
+ this.cancel = null;
+ }
+ };
+
+ /**
+ * Call a user-provided synchronous hook function.
+ *
+ * @param {String} type
+ */
+
+ p$1.callHook = function (type) {
+ if (this.hooks && this.hooks[type]) {
+ this.hooks[type].call(this.vm, this.el);
+ }
+ };
+
+ /**
+ * Call a user-provided, potentially-async hook function.
+ * We check for the length of arguments to see if the hook
+ * expects a `done` callback. If true, the transition's end
+ * will be determined by when the user calls that callback;
+ * otherwise, the end is determined by the CSS transition or
+ * animation.
+ *
+ * @param {String} type
+ */
+
+ p$1.callHookWithCb = function (type) {
+ var hook = this.hooks && this.hooks[type];
+ if (hook) {
+ if (hook.length > 1) {
+ this.pendingJsCb = cancellable(this[type + 'Done']);
+ }
+ hook.call(this.vm, this.el, this.pendingJsCb);
+ }
+ };
+
+ /**
+ * Get an element's transition type based on the
+ * calculated styles.
+ *
+ * @param {String} className
+ * @return {Number}
+ */
+
+ p$1.getCssTransitionType = function (className) {
+ /* istanbul ignore if */
+ if (!transitionEndEvent ||
+ // skip CSS transitions if page is not visible -
+ // this solves the issue of transitionend events not
+ // firing until the page is visible again.
+ // pageVisibility API is supported in IE10+, same as
+ // CSS transitions.
+ document.hidden ||
+ // explicit js-only transition
+ this.hooks && this.hooks.css === false ||
+ // element is hidden
+ isHidden(this.el)) {
+ return;
+ }
+ var type = this.type || this.typeCache[className];
+ if (type) return type;
+ var inlineStyles = this.el.style;
+ var computedStyles = window.getComputedStyle(this.el);
+ var transDuration = inlineStyles[transDurationProp] || computedStyles[transDurationProp];
+ if (transDuration && transDuration !== '0s') {
+ type = TYPE_TRANSITION;
+ } else {
+ var animDuration = inlineStyles[animDurationProp] || computedStyles[animDurationProp];
+ if (animDuration && animDuration !== '0s') {
+ type = TYPE_ANIMATION;
+ }
+ }
+ if (type) {
+ this.typeCache[className] = type;
+ }
+ return type;
+ };
+
+ /**
+ * Setup a CSS transitionend/animationend callback.
+ *
+ * @param {String} event
+ * @param {Function} cb
+ */
+
+ p$1.setupCssCb = function (event, cb) {
+ this.pendingCssEvent = event;
+ var self = this;
+ var el = this.el;
+ var onEnd = this.pendingCssCb = function (e) {
+ if (e.target === el) {
+ off(el, event, onEnd);
+ self.pendingCssEvent = self.pendingCssCb = null;
+ if (!self.pendingJsCb && cb) {
+ cb();
+ }
+ }
+ };
+ on(el, event, onEnd);
+ };
+
+ /**
+ * Check if an element is hidden - in that case we can just
+ * skip the transition alltogether.
+ *
+ * @param {Element} el
+ * @return {Boolean}
+ */
+
+ function isHidden(el) {
+ if (/svg$/.test(el.namespaceURI)) {
+ // SVG elements do not have offset(Width|Height)
+ // so we need to check the client rect
+ var rect = el.getBoundingClientRect();
+ return !(rect.width || rect.height);
+ } else {
+ return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
+ }
+ }
+
+ var transition$1 = {
+
+ priority: TRANSITION,
+
+ update: function update(id, oldId) {
+ var el = this.el;
+ // resolve on owner vm
+ var hooks = resolveAsset(this.vm.$options, 'transitions', id);
+ id = id || 'v';
+ el.__v_trans = new Transition(el, id, hooks, this.vm);
+ if (oldId) {
+ removeClass(el, oldId + '-transition');
+ }
+ addClass(el, id + '-transition');
+ }
+ };
+
+ var internalDirectives = {
+ style: style,
+ 'class': vClass,
+ component: component,
+ prop: propDef,
+ transition: transition$1
+ };
+
+ // special binding prefixes
+ var bindRE = /^v-bind:|^:/;
+ var onRE = /^v-on:|^@/;
+ var dirAttrRE = /^v-([^:]+)(?:$|:(.*)$)/;
+ var modifierRE = /\.[^\.]+/g;
+ var transitionRE = /^(v-bind:|:)?transition$/;
+
+ // default directive priority
+ var DEFAULT_PRIORITY = 1000;
+ var DEFAULT_TERMINAL_PRIORITY = 2000;
+
+ /**
+ * Compile a template and return a reusable composite link
+ * function, which recursively contains more link functions
+ * inside. This top level compile function would normally
+ * be called on instance root nodes, but can also be used
+ * for partial compilation if the partial argument is true.
+ *
+ * The returned composite link function, when called, will
+ * return an unlink function that tearsdown all directives
+ * created during the linking phase.
+ *
+ * @param {Element|DocumentFragment} el
+ * @param {Object} options
+ * @param {Boolean} partial
+ * @return {Function}
+ */
+
+ function compile(el, options, partial) {
+ // link function for the node itself.
+ var nodeLinkFn = partial || !options._asComponent ? compileNode(el, options) : null;
+ // link function for the childNodes
+ var childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && !isScript(el) && el.hasChildNodes() ? compileNodeList(el.childNodes, options) : null;
+
+ /**
+ * A composite linker function to be called on a already
+ * compiled piece of DOM, which instantiates all directive
+ * instances.
+ *
+ * @param {Vue} vm
+ * @param {Element|DocumentFragment} el
+ * @param {Vue} [host] - host vm of transcluded content
+ * @param {Object} [scope] - v-for scope
+ * @param {Fragment} [frag] - link context fragment
+ * @return {Function|undefined}
+ */
+
+ return function compositeLinkFn(vm, el, host, scope, frag) {
+ // cache childNodes before linking parent, fix #657
+ var childNodes = toArray(el.childNodes);
+ // link
+ var dirs = linkAndCapture(function compositeLinkCapturer() {
+ if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag);
+ if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag);
+ }, vm);
+ return makeUnlinkFn(vm, dirs);
+ };
+ }
+
+ /**
+ * Apply a linker to a vm/element pair and capture the
+ * directives created during the process.
+ *
+ * @param {Function} linker
+ * @param {Vue} vm
+ */
+
+ function linkAndCapture(linker, vm) {
+ /* istanbul ignore if */
+ if (true) {
+ // reset directives before every capture in production
+ // mode, so that when unlinking we don't need to splice
+ // them out (which turns out to be a perf hit).
+ // they are kept in development mode because they are
+ // useful for Vue's own tests.
+ vm._directives = [];
+ }
+ var originalDirCount = vm._directives.length;
+ linker();
+ var dirs = vm._directives.slice(originalDirCount);
+ dirs.sort(directiveComparator);
+ for (var i = 0, l = dirs.length; i < l; i++) {
+ dirs[i]._bind();
+ }
+ return dirs;
+ }
+
+ /**
+ * Directive priority sort comparator
+ *
+ * @param {Object} a
+ * @param {Object} b
+ */
+
+ function directiveComparator(a, b) {
+ a = a.descriptor.def.priority || DEFAULT_PRIORITY;
+ b = b.descriptor.def.priority || DEFAULT_PRIORITY;
+ return a > b ? -1 : a === b ? 0 : 1;
+ }
+
+ /**
+ * Linker functions return an unlink function that
+ * tearsdown all directives instances generated during
+ * the process.
+ *
+ * We create unlink functions with only the necessary
+ * information to avoid retaining additional closures.
+ *
+ * @param {Vue} vm
+ * @param {Array} dirs
+ * @param {Vue} [context]
+ * @param {Array} [contextDirs]
+ * @return {Function}
+ */
+
+ function makeUnlinkFn(vm, dirs, context, contextDirs) {
+ function unlink(destroying) {
+ teardownDirs(vm, dirs, destroying);
+ if (context && contextDirs) {
+ teardownDirs(context, contextDirs);
+ }
+ }
+ // expose linked directives
+ unlink.dirs = dirs;
+ return unlink;
+ }
+
+ /**
+ * Teardown partial linked directives.
+ *
+ * @param {Vue} vm
+ * @param {Array} dirs
+ * @param {Boolean} destroying
+ */
+
+ function teardownDirs(vm, dirs, destroying) {
+ var i = dirs.length;
+ while (i--) {
+ dirs[i]._teardown();
+ if (false) {
+ vm._directives.$remove(dirs[i]);
+ }
+ }
+ }
+
+ /**
+ * Compile link props on an instance.
+ *
+ * @param {Vue} vm
+ * @param {Element} el
+ * @param {Object} props
+ * @param {Object} [scope]
+ * @return {Function}
+ */
+
+ function compileAndLinkProps(vm, el, props, scope) {
+ var propsLinkFn = compileProps(el, props, vm);
+ var propDirs = linkAndCapture(function () {
+ propsLinkFn(vm, scope);
+ }, vm);
+ return makeUnlinkFn(vm, propDirs);
+ }
+
+ /**
+ * Compile the root element of an instance.
+ *
+ * 1. attrs on context container (context scope)
+ * 2. attrs on the component template root node, if
+ * replace:true (child scope)
+ *
+ * If this is a fragment instance, we only need to compile 1.
+ *
+ * @param {Element} el
+ * @param {Object} options
+ * @param {Object} contextOptions
+ * @return {Function}
+ */
+
+ function compileRoot(el, options, contextOptions) {
+ var containerAttrs = options._containerAttrs;
+ var replacerAttrs = options._replacerAttrs;
+ var contextLinkFn, replacerLinkFn;
+
+ // only need to compile other attributes for
+ // non-fragment instances
+ if (el.nodeType !== 11) {
+ // for components, container and replacer need to be
+ // compiled separately and linked in different scopes.
+ if (options._asComponent) {
+ // 2. container attributes
+ if (containerAttrs && contextOptions) {
+ contextLinkFn = compileDirectives(containerAttrs, contextOptions);
+ }
+ if (replacerAttrs) {
+ // 3. replacer attributes
+ replacerLinkFn = compileDirectives(replacerAttrs, options);
+ }
+ } else {
+ // non-component, just compile as a normal element.
+ replacerLinkFn = compileDirectives(el.attributes, options);
+ }
+ } else if (false) {
+ // warn container directives for fragment instances
+ var names = containerAttrs.filter(function (attr) {
+ // allow vue-loader/vueify scoped css attributes
+ return attr.name.indexOf('_v-') < 0 &&
+ // allow event listeners
+ !onRE.test(attr.name) &&
+ // allow slots
+ attr.name !== 'slot';
+ }).map(function (attr) {
+ return '"' + attr.name + '"';
+ });
+ if (names.length) {
+ var plural = names.length > 1;
+ warn('Attribute' + (plural ? 's ' : ' ') + names.join(', ') + (plural ? ' are' : ' is') + ' ignored on component ' + '<' + options.el.tagName.toLowerCase() + '> because ' + 'the component is a fragment instance: ' + 'http://vuejs.org/guide/components.html#Fragment-Instance');
+ }
+ }
+
+ options._containerAttrs = options._replacerAttrs = null;
+ return function rootLinkFn(vm, el, scope) {
+ // link context scope dirs
+ var context = vm._context;
+ var contextDirs;
+ if (context && contextLinkFn) {
+ contextDirs = linkAndCapture(function () {
+ contextLinkFn(context, el, null, scope);
+ }, context);
+ }
+
+ // link self
+ var selfDirs = linkAndCapture(function () {
+ if (replacerLinkFn) replacerLinkFn(vm, el);
+ }, vm);
+
+ // return the unlink function that tearsdown context
+ // container directives.
+ return makeUnlinkFn(vm, selfDirs, context, contextDirs);
+ };
+ }
+
+ /**
+ * Compile a node and return a nodeLinkFn based on the
+ * node type.
+ *
+ * @param {Node} node
+ * @param {Object} options
+ * @return {Function|null}
+ */
+
+ function compileNode(node, options) {
+ var type = node.nodeType;
+ if (type === 1 && !isScript(node)) {
+ return compileElement(node, options);
+ } else if (type === 3 && node.data.trim()) {
+ return compileTextNode(node, options);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Compile an element and return a nodeLinkFn.
+ *
+ * @param {Element} el
+ * @param {Object} options
+ * @return {Function|null}
+ */
+
+ function compileElement(el, options) {
+ // preprocess textareas.
+ // textarea treats its text content as the initial value.
+ // just bind it as an attr directive for value.
+ if (el.tagName === 'TEXTAREA') {
+ var tokens = parseText(el.value);
+ if (tokens) {
+ el.setAttribute(':value', tokensToExp(tokens));
+ el.value = '';
+ }
+ }
+ var linkFn;
+ var hasAttrs = el.hasAttributes();
+ var attrs = hasAttrs && toArray(el.attributes);
+ // check terminal directives (for & if)
+ if (hasAttrs) {
+ linkFn = checkTerminalDirectives(el, attrs, options);
+ }
+ // check element directives
+ if (!linkFn) {
+ linkFn = checkElementDirectives(el, options);
+ }
+ // check component
+ if (!linkFn) {
+ linkFn = checkComponent(el, options);
+ }
+ // normal directives
+ if (!linkFn && hasAttrs) {
+ linkFn = compileDirectives(attrs, options);
+ }
+ return linkFn;
+ }
+
+ /**
+ * Compile a textNode and return a nodeLinkFn.
+ *
+ * @param {TextNode} node
+ * @param {Object} options
+ * @return {Function|null} textNodeLinkFn
+ */
+
+ function compileTextNode(node, options) {
+ // skip marked text nodes
+ if (node._skip) {
+ return removeText;
+ }
+
+ var tokens = parseText(node.wholeText);
+ if (!tokens) {
+ return null;
+ }
+
+ // mark adjacent text nodes as skipped,
+ // because we are using node.wholeText to compile
+ // all adjacent text nodes together. This fixes
+ // issues in IE where sometimes it splits up a single
+ // text node into multiple ones.
+ var next = node.nextSibling;
+ while (next && next.nodeType === 3) {
+ next._skip = true;
+ next = next.nextSibling;
+ }
+
+ var frag = document.createDocumentFragment();
+ var el, token;
+ for (var i = 0, l = tokens.length; i < l; i++) {
+ token = tokens[i];
+ el = token.tag ? processTextToken(token, options) : document.createTextNode(token.value);
+ frag.appendChild(el);
+ }
+ return makeTextNodeLinkFn(tokens, frag, options);
+ }
+
+ /**
+ * Linker for an skipped text node.
+ *
+ * @param {Vue} vm
+ * @param {Text} node
+ */
+
+ function removeText(vm, node) {
+ remove(node);
+ }
+
+ /**
+ * Process a single text token.
+ *
+ * @param {Object} token
+ * @param {Object} options
+ * @return {Node}
+ */
+
+ function processTextToken(token, options) {
+ var el;
+ if (token.oneTime) {
+ el = document.createTextNode(token.value);
+ } else {
+ if (token.html) {
+ el = document.createComment('v-html');
+ setTokenType('html');
+ } else {
+ // IE will clean up empty textNodes during
+ // frag.cloneNode(true), so we have to give it
+ // something here...
+ el = document.createTextNode(' ');
+ setTokenType('text');
+ }
+ }
+ function setTokenType(type) {
+ if (token.descriptor) return;
+ var parsed = parseDirective(token.value);
+ token.descriptor = {
+ name: type,
+ def: directives[type],
+ expression: parsed.expression,
+ filters: parsed.filters
+ };
+ }
+ return el;
+ }
+
+ /**
+ * Build a function that processes a textNode.
+ *
+ * @param {Array