github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/vue-1.0.24/dist/vue.js (about)

     1  /*!
     2   * Vue.js v1.0.24
     3   * (c) 2016 Evan You
     4   * Released under the MIT License.
     5   */
     6  (function (global, factory) {
     7    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
     8    typeof define === 'function' && define.amd ? define(factory) :
     9    (global.Vue = factory());
    10  }(this, function () { 'use strict';
    11  
    12    function set(obj, key, val) {
    13      if (hasOwn(obj, key)) {
    14        obj[key] = val;
    15        return;
    16      }
    17      if (obj._isVue) {
    18        set(obj._data, key, val);
    19        return;
    20      }
    21      var ob = obj.__ob__;
    22      if (!ob) {
    23        obj[key] = val;
    24        return;
    25      }
    26      ob.convert(key, val);
    27      ob.dep.notify();
    28      if (ob.vms) {
    29        var i = ob.vms.length;
    30        while (i--) {
    31          var vm = ob.vms[i];
    32          vm._proxy(key);
    33          vm._digest();
    34        }
    35      }
    36      return val;
    37    }
    38  
    39    /**
    40     * Delete a property and trigger change if necessary.
    41     *
    42     * @param {Object} obj
    43     * @param {String} key
    44     */
    45  
    46    function del(obj, key) {
    47      if (!hasOwn(obj, key)) {
    48        return;
    49      }
    50      delete obj[key];
    51      var ob = obj.__ob__;
    52      if (!ob) {
    53        if (obj._isVue) {
    54          delete obj._data[key];
    55          obj._digest();
    56        }
    57        return;
    58      }
    59      ob.dep.notify();
    60      if (ob.vms) {
    61        var i = ob.vms.length;
    62        while (i--) {
    63          var vm = ob.vms[i];
    64          vm._unproxy(key);
    65          vm._digest();
    66        }
    67      }
    68    }
    69  
    70    var hasOwnProperty = Object.prototype.hasOwnProperty;
    71    /**
    72     * Check whether the object has the property.
    73     *
    74     * @param {Object} obj
    75     * @param {String} key
    76     * @return {Boolean}
    77     */
    78  
    79    function hasOwn(obj, key) {
    80      return hasOwnProperty.call(obj, key);
    81    }
    82  
    83    /**
    84     * Check if an expression is a literal value.
    85     *
    86     * @param {String} exp
    87     * @return {Boolean}
    88     */
    89  
    90    var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;
    91  
    92    function isLiteral(exp) {
    93      return literalValueRE.test(exp);
    94    }
    95  
    96    /**
    97     * Check if a string starts with $ or _
    98     *
    99     * @param {String} str
   100     * @return {Boolean}
   101     */
   102  
   103    function isReserved(str) {
   104      var c = (str + '').charCodeAt(0);
   105      return c === 0x24 || c === 0x5F;
   106    }
   107  
   108    /**
   109     * Guard text output, make sure undefined outputs
   110     * empty string
   111     *
   112     * @param {*} value
   113     * @return {String}
   114     */
   115  
   116    function _toString(value) {
   117      return value == null ? '' : value.toString();
   118    }
   119  
   120    /**
   121     * Check and convert possible numeric strings to numbers
   122     * before setting back to data
   123     *
   124     * @param {*} value
   125     * @return {*|Number}
   126     */
   127  
   128    function toNumber(value) {
   129      if (typeof value !== 'string') {
   130        return value;
   131      } else {
   132        var parsed = Number(value);
   133        return isNaN(parsed) ? value : parsed;
   134      }
   135    }
   136  
   137    /**
   138     * Convert string boolean literals into real booleans.
   139     *
   140     * @param {*} value
   141     * @return {*|Boolean}
   142     */
   143  
   144    function toBoolean(value) {
   145      return value === 'true' ? true : value === 'false' ? false : value;
   146    }
   147  
   148    /**
   149     * Strip quotes from a string
   150     *
   151     * @param {String} str
   152     * @return {String | false}
   153     */
   154  
   155    function stripQuotes(str) {
   156      var a = str.charCodeAt(0);
   157      var b = str.charCodeAt(str.length - 1);
   158      return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
   159    }
   160  
   161    /**
   162     * Camelize a hyphen-delmited string.
   163     *
   164     * @param {String} str
   165     * @return {String}
   166     */
   167  
   168    var camelizeRE = /-(\w)/g;
   169  
   170    function camelize(str) {
   171      return str.replace(camelizeRE, toUpper);
   172    }
   173  
   174    function toUpper(_, c) {
   175      return c ? c.toUpperCase() : '';
   176    }
   177  
   178    /**
   179     * Hyphenate a camelCase string.
   180     *
   181     * @param {String} str
   182     * @return {String}
   183     */
   184  
   185    var hyphenateRE = /([a-z\d])([A-Z])/g;
   186  
   187    function hyphenate(str) {
   188      return str.replace(hyphenateRE, '$1-$2').toLowerCase();
   189    }
   190  
   191    /**
   192     * Converts hyphen/underscore/slash delimitered names into
   193     * camelized classNames.
   194     *
   195     * e.g. my-component => MyComponent
   196     *      some_else    => SomeElse
   197     *      some/comp    => SomeComp
   198     *
   199     * @param {String} str
   200     * @return {String}
   201     */
   202  
   203    var classifyRE = /(?:^|[-_\/])(\w)/g;
   204  
   205    function classify(str) {
   206      return str.replace(classifyRE, toUpper);
   207    }
   208  
   209    /**
   210     * Simple bind, faster than native
   211     *
   212     * @param {Function} fn
   213     * @param {Object} ctx
   214     * @return {Function}
   215     */
   216  
   217    function bind(fn, ctx) {
   218      return function (a) {
   219        var l = arguments.length;
   220        return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
   221      };
   222    }
   223  
   224    /**
   225     * Convert an Array-like object to a real Array.
   226     *
   227     * @param {Array-like} list
   228     * @param {Number} [start] - start index
   229     * @return {Array}
   230     */
   231  
   232    function toArray(list, start) {
   233      start = start || 0;
   234      var i = list.length - start;
   235      var ret = new Array(i);
   236      while (i--) {
   237        ret[i] = list[i + start];
   238      }
   239      return ret;
   240    }
   241  
   242    /**
   243     * Mix properties into target object.
   244     *
   245     * @param {Object} to
   246     * @param {Object} from
   247     */
   248  
   249    function extend(to, from) {
   250      var keys = Object.keys(from);
   251      var i = keys.length;
   252      while (i--) {
   253        to[keys[i]] = from[keys[i]];
   254      }
   255      return to;
   256    }
   257  
   258    /**
   259     * Quick object check - this is primarily used to tell
   260     * Objects from primitive values when we know the value
   261     * is a JSON-compliant type.
   262     *
   263     * @param {*} obj
   264     * @return {Boolean}
   265     */
   266  
   267    function isObject(obj) {
   268      return obj !== null && typeof obj === 'object';
   269    }
   270  
   271    /**
   272     * Strict object type check. Only returns true
   273     * for plain JavaScript objects.
   274     *
   275     * @param {*} obj
   276     * @return {Boolean}
   277     */
   278  
   279    var toString = Object.prototype.toString;
   280    var OBJECT_STRING = '[object Object]';
   281  
   282    function isPlainObject(obj) {
   283      return toString.call(obj) === OBJECT_STRING;
   284    }
   285  
   286    /**
   287     * Array type check.
   288     *
   289     * @param {*} obj
   290     * @return {Boolean}
   291     */
   292  
   293    var isArray = Array.isArray;
   294  
   295    /**
   296     * Define a property.
   297     *
   298     * @param {Object} obj
   299     * @param {String} key
   300     * @param {*} val
   301     * @param {Boolean} [enumerable]
   302     */
   303  
   304    function def(obj, key, val, enumerable) {
   305      Object.defineProperty(obj, key, {
   306        value: val,
   307        enumerable: !!enumerable,
   308        writable: true,
   309        configurable: true
   310      });
   311    }
   312  
   313    /**
   314     * Debounce a function so it only gets called after the
   315     * input stops arriving after the given wait period.
   316     *
   317     * @param {Function} func
   318     * @param {Number} wait
   319     * @return {Function} - the debounced function
   320     */
   321  
   322    function _debounce(func, wait) {
   323      var timeout, args, context, timestamp, result;
   324      var later = function later() {
   325        var last = Date.now() - timestamp;
   326        if (last < wait && last >= 0) {
   327          timeout = setTimeout(later, wait - last);
   328        } else {
   329          timeout = null;
   330          result = func.apply(context, args);
   331          if (!timeout) context = args = null;
   332        }
   333      };
   334      return function () {
   335        context = this;
   336        args = arguments;
   337        timestamp = Date.now();
   338        if (!timeout) {
   339          timeout = setTimeout(later, wait);
   340        }
   341        return result;
   342      };
   343    }
   344  
   345    /**
   346     * Manual indexOf because it's slightly faster than
   347     * native.
   348     *
   349     * @param {Array} arr
   350     * @param {*} obj
   351     */
   352  
   353    function indexOf(arr, obj) {
   354      var i = arr.length;
   355      while (i--) {
   356        if (arr[i] === obj) return i;
   357      }
   358      return -1;
   359    }
   360  
   361    /**
   362     * Make a cancellable version of an async callback.
   363     *
   364     * @param {Function} fn
   365     * @return {Function}
   366     */
   367  
   368    function cancellable(fn) {
   369      var cb = function cb() {
   370        if (!cb.cancelled) {
   371          return fn.apply(this, arguments);
   372        }
   373      };
   374      cb.cancel = function () {
   375        cb.cancelled = true;
   376      };
   377      return cb;
   378    }
   379  
   380    /**
   381     * Check if two values are loosely equal - that is,
   382     * if they are plain objects, do they have the same shape?
   383     *
   384     * @param {*} a
   385     * @param {*} b
   386     * @return {Boolean}
   387     */
   388  
   389    function looseEqual(a, b) {
   390      /* eslint-disable eqeqeq */
   391      return a == b || (isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false);
   392      /* eslint-enable eqeqeq */
   393    }
   394  
   395    var hasProto = ('__proto__' in {});
   396  
   397    // Browser environment sniffing
   398    var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
   399  
   400    // detect devtools
   401    var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
   402  
   403    // UA sniffing for working around browser-specific quirks
   404    var UA = inBrowser && window.navigator.userAgent.toLowerCase();
   405    var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
   406    var isAndroid = UA && UA.indexOf('android') > 0;
   407    var isIos = UA && /(iphone|ipad|ipod|ios)/i.test(UA);
   408    var isWechat = UA && UA.indexOf('micromessenger') > 0;
   409  
   410    var transitionProp = undefined;
   411    var transitionEndEvent = undefined;
   412    var animationProp = undefined;
   413    var animationEndEvent = undefined;
   414  
   415    // Transition property/event sniffing
   416    if (inBrowser && !isIE9) {
   417      var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
   418      var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
   419      transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
   420      transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
   421      animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
   422      animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
   423    }
   424  
   425    /**
   426     * Defer a task to execute it asynchronously. Ideally this
   427     * should be executed as a microtask, so we leverage
   428     * MutationObserver if it's available, and fallback to
   429     * setTimeout(0).
   430     *
   431     * @param {Function} cb
   432     * @param {Object} ctx
   433     */
   434  
   435    var nextTick = (function () {
   436      var callbacks = [];
   437      var pending = false;
   438      var timerFunc;
   439      function nextTickHandler() {
   440        pending = false;
   441        var copies = callbacks.slice(0);
   442        callbacks = [];
   443        for (var i = 0; i < copies.length; i++) {
   444          copies[i]();
   445        }
   446      }
   447  
   448      /* istanbul ignore if */
   449      if (typeof MutationObserver !== 'undefined' && !(isWechat && isIos)) {
   450        var counter = 1;
   451        var observer = new MutationObserver(nextTickHandler);
   452        var textNode = document.createTextNode(counter);
   453        observer.observe(textNode, {
   454          characterData: true
   455        });
   456        timerFunc = function () {
   457          counter = (counter + 1) % 2;
   458          textNode.data = counter;
   459        };
   460      } else {
   461        // webpack attempts to inject a shim for setImmediate
   462        // if it is used as a global, so we have to work around that to
   463        // avoid bundling unnecessary code.
   464        var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
   465        timerFunc = context.setImmediate || setTimeout;
   466      }
   467      return function (cb, ctx) {
   468        var func = ctx ? function () {
   469          cb.call(ctx);
   470        } : cb;
   471        callbacks.push(func);
   472        if (pending) return;
   473        pending = true;
   474        timerFunc(nextTickHandler, 0);
   475      };
   476    })();
   477  
   478    var _Set = undefined;
   479    /* istanbul ignore if */
   480    if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
   481      // use native Set when available.
   482      _Set = Set;
   483    } else {
   484      // a non-standard Set polyfill that only works with primitive keys.
   485      _Set = function () {
   486        this.set = Object.create(null);
   487      };
   488      _Set.prototype.has = function (key) {
   489        return this.set[key] !== undefined;
   490      };
   491      _Set.prototype.add = function (key) {
   492        this.set[key] = 1;
   493      };
   494      _Set.prototype.clear = function () {
   495        this.set = Object.create(null);
   496      };
   497    }
   498  
   499    function Cache(limit) {
   500      this.size = 0;
   501      this.limit = limit;
   502      this.head = this.tail = undefined;
   503      this._keymap = Object.create(null);
   504    }
   505  
   506    var p = Cache.prototype;
   507  
   508    /**
   509     * Put <value> into the cache associated with <key>.
   510     * Returns the entry which was removed to make room for
   511     * the new entry. Otherwise undefined is returned.
   512     * (i.e. if there was enough room already).
   513     *
   514     * @param {String} key
   515     * @param {*} value
   516     * @return {Entry|undefined}
   517     */
   518  
   519    p.put = function (key, value) {
   520      var removed;
   521      if (this.size === this.limit) {
   522        removed = this.shift();
   523      }
   524  
   525      var entry = this.get(key, true);
   526      if (!entry) {
   527        entry = {
   528          key: key
   529        };
   530        this._keymap[key] = entry;
   531        if (this.tail) {
   532          this.tail.newer = entry;
   533          entry.older = this.tail;
   534        } else {
   535          this.head = entry;
   536        }
   537        this.tail = entry;
   538        this.size++;
   539      }
   540      entry.value = value;
   541  
   542      return removed;
   543    };
   544  
   545    /**
   546     * Purge the least recently used (oldest) entry from the
   547     * cache. Returns the removed entry or undefined if the
   548     * cache was empty.
   549     */
   550  
   551    p.shift = function () {
   552      var entry = this.head;
   553      if (entry) {
   554        this.head = this.head.newer;
   555        this.head.older = undefined;
   556        entry.newer = entry.older = undefined;
   557        this._keymap[entry.key] = undefined;
   558        this.size--;
   559      }
   560      return entry;
   561    };
   562  
   563    /**
   564     * Get and register recent use of <key>. Returns the value
   565     * associated with <key> or undefined if not in cache.
   566     *
   567     * @param {String} key
   568     * @param {Boolean} returnEntry
   569     * @return {Entry|*}
   570     */
   571  
   572    p.get = function (key, returnEntry) {
   573      var entry = this._keymap[key];
   574      if (entry === undefined) return;
   575      if (entry === this.tail) {
   576        return returnEntry ? entry : entry.value;
   577      }
   578      // HEAD--------------TAIL
   579      //   <.older   .newer>
   580      //  <--- add direction --
   581      //   A  B  C  <D>  E
   582      if (entry.newer) {
   583        if (entry === this.head) {
   584          this.head = entry.newer;
   585        }
   586        entry.newer.older = entry.older; // C <-- E.
   587      }
   588      if (entry.older) {
   589        entry.older.newer = entry.newer; // C. --> E
   590      }
   591      entry.newer = undefined; // D --x
   592      entry.older = this.tail; // D. --> E
   593      if (this.tail) {
   594        this.tail.newer = entry; // E. <-- D
   595      }
   596      this.tail = entry;
   597      return returnEntry ? entry : entry.value;
   598    };
   599  
   600    var cache$1 = new Cache(1000);
   601    var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
   602    var reservedArgRE = /^in$|^-?\d+/;
   603  
   604    /**
   605     * Parser state
   606     */
   607  
   608    var str;
   609    var dir;
   610    var c;
   611    var prev;
   612    var i;
   613    var l;
   614    var lastFilterIndex;
   615    var inSingle;
   616    var inDouble;
   617    var curly;
   618    var square;
   619    var paren;
   620    /**
   621     * Push a filter to the current directive object
   622     */
   623  
   624    function pushFilter() {
   625      var exp = str.slice(lastFilterIndex, i).trim();
   626      var filter;
   627      if (exp) {
   628        filter = {};
   629        var tokens = exp.match(filterTokenRE);
   630        filter.name = tokens[0];
   631        if (tokens.length > 1) {
   632          filter.args = tokens.slice(1).map(processFilterArg);
   633        }
   634      }
   635      if (filter) {
   636        (dir.filters = dir.filters || []).push(filter);
   637      }
   638      lastFilterIndex = i + 1;
   639    }
   640  
   641    /**
   642     * Check if an argument is dynamic and strip quotes.
   643     *
   644     * @param {String} arg
   645     * @return {Object}
   646     */
   647  
   648    function processFilterArg(arg) {
   649      if (reservedArgRE.test(arg)) {
   650        return {
   651          value: toNumber(arg),
   652          dynamic: false
   653        };
   654      } else {
   655        var stripped = stripQuotes(arg);
   656        var dynamic = stripped === arg;
   657        return {
   658          value: dynamic ? arg : stripped,
   659          dynamic: dynamic
   660        };
   661      }
   662    }
   663  
   664    /**
   665     * Parse a directive value and extract the expression
   666     * and its filters into a descriptor.
   667     *
   668     * Example:
   669     *
   670     * "a + 1 | uppercase" will yield:
   671     * {
   672     *   expression: 'a + 1',
   673     *   filters: [
   674     *     { name: 'uppercase', args: null }
   675     *   ]
   676     * }
   677     *
   678     * @param {String} s
   679     * @return {Object}
   680     */
   681  
   682    function parseDirective(s) {
   683      var hit = cache$1.get(s);
   684      if (hit) {
   685        return hit;
   686      }
   687  
   688      // reset parser state
   689      str = s;
   690      inSingle = inDouble = false;
   691      curly = square = paren = 0;
   692      lastFilterIndex = 0;
   693      dir = {};
   694  
   695      for (i = 0, l = str.length; i < l; i++) {
   696        prev = c;
   697        c = str.charCodeAt(i);
   698        if (inSingle) {
   699          // check single quote
   700          if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
   701        } else if (inDouble) {
   702          // check double quote
   703          if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
   704        } else if (c === 0x7C && // pipe
   705        str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
   706          if (dir.expression == null) {
   707            // first filter, end of expression
   708            lastFilterIndex = i + 1;
   709            dir.expression = str.slice(0, i).trim();
   710          } else {
   711            // already has filter
   712            pushFilter();
   713          }
   714        } else {
   715          switch (c) {
   716            case 0x22:
   717              inDouble = true;break; // "
   718            case 0x27:
   719              inSingle = true;break; // '
   720            case 0x28:
   721              paren++;break; // (
   722            case 0x29:
   723              paren--;break; // )
   724            case 0x5B:
   725              square++;break; // [
   726            case 0x5D:
   727              square--;break; // ]
   728            case 0x7B:
   729              curly++;break; // {
   730            case 0x7D:
   731              curly--;break; // }
   732          }
   733        }
   734      }
   735  
   736      if (dir.expression == null) {
   737        dir.expression = str.slice(0, i).trim();
   738      } else if (lastFilterIndex !== 0) {
   739        pushFilter();
   740      }
   741  
   742      cache$1.put(s, dir);
   743      return dir;
   744    }
   745  
   746  var directive = Object.freeze({
   747      parseDirective: parseDirective
   748    });
   749  
   750    var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
   751    var cache = undefined;
   752    var tagRE = undefined;
   753    var htmlRE = undefined;
   754    /**
   755     * Escape a string so it can be used in a RegExp
   756     * constructor.
   757     *
   758     * @param {String} str
   759     */
   760  
   761    function escapeRegex(str) {
   762      return str.replace(regexEscapeRE, '\\$&');
   763    }
   764  
   765    function compileRegex() {
   766      var open = escapeRegex(config.delimiters[0]);
   767      var close = escapeRegex(config.delimiters[1]);
   768      var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
   769      var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
   770      tagRE = new RegExp(unsafeOpen + '((?:.|\\n)+?)' + unsafeClose + '|' + open + '((?:.|\\n)+?)' + close, 'g');
   771      htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
   772      // reset cache
   773      cache = new Cache(1000);
   774    }
   775  
   776    /**
   777     * Parse a template text string into an array of tokens.
   778     *
   779     * @param {String} text
   780     * @return {Array<Object> | null}
   781     *               - {String} type
   782     *               - {String} value
   783     *               - {Boolean} [html]
   784     *               - {Boolean} [oneTime]
   785     */
   786  
   787    function parseText(text) {
   788      if (!cache) {
   789        compileRegex();
   790      }
   791      var hit = cache.get(text);
   792      if (hit) {
   793        return hit;
   794      }
   795      if (!tagRE.test(text)) {
   796        return null;
   797      }
   798      var tokens = [];
   799      var lastIndex = tagRE.lastIndex = 0;
   800      var match, index, html, value, first, oneTime;
   801      /* eslint-disable no-cond-assign */
   802      while (match = tagRE.exec(text)) {
   803        /* eslint-enable no-cond-assign */
   804        index = match.index;
   805        // push text token
   806        if (index > lastIndex) {
   807          tokens.push({
   808            value: text.slice(lastIndex, index)
   809          });
   810        }
   811        // tag token
   812        html = htmlRE.test(match[0]);
   813        value = html ? match[1] : match[2];
   814        first = value.charCodeAt(0);
   815        oneTime = first === 42; // *
   816        value = oneTime ? value.slice(1) : value;
   817        tokens.push({
   818          tag: true,
   819          value: value.trim(),
   820          html: html,
   821          oneTime: oneTime
   822        });
   823        lastIndex = index + match[0].length;
   824      }
   825      if (lastIndex < text.length) {
   826        tokens.push({
   827          value: text.slice(lastIndex)
   828        });
   829      }
   830      cache.put(text, tokens);
   831      return tokens;
   832    }
   833  
   834    /**
   835     * Format a list of tokens into an expression.
   836     * e.g. tokens parsed from 'a {{b}} c' can be serialized
   837     * into one single expression as '"a " + b + " c"'.
   838     *
   839     * @param {Array} tokens
   840     * @param {Vue} [vm]
   841     * @return {String}
   842     */
   843  
   844    function tokensToExp(tokens, vm) {
   845      if (tokens.length > 1) {
   846        return tokens.map(function (token) {
   847          return formatToken(token, vm);
   848        }).join('+');
   849      } else {
   850        return formatToken(tokens[0], vm, true);
   851      }
   852    }
   853  
   854    /**
   855     * Format a single token.
   856     *
   857     * @param {Object} token
   858     * @param {Vue} [vm]
   859     * @param {Boolean} [single]
   860     * @return {String}
   861     */
   862  
   863    function formatToken(token, vm, single) {
   864      return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
   865    }
   866  
   867    /**
   868     * For an attribute with multiple interpolation tags,
   869     * e.g. attr="some-{{thing | filter}}", in order to combine
   870     * the whole thing into a single watchable expression, we
   871     * have to inline those filters. This function does exactly
   872     * that. This is a bit hacky but it avoids heavy changes
   873     * to directive parser and watcher mechanism.
   874     *
   875     * @param {String} exp
   876     * @param {Boolean} single
   877     * @return {String}
   878     */
   879  
   880    var filterRE = /[^|]\|[^|]/;
   881    function inlineFilters(exp, single) {
   882      if (!filterRE.test(exp)) {
   883        return single ? exp : '(' + exp + ')';
   884      } else {
   885        var dir = parseDirective(exp);
   886        if (!dir.filters) {
   887          return '(' + exp + ')';
   888        } else {
   889          return 'this._applyFilters(' + dir.expression + // value
   890          ',null,' + // oldValue (null for read)
   891          JSON.stringify(dir.filters) + // filter descriptors
   892          ',false)'; // write?
   893        }
   894      }
   895    }
   896  
   897  var text = Object.freeze({
   898      compileRegex: compileRegex,
   899      parseText: parseText,
   900      tokensToExp: tokensToExp
   901    });
   902  
   903    var delimiters = ['{{', '}}'];
   904    var unsafeDelimiters = ['{{{', '}}}'];
   905  
   906    var config = Object.defineProperties({
   907  
   908      /**
   909       * Whether to print debug messages.
   910       * Also enables stack trace for warnings.
   911       *
   912       * @type {Boolean}
   913       */
   914  
   915      debug: false,
   916  
   917      /**
   918       * Whether to suppress warnings.
   919       *
   920       * @type {Boolean}
   921       */
   922  
   923      silent: false,
   924  
   925      /**
   926       * Whether to use async rendering.
   927       */
   928  
   929      async: true,
   930  
   931      /**
   932       * Whether to warn against errors caught when evaluating
   933       * expressions.
   934       */
   935  
   936      warnExpressionErrors: true,
   937  
   938      /**
   939       * Whether to allow devtools inspection.
   940       * Disabled by default in production builds.
   941       */
   942  
   943      devtools: 'development' !== 'production',
   944  
   945      /**
   946       * Internal flag to indicate the delimiters have been
   947       * changed.
   948       *
   949       * @type {Boolean}
   950       */
   951  
   952      _delimitersChanged: true,
   953  
   954      /**
   955       * List of asset types that a component can own.
   956       *
   957       * @type {Array}
   958       */
   959  
   960      _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
   961  
   962      /**
   963       * prop binding modes
   964       */
   965  
   966      _propBindingModes: {
   967        ONE_WAY: 0,
   968        TWO_WAY: 1,
   969        ONE_TIME: 2
   970      },
   971  
   972      /**
   973       * Max circular updates allowed in a batcher flush cycle.
   974       */
   975  
   976      _maxUpdateCount: 100
   977  
   978    }, {
   979      delimiters: { /**
   980                     * Interpolation delimiters. Changing these would trigger
   981                     * the text parser to re-compile the regular expressions.
   982                     *
   983                     * @type {Array<String>}
   984                     */
   985  
   986        get: function get() {
   987          return delimiters;
   988        },
   989        set: function set(val) {
   990          delimiters = val;
   991          compileRegex();
   992        },
   993        configurable: true,
   994        enumerable: true
   995      },
   996      unsafeDelimiters: {
   997        get: function get() {
   998          return unsafeDelimiters;
   999        },
  1000        set: function set(val) {
  1001          unsafeDelimiters = val;
  1002          compileRegex();
  1003        },
  1004        configurable: true,
  1005        enumerable: true
  1006      }
  1007    });
  1008  
  1009    var warn = undefined;
  1010    var formatComponentName = undefined;
  1011  
  1012    if ('development' !== 'production') {
  1013      (function () {
  1014        var hasConsole = typeof console !== 'undefined';
  1015  
  1016        warn = function (msg, vm) {
  1017          if (hasConsole && !config.silent) {
  1018            console.error('[Vue warn]: ' + msg + (vm ? formatComponentName(vm) : ''));
  1019          }
  1020        };
  1021  
  1022        formatComponentName = function (vm) {
  1023          var name = vm._isVue ? vm.$options.name : vm.name;
  1024          return name ? ' (found in component: <' + hyphenate(name) + '>)' : '';
  1025        };
  1026      })();
  1027    }
  1028  
  1029    /**
  1030     * Append with transition.
  1031     *
  1032     * @param {Element} el
  1033     * @param {Element} target
  1034     * @param {Vue} vm
  1035     * @param {Function} [cb]
  1036     */
  1037  
  1038    function appendWithTransition(el, target, vm, cb) {
  1039      applyTransition(el, 1, function () {
  1040        target.appendChild(el);
  1041      }, vm, cb);
  1042    }
  1043  
  1044    /**
  1045     * InsertBefore with transition.
  1046     *
  1047     * @param {Element} el
  1048     * @param {Element} target
  1049     * @param {Vue} vm
  1050     * @param {Function} [cb]
  1051     */
  1052  
  1053    function beforeWithTransition(el, target, vm, cb) {
  1054      applyTransition(el, 1, function () {
  1055        before(el, target);
  1056      }, vm, cb);
  1057    }
  1058  
  1059    /**
  1060     * Remove with transition.
  1061     *
  1062     * @param {Element} el
  1063     * @param {Vue} vm
  1064     * @param {Function} [cb]
  1065     */
  1066  
  1067    function removeWithTransition(el, vm, cb) {
  1068      applyTransition(el, -1, function () {
  1069        remove(el);
  1070      }, vm, cb);
  1071    }
  1072  
  1073    /**
  1074     * Apply transitions with an operation callback.
  1075     *
  1076     * @param {Element} el
  1077     * @param {Number} direction
  1078     *                  1: enter
  1079     *                 -1: leave
  1080     * @param {Function} op - the actual DOM operation
  1081     * @param {Vue} vm
  1082     * @param {Function} [cb]
  1083     */
  1084  
  1085    function applyTransition(el, direction, op, vm, cb) {
  1086      var transition = el.__v_trans;
  1087      if (!transition ||
  1088      // skip if there are no js hooks and CSS transition is
  1089      // not supported
  1090      !transition.hooks && !transitionEndEvent ||
  1091      // skip transitions for initial compile
  1092      !vm._isCompiled ||
  1093      // if the vm is being manipulated by a parent directive
  1094      // during the parent's compilation phase, skip the
  1095      // animation.
  1096      vm.$parent && !vm.$parent._isCompiled) {
  1097        op();
  1098        if (cb) cb();
  1099        return;
  1100      }
  1101      var action = direction > 0 ? 'enter' : 'leave';
  1102      transition[action](op, cb);
  1103    }
  1104  
  1105  var transition = Object.freeze({
  1106      appendWithTransition: appendWithTransition,
  1107      beforeWithTransition: beforeWithTransition,
  1108      removeWithTransition: removeWithTransition,
  1109      applyTransition: applyTransition
  1110    });
  1111  
  1112    /**
  1113     * Query an element selector if it's not an element already.
  1114     *
  1115     * @param {String|Element} el
  1116     * @return {Element}
  1117     */
  1118  
  1119    function query(el) {
  1120      if (typeof el === 'string') {
  1121        var selector = el;
  1122        el = document.querySelector(el);
  1123        if (!el) {
  1124          'development' !== 'production' && warn('Cannot find element: ' + selector);
  1125        }
  1126      }
  1127      return el;
  1128    }
  1129  
  1130    /**
  1131     * Check if a node is in the document.
  1132     * Note: document.documentElement.contains should work here
  1133     * but always returns false for comment nodes in phantomjs,
  1134     * making unit tests difficult. This is fixed by doing the
  1135     * contains() check on the node's parentNode instead of
  1136     * the node itself.
  1137     *
  1138     * @param {Node} node
  1139     * @return {Boolean}
  1140     */
  1141  
  1142    function inDoc(node) {
  1143      if (!node) return false;
  1144      var doc = node.ownerDocument.documentElement;
  1145      var parent = node.parentNode;
  1146      return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
  1147    }
  1148  
  1149    /**
  1150     * Get and remove an attribute from a node.
  1151     *
  1152     * @param {Node} node
  1153     * @param {String} _attr
  1154     */
  1155  
  1156    function getAttr(node, _attr) {
  1157      var val = node.getAttribute(_attr);
  1158      if (val !== null) {
  1159        node.removeAttribute(_attr);
  1160      }
  1161      return val;
  1162    }
  1163  
  1164    /**
  1165     * Get an attribute with colon or v-bind: prefix.
  1166     *
  1167     * @param {Node} node
  1168     * @param {String} name
  1169     * @return {String|null}
  1170     */
  1171  
  1172    function getBindAttr(node, name) {
  1173      var val = getAttr(node, ':' + name);
  1174      if (val === null) {
  1175        val = getAttr(node, 'v-bind:' + name);
  1176      }
  1177      return val;
  1178    }
  1179  
  1180    /**
  1181     * Check the presence of a bind attribute.
  1182     *
  1183     * @param {Node} node
  1184     * @param {String} name
  1185     * @return {Boolean}
  1186     */
  1187  
  1188    function hasBindAttr(node, name) {
  1189      return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
  1190    }
  1191  
  1192    /**
  1193     * Insert el before target
  1194     *
  1195     * @param {Element} el
  1196     * @param {Element} target
  1197     */
  1198  
  1199    function before(el, target) {
  1200      target.parentNode.insertBefore(el, target);
  1201    }
  1202  
  1203    /**
  1204     * Insert el after target
  1205     *
  1206     * @param {Element} el
  1207     * @param {Element} target
  1208     */
  1209  
  1210    function after(el, target) {
  1211      if (target.nextSibling) {
  1212        before(el, target.nextSibling);
  1213      } else {
  1214        target.parentNode.appendChild(el);
  1215      }
  1216    }
  1217  
  1218    /**
  1219     * Remove el from DOM
  1220     *
  1221     * @param {Element} el
  1222     */
  1223  
  1224    function remove(el) {
  1225      el.parentNode.removeChild(el);
  1226    }
  1227  
  1228    /**
  1229     * Prepend el to target
  1230     *
  1231     * @param {Element} el
  1232     * @param {Element} target
  1233     */
  1234  
  1235    function prepend(el, target) {
  1236      if (target.firstChild) {
  1237        before(el, target.firstChild);
  1238      } else {
  1239        target.appendChild(el);
  1240      }
  1241    }
  1242  
  1243    /**
  1244     * Replace target with el
  1245     *
  1246     * @param {Element} target
  1247     * @param {Element} el
  1248     */
  1249  
  1250    function replace(target, el) {
  1251      var parent = target.parentNode;
  1252      if (parent) {
  1253        parent.replaceChild(el, target);
  1254      }
  1255    }
  1256  
  1257    /**
  1258     * Add event listener shorthand.
  1259     *
  1260     * @param {Element} el
  1261     * @param {String} event
  1262     * @param {Function} cb
  1263     * @param {Boolean} [useCapture]
  1264     */
  1265  
  1266    function on(el, event, cb, useCapture) {
  1267      el.addEventListener(event, cb, useCapture);
  1268    }
  1269  
  1270    /**
  1271     * Remove event listener shorthand.
  1272     *
  1273     * @param {Element} el
  1274     * @param {String} event
  1275     * @param {Function} cb
  1276     */
  1277  
  1278    function off(el, event, cb) {
  1279      el.removeEventListener(event, cb);
  1280    }
  1281  
  1282    /**
  1283     * For IE9 compat: when both class and :class are present
  1284     * getAttribute('class') returns wrong value...
  1285     *
  1286     * @param {Element} el
  1287     * @return {String}
  1288     */
  1289  
  1290    function getClass(el) {
  1291      var classname = el.className;
  1292      if (typeof classname === 'object') {
  1293        classname = classname.baseVal || '';
  1294      }
  1295      return classname;
  1296    }
  1297  
  1298    /**
  1299     * In IE9, setAttribute('class') will result in empty class
  1300     * if the element also has the :class attribute; However in
  1301     * PhantomJS, setting `className` does not work on SVG elements...
  1302     * So we have to do a conditional check here.
  1303     *
  1304     * @param {Element} el
  1305     * @param {String} cls
  1306     */
  1307  
  1308    function setClass(el, cls) {
  1309      /* istanbul ignore if */
  1310      if (isIE9 && !/svg$/.test(el.namespaceURI)) {
  1311        el.className = cls;
  1312      } else {
  1313        el.setAttribute('class', cls);
  1314      }
  1315    }
  1316  
  1317    /**
  1318     * Add class with compatibility for IE & SVG
  1319     *
  1320     * @param {Element} el
  1321     * @param {String} cls
  1322     */
  1323  
  1324    function addClass(el, cls) {
  1325      if (el.classList) {
  1326        el.classList.add(cls);
  1327      } else {
  1328        var cur = ' ' + getClass(el) + ' ';
  1329        if (cur.indexOf(' ' + cls + ' ') < 0) {
  1330          setClass(el, (cur + cls).trim());
  1331        }
  1332      }
  1333    }
  1334  
  1335    /**
  1336     * Remove class with compatibility for IE & SVG
  1337     *
  1338     * @param {Element} el
  1339     * @param {String} cls
  1340     */
  1341  
  1342    function removeClass(el, cls) {
  1343      if (el.classList) {
  1344        el.classList.remove(cls);
  1345      } else {
  1346        var cur = ' ' + getClass(el) + ' ';
  1347        var tar = ' ' + cls + ' ';
  1348        while (cur.indexOf(tar) >= 0) {
  1349          cur = cur.replace(tar, ' ');
  1350        }
  1351        setClass(el, cur.trim());
  1352      }
  1353      if (!el.className) {
  1354        el.removeAttribute('class');
  1355      }
  1356    }
  1357  
  1358    /**
  1359     * Extract raw content inside an element into a temporary
  1360     * container div
  1361     *
  1362     * @param {Element} el
  1363     * @param {Boolean} asFragment
  1364     * @return {Element|DocumentFragment}
  1365     */
  1366  
  1367    function extractContent(el, asFragment) {
  1368      var child;
  1369      var rawContent;
  1370      /* istanbul ignore if */
  1371      if (isTemplate(el) && isFragment(el.content)) {
  1372        el = el.content;
  1373      }
  1374      if (el.hasChildNodes()) {
  1375        trimNode(el);
  1376        rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
  1377        /* eslint-disable no-cond-assign */
  1378        while (child = el.firstChild) {
  1379          /* eslint-enable no-cond-assign */
  1380          rawContent.appendChild(child);
  1381        }
  1382      }
  1383      return rawContent;
  1384    }
  1385  
  1386    /**
  1387     * Trim possible empty head/tail text and comment
  1388     * nodes inside a parent.
  1389     *
  1390     * @param {Node} node
  1391     */
  1392  
  1393    function trimNode(node) {
  1394      var child;
  1395      /* eslint-disable no-sequences */
  1396      while ((child = node.firstChild, isTrimmable(child))) {
  1397        node.removeChild(child);
  1398      }
  1399      while ((child = node.lastChild, isTrimmable(child))) {
  1400        node.removeChild(child);
  1401      }
  1402      /* eslint-enable no-sequences */
  1403    }
  1404  
  1405    function isTrimmable(node) {
  1406      return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
  1407    }
  1408  
  1409    /**
  1410     * Check if an element is a template tag.
  1411     * Note if the template appears inside an SVG its tagName
  1412     * will be in lowercase.
  1413     *
  1414     * @param {Element} el
  1415     */
  1416  
  1417    function isTemplate(el) {
  1418      return el.tagName && el.tagName.toLowerCase() === 'template';
  1419    }
  1420  
  1421    /**
  1422     * Create an "anchor" for performing dom insertion/removals.
  1423     * This is used in a number of scenarios:
  1424     * - fragment instance
  1425     * - v-html
  1426     * - v-if
  1427     * - v-for
  1428     * - component
  1429     *
  1430     * @param {String} content
  1431     * @param {Boolean} persist - IE trashes empty textNodes on
  1432     *                            cloneNode(true), so in certain
  1433     *                            cases the anchor needs to be
  1434     *                            non-empty to be persisted in
  1435     *                            templates.
  1436     * @return {Comment|Text}
  1437     */
  1438  
  1439    function createAnchor(content, persist) {
  1440      var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
  1441      anchor.__v_anchor = true;
  1442      return anchor;
  1443    }
  1444  
  1445    /**
  1446     * Find a component ref attribute that starts with $.
  1447     *
  1448     * @param {Element} node
  1449     * @return {String|undefined}
  1450     */
  1451  
  1452    var refRE = /^v-ref:/;
  1453  
  1454    function findRef(node) {
  1455      if (node.hasAttributes()) {
  1456        var attrs = node.attributes;
  1457        for (var i = 0, l = attrs.length; i < l; i++) {
  1458          var name = attrs[i].name;
  1459          if (refRE.test(name)) {
  1460            return camelize(name.replace(refRE, ''));
  1461          }
  1462        }
  1463      }
  1464    }
  1465  
  1466    /**
  1467     * Map a function to a range of nodes .
  1468     *
  1469     * @param {Node} node
  1470     * @param {Node} end
  1471     * @param {Function} op
  1472     */
  1473  
  1474    function mapNodeRange(node, end, op) {
  1475      var next;
  1476      while (node !== end) {
  1477        next = node.nextSibling;
  1478        op(node);
  1479        node = next;
  1480      }
  1481      op(end);
  1482    }
  1483  
  1484    /**
  1485     * Remove a range of nodes with transition, store
  1486     * the nodes in a fragment with correct ordering,
  1487     * and call callback when done.
  1488     *
  1489     * @param {Node} start
  1490     * @param {Node} end
  1491     * @param {Vue} vm
  1492     * @param {DocumentFragment} frag
  1493     * @param {Function} cb
  1494     */
  1495  
  1496    function removeNodeRange(start, end, vm, frag, cb) {
  1497      var done = false;
  1498      var removed = 0;
  1499      var nodes = [];
  1500      mapNodeRange(start, end, function (node) {
  1501        if (node === end) done = true;
  1502        nodes.push(node);
  1503        removeWithTransition(node, vm, onRemoved);
  1504      });
  1505      function onRemoved() {
  1506        removed++;
  1507        if (done && removed >= nodes.length) {
  1508          for (var i = 0; i < nodes.length; i++) {
  1509            frag.appendChild(nodes[i]);
  1510          }
  1511          cb && cb();
  1512        }
  1513      }
  1514    }
  1515  
  1516    /**
  1517     * Check if a node is a DocumentFragment.
  1518     *
  1519     * @param {Node} node
  1520     * @return {Boolean}
  1521     */
  1522  
  1523    function isFragment(node) {
  1524      return node && node.nodeType === 11;
  1525    }
  1526  
  1527    /**
  1528     * Get outerHTML of elements, taking care
  1529     * of SVG elements in IE as well.
  1530     *
  1531     * @param {Element} el
  1532     * @return {String}
  1533     */
  1534  
  1535    function getOuterHTML(el) {
  1536      if (el.outerHTML) {
  1537        return el.outerHTML;
  1538      } else {
  1539        var container = document.createElement('div');
  1540        container.appendChild(el.cloneNode(true));
  1541        return container.innerHTML;
  1542      }
  1543    }
  1544  
  1545    var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i;
  1546    var reservedTagRE = /^(slot|partial|component)$/i;
  1547  
  1548    var isUnknownElement = undefined;
  1549    if ('development' !== 'production') {
  1550      isUnknownElement = function (el, tag) {
  1551        if (tag.indexOf('-') > -1) {
  1552          // http://stackoverflow.com/a/28210364/1070244
  1553          return el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement;
  1554        } else {
  1555          return (/HTMLUnknownElement/.test(el.toString()) &&
  1556            // Chrome returns unknown for several HTML5 elements.
  1557            // https://code.google.com/p/chromium/issues/detail?id=540526
  1558            !/^(data|time|rtc|rb)$/.test(tag)
  1559          );
  1560        }
  1561      };
  1562    }
  1563  
  1564    /**
  1565     * Check if an element is a component, if yes return its
  1566     * component id.
  1567     *
  1568     * @param {Element} el
  1569     * @param {Object} options
  1570     * @return {Object|undefined}
  1571     */
  1572  
  1573    function checkComponentAttr(el, options) {
  1574      var tag = el.tagName.toLowerCase();
  1575      var hasAttrs = el.hasAttributes();
  1576      if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
  1577        if (resolveAsset(options, 'components', tag)) {
  1578          return { id: tag };
  1579        } else {
  1580          var is = hasAttrs && getIsBinding(el, options);
  1581          if (is) {
  1582            return is;
  1583          } else if ('development' !== 'production') {
  1584            var expectedTag = options._componentNameMap && options._componentNameMap[tag];
  1585            if (expectedTag) {
  1586              warn('Unknown custom element: <' + tag + '> - ' + 'did you mean <' + expectedTag + '>? ' + 'HTML is case-insensitive, remember to use kebab-case in templates.');
  1587            } else if (isUnknownElement(el, tag)) {
  1588              warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
  1589            }
  1590          }
  1591        }
  1592      } else if (hasAttrs) {
  1593        return getIsBinding(el, options);
  1594      }
  1595    }
  1596  
  1597    /**
  1598     * Get "is" binding from an element.
  1599     *
  1600     * @param {Element} el
  1601     * @param {Object} options
  1602     * @return {Object|undefined}
  1603     */
  1604  
  1605    function getIsBinding(el, options) {
  1606      // dynamic syntax
  1607      var exp = el.getAttribute('is');
  1608      if (exp != null) {
  1609        if (resolveAsset(options, 'components', exp)) {
  1610          el.removeAttribute('is');
  1611          return { id: exp };
  1612        }
  1613      } else {
  1614        exp = getBindAttr(el, 'is');
  1615        if (exp != null) {
  1616          return { id: exp, dynamic: true };
  1617        }
  1618      }
  1619    }
  1620  
  1621    /**
  1622     * Option overwriting strategies are functions that handle
  1623     * how to merge a parent option value and a child option
  1624     * value into the final value.
  1625     *
  1626     * All strategy functions follow the same signature:
  1627     *
  1628     * @param {*} parentVal
  1629     * @param {*} childVal
  1630     * @param {Vue} [vm]
  1631     */
  1632  
  1633    var strats = config.optionMergeStrategies = Object.create(null);
  1634  
  1635    /**
  1636     * Helper that recursively merges two data objects together.
  1637     */
  1638  
  1639    function mergeData(to, from) {
  1640      var key, toVal, fromVal;
  1641      for (key in from) {
  1642        toVal = to[key];
  1643        fromVal = from[key];
  1644        if (!hasOwn(to, key)) {
  1645          set(to, key, fromVal);
  1646        } else if (isObject(toVal) && isObject(fromVal)) {
  1647          mergeData(toVal, fromVal);
  1648        }
  1649      }
  1650      return to;
  1651    }
  1652  
  1653    /**
  1654     * Data
  1655     */
  1656  
  1657    strats.data = function (parentVal, childVal, vm) {
  1658      if (!vm) {
  1659        // in a Vue.extend merge, both should be functions
  1660        if (!childVal) {
  1661          return parentVal;
  1662        }
  1663        if (typeof childVal !== 'function') {
  1664          'development' !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
  1665          return parentVal;
  1666        }
  1667        if (!parentVal) {
  1668          return childVal;
  1669        }
  1670        // when parentVal & childVal are both present,
  1671        // we need to return a function that returns the
  1672        // merged result of both functions... no need to
  1673        // check if parentVal is a function here because
  1674        // it has to be a function to pass previous merges.
  1675        return function mergedDataFn() {
  1676          return mergeData(childVal.call(this), parentVal.call(this));
  1677        };
  1678      } else if (parentVal || childVal) {
  1679        return function mergedInstanceDataFn() {
  1680          // instance merge
  1681          var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal;
  1682          var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined;
  1683          if (instanceData) {
  1684            return mergeData(instanceData, defaultData);
  1685          } else {
  1686            return defaultData;
  1687          }
  1688        };
  1689      }
  1690    };
  1691  
  1692    /**
  1693     * El
  1694     */
  1695  
  1696    strats.el = function (parentVal, childVal, vm) {
  1697      if (!vm && childVal && typeof childVal !== 'function') {
  1698        'development' !== 'production' && warn('The "el" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
  1699        return;
  1700      }
  1701      var ret = childVal || parentVal;
  1702      // invoke the element factory if this is instance merge
  1703      return vm && typeof ret === 'function' ? ret.call(vm) : ret;
  1704    };
  1705  
  1706    /**
  1707     * Hooks and param attributes are merged as arrays.
  1708     */
  1709  
  1710    strats.init = strats.created = strats.ready = strats.attached = strats.detached = strats.beforeCompile = strats.compiled = strats.beforeDestroy = strats.destroyed = strats.activate = function (parentVal, childVal) {
  1711      return childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
  1712    };
  1713  
  1714    /**
  1715     * Assets
  1716     *
  1717     * When a vm is present (instance creation), we need to do
  1718     * a three-way merge between constructor options, instance
  1719     * options and parent options.
  1720     */
  1721  
  1722    function mergeAssets(parentVal, childVal) {
  1723      var res = Object.create(parentVal || null);
  1724      return childVal ? extend(res, guardArrayAssets(childVal)) : res;
  1725    }
  1726  
  1727    config._assetTypes.forEach(function (type) {
  1728      strats[type + 's'] = mergeAssets;
  1729    });
  1730  
  1731    /**
  1732     * Events & Watchers.
  1733     *
  1734     * Events & watchers hashes should not overwrite one
  1735     * another, so we merge them as arrays.
  1736     */
  1737  
  1738    strats.watch = strats.events = function (parentVal, childVal) {
  1739      if (!childVal) return parentVal;
  1740      if (!parentVal) return childVal;
  1741      var ret = {};
  1742      extend(ret, parentVal);
  1743      for (var key in childVal) {
  1744        var parent = ret[key];
  1745        var child = childVal[key];
  1746        if (parent && !isArray(parent)) {
  1747          parent = [parent];
  1748        }
  1749        ret[key] = parent ? parent.concat(child) : [child];
  1750      }
  1751      return ret;
  1752    };
  1753  
  1754    /**
  1755     * Other object hashes.
  1756     */
  1757  
  1758    strats.props = strats.methods = strats.computed = function (parentVal, childVal) {
  1759      if (!childVal) return parentVal;
  1760      if (!parentVal) return childVal;
  1761      var ret = Object.create(null);
  1762      extend(ret, parentVal);
  1763      extend(ret, childVal);
  1764      return ret;
  1765    };
  1766  
  1767    /**
  1768     * Default strategy.
  1769     */
  1770  
  1771    var defaultStrat = function defaultStrat(parentVal, childVal) {
  1772      return childVal === undefined ? parentVal : childVal;
  1773    };
  1774  
  1775    /**
  1776     * Make sure component options get converted to actual
  1777     * constructors.
  1778     *
  1779     * @param {Object} options
  1780     */
  1781  
  1782    function guardComponents(options) {
  1783      if (options.components) {
  1784        var components = options.components = guardArrayAssets(options.components);
  1785        var ids = Object.keys(components);
  1786        var def;
  1787        if ('development' !== 'production') {
  1788          var map = options._componentNameMap = {};
  1789        }
  1790        for (var i = 0, l = ids.length; i < l; i++) {
  1791          var key = ids[i];
  1792          if (commonTagRE.test(key) || reservedTagRE.test(key)) {
  1793            'development' !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
  1794            continue;
  1795          }
  1796          // record a all lowercase <-> kebab-case mapping for
  1797          // possible custom element case error warning
  1798          if ('development' !== 'production') {
  1799            map[key.replace(/-/g, '').toLowerCase()] = hyphenate(key);
  1800          }
  1801          def = components[key];
  1802          if (isPlainObject(def)) {
  1803            components[key] = Vue.extend(def);
  1804          }
  1805        }
  1806      }
  1807    }
  1808  
  1809    /**
  1810     * Ensure all props option syntax are normalized into the
  1811     * Object-based format.
  1812     *
  1813     * @param {Object} options
  1814     */
  1815  
  1816    function guardProps(options) {
  1817      var props = options.props;
  1818      var i, val;
  1819      if (isArray(props)) {
  1820        options.props = {};
  1821        i = props.length;
  1822        while (i--) {
  1823          val = props[i];
  1824          if (typeof val === 'string') {
  1825            options.props[val] = null;
  1826          } else if (val.name) {
  1827            options.props[val.name] = val;
  1828          }
  1829        }
  1830      } else if (isPlainObject(props)) {
  1831        var keys = Object.keys(props);
  1832        i = keys.length;
  1833        while (i--) {
  1834          val = props[keys[i]];
  1835          if (typeof val === 'function') {
  1836            props[keys[i]] = { type: val };
  1837          }
  1838        }
  1839      }
  1840    }
  1841  
  1842    /**
  1843     * Guard an Array-format assets option and converted it
  1844     * into the key-value Object format.
  1845     *
  1846     * @param {Object|Array} assets
  1847     * @return {Object}
  1848     */
  1849  
  1850    function guardArrayAssets(assets) {
  1851      if (isArray(assets)) {
  1852        var res = {};
  1853        var i = assets.length;
  1854        var asset;
  1855        while (i--) {
  1856          asset = assets[i];
  1857          var id = typeof asset === 'function' ? asset.options && asset.options.name || asset.id : asset.name || asset.id;
  1858          if (!id) {
  1859            'development' !== 'production' && warn('Array-syntax assets must provide a "name" or "id" field.');
  1860          } else {
  1861            res[id] = asset;
  1862          }
  1863        }
  1864        return res;
  1865      }
  1866      return assets;
  1867    }
  1868  
  1869    /**
  1870     * Merge two option objects into a new one.
  1871     * Core utility used in both instantiation and inheritance.
  1872     *
  1873     * @param {Object} parent
  1874     * @param {Object} child
  1875     * @param {Vue} [vm] - if vm is present, indicates this is
  1876     *                     an instantiation merge.
  1877     */
  1878  
  1879    function mergeOptions(parent, child, vm) {
  1880      guardComponents(child);
  1881      guardProps(child);
  1882      if ('development' !== 'production') {
  1883        if (child.propsData && !vm) {
  1884          warn('propsData can only be used as an instantiation option.');
  1885        }
  1886      }
  1887      var options = {};
  1888      var key;
  1889      if (child['extends']) {
  1890        parent = typeof child['extends'] === 'function' ? mergeOptions(parent, child['extends'].options, vm) : mergeOptions(parent, child['extends'], vm);
  1891      }
  1892      if (child.mixins) {
  1893        for (var i = 0, l = child.mixins.length; i < l; i++) {
  1894          parent = mergeOptions(parent, child.mixins[i], vm);
  1895        }
  1896      }
  1897      for (key in parent) {
  1898        mergeField(key);
  1899      }
  1900      for (key in child) {
  1901        if (!hasOwn(parent, key)) {
  1902          mergeField(key);
  1903        }
  1904      }
  1905      function mergeField(key) {
  1906        var strat = strats[key] || defaultStrat;
  1907        options[key] = strat(parent[key], child[key], vm, key);
  1908      }
  1909      return options;
  1910    }
  1911  
  1912    /**
  1913     * Resolve an asset.
  1914     * This function is used because child instances need access
  1915     * to assets defined in its ancestor chain.
  1916     *
  1917     * @param {Object} options
  1918     * @param {String} type
  1919     * @param {String} id
  1920     * @param {Boolean} warnMissing
  1921     * @return {Object|Function}
  1922     */
  1923  
  1924    function resolveAsset(options, type, id, warnMissing) {
  1925      /* istanbul ignore if */
  1926      if (typeof id !== 'string') {
  1927        return;
  1928      }
  1929      var assets = options[type];
  1930      var camelizedId;
  1931      var res = assets[id] ||
  1932      // camelCase ID
  1933      assets[camelizedId = camelize(id)] ||
  1934      // Pascal Case ID
  1935      assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)];
  1936      if ('development' !== 'production' && warnMissing && !res) {
  1937        warn('Failed to resolve ' + type.slice(0, -1) + ': ' + id, options);
  1938      }
  1939      return res;
  1940    }
  1941  
  1942    var uid$1 = 0;
  1943  
  1944    /**
  1945     * A dep is an observable that can have multiple
  1946     * directives subscribing to it.
  1947     *
  1948     * @constructor
  1949     */
  1950    function Dep() {
  1951      this.id = uid$1++;
  1952      this.subs = [];
  1953    }
  1954  
  1955    // the current target watcher being evaluated.
  1956    // this is globally unique because there could be only one
  1957    // watcher being evaluated at any time.
  1958    Dep.target = null;
  1959  
  1960    /**
  1961     * Add a directive subscriber.
  1962     *
  1963     * @param {Directive} sub
  1964     */
  1965  
  1966    Dep.prototype.addSub = function (sub) {
  1967      this.subs.push(sub);
  1968    };
  1969  
  1970    /**
  1971     * Remove a directive subscriber.
  1972     *
  1973     * @param {Directive} sub
  1974     */
  1975  
  1976    Dep.prototype.removeSub = function (sub) {
  1977      this.subs.$remove(sub);
  1978    };
  1979  
  1980    /**
  1981     * Add self as a dependency to the target watcher.
  1982     */
  1983  
  1984    Dep.prototype.depend = function () {
  1985      Dep.target.addDep(this);
  1986    };
  1987  
  1988    /**
  1989     * Notify all subscribers of a new value.
  1990     */
  1991  
  1992    Dep.prototype.notify = function () {
  1993      // stablize the subscriber list first
  1994      var subs = toArray(this.subs);
  1995      for (var i = 0, l = subs.length; i < l; i++) {
  1996        subs[i].update();
  1997      }
  1998    };
  1999  
  2000    var arrayProto = Array.prototype;
  2001    var arrayMethods = Object.create(arrayProto)
  2002  
  2003    /**
  2004     * Intercept mutating methods and emit events
  2005     */
  2006  
  2007    ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
  2008      // cache original method
  2009      var original = arrayProto[method];
  2010      def(arrayMethods, method, function mutator() {
  2011        // avoid leaking arguments:
  2012        // http://jsperf.com/closure-with-arguments
  2013        var i = arguments.length;
  2014        var args = new Array(i);
  2015        while (i--) {
  2016          args[i] = arguments[i];
  2017        }
  2018        var result = original.apply(this, args);
  2019        var ob = this.__ob__;
  2020        var inserted;
  2021        switch (method) {
  2022          case 'push':
  2023            inserted = args;
  2024            break;
  2025          case 'unshift':
  2026            inserted = args;
  2027            break;
  2028          case 'splice':
  2029            inserted = args.slice(2);
  2030            break;
  2031        }
  2032        if (inserted) ob.observeArray(inserted);
  2033        // notify change
  2034        ob.dep.notify();
  2035        return result;
  2036      });
  2037    });
  2038  
  2039    /**
  2040     * Swap the element at the given index with a new value
  2041     * and emits corresponding event.
  2042     *
  2043     * @param {Number} index
  2044     * @param {*} val
  2045     * @return {*} - replaced element
  2046     */
  2047  
  2048    def(arrayProto, '$set', function $set(index, val) {
  2049      if (index >= this.length) {
  2050        this.length = Number(index) + 1;
  2051      }
  2052      return this.splice(index, 1, val)[0];
  2053    });
  2054  
  2055    /**
  2056     * Convenience method to remove the element at given index or target element reference.
  2057     *
  2058     * @param {*} item
  2059     */
  2060  
  2061    def(arrayProto, '$remove', function $remove(item) {
  2062      /* istanbul ignore if */
  2063      if (!this.length) return;
  2064      var index = indexOf(this, item);
  2065      if (index > -1) {
  2066        return this.splice(index, 1);
  2067      }
  2068    });
  2069  
  2070    var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
  2071  
  2072    /**
  2073     * By default, when a reactive property is set, the new value is
  2074     * also converted to become reactive. However in certain cases, e.g.
  2075     * v-for scope alias and props, we don't want to force conversion
  2076     * because the value may be a nested value under a frozen data structure.
  2077     *
  2078     * So whenever we want to set a reactive property without forcing
  2079     * conversion on the new value, we wrap that call inside this function.
  2080     */
  2081  
  2082    var shouldConvert = true;
  2083  
  2084    function withoutConversion(fn) {
  2085      shouldConvert = false;
  2086      fn();
  2087      shouldConvert = true;
  2088    }
  2089  
  2090    /**
  2091     * Observer class that are attached to each observed
  2092     * object. Once attached, the observer converts target
  2093     * object's property keys into getter/setters that
  2094     * collect dependencies and dispatches updates.
  2095     *
  2096     * @param {Array|Object} value
  2097     * @constructor
  2098     */
  2099  
  2100    function Observer(value) {
  2101      this.value = value;
  2102      this.dep = new Dep();
  2103      def(value, '__ob__', this);
  2104      if (isArray(value)) {
  2105        var augment = hasProto ? protoAugment : copyAugment;
  2106        augment(value, arrayMethods, arrayKeys);
  2107        this.observeArray(value);
  2108      } else {
  2109        this.walk(value);
  2110      }
  2111    }
  2112  
  2113    // Instance methods
  2114  
  2115    /**
  2116     * Walk through each property and convert them into
  2117     * getter/setters. This method should only be called when
  2118     * value type is Object.
  2119     *
  2120     * @param {Object} obj
  2121     */
  2122  
  2123    Observer.prototype.walk = function (obj) {
  2124      var keys = Object.keys(obj);
  2125      for (var i = 0, l = keys.length; i < l; i++) {
  2126        this.convert(keys[i], obj[keys[i]]);
  2127      }
  2128    };
  2129  
  2130    /**
  2131     * Observe a list of Array items.
  2132     *
  2133     * @param {Array} items
  2134     */
  2135  
  2136    Observer.prototype.observeArray = function (items) {
  2137      for (var i = 0, l = items.length; i < l; i++) {
  2138        observe(items[i]);
  2139      }
  2140    };
  2141  
  2142    /**
  2143     * Convert a property into getter/setter so we can emit
  2144     * the events when the property is accessed/changed.
  2145     *
  2146     * @param {String} key
  2147     * @param {*} val
  2148     */
  2149  
  2150    Observer.prototype.convert = function (key, val) {
  2151      defineReactive(this.value, key, val);
  2152    };
  2153  
  2154    /**
  2155     * Add an owner vm, so that when $set/$delete mutations
  2156     * happen we can notify owner vms to proxy the keys and
  2157     * digest the watchers. This is only called when the object
  2158     * is observed as an instance's root $data.
  2159     *
  2160     * @param {Vue} vm
  2161     */
  2162  
  2163    Observer.prototype.addVm = function (vm) {
  2164      (this.vms || (this.vms = [])).push(vm);
  2165    };
  2166  
  2167    /**
  2168     * Remove an owner vm. This is called when the object is
  2169     * swapped out as an instance's $data object.
  2170     *
  2171     * @param {Vue} vm
  2172     */
  2173  
  2174    Observer.prototype.removeVm = function (vm) {
  2175      this.vms.$remove(vm);
  2176    };
  2177  
  2178    // helpers
  2179  
  2180    /**
  2181     * Augment an target Object or Array by intercepting
  2182     * the prototype chain using __proto__
  2183     *
  2184     * @param {Object|Array} target
  2185     * @param {Object} src
  2186     */
  2187  
  2188    function protoAugment(target, src) {
  2189      /* eslint-disable no-proto */
  2190      target.__proto__ = src;
  2191      /* eslint-enable no-proto */
  2192    }
  2193  
  2194    /**
  2195     * Augment an target Object or Array by defining
  2196     * hidden properties.
  2197     *
  2198     * @param {Object|Array} target
  2199     * @param {Object} proto
  2200     */
  2201  
  2202    function copyAugment(target, src, keys) {
  2203      for (var i = 0, l = keys.length; i < l; i++) {
  2204        var key = keys[i];
  2205        def(target, key, src[key]);
  2206      }
  2207    }
  2208  
  2209    /**
  2210     * Attempt to create an observer instance for a value,
  2211     * returns the new observer if successfully observed,
  2212     * or the existing observer if the value already has one.
  2213     *
  2214     * @param {*} value
  2215     * @param {Vue} [vm]
  2216     * @return {Observer|undefined}
  2217     * @static
  2218     */
  2219  
  2220    function observe(value, vm) {
  2221      if (!value || typeof value !== 'object') {
  2222        return;
  2223      }
  2224      var ob;
  2225      if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
  2226        ob = value.__ob__;
  2227      } else if (shouldConvert && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
  2228        ob = new Observer(value);
  2229      }
  2230      if (ob && vm) {
  2231        ob.addVm(vm);
  2232      }
  2233      return ob;
  2234    }
  2235  
  2236    /**
  2237     * Define a reactive property on an Object.
  2238     *
  2239     * @param {Object} obj
  2240     * @param {String} key
  2241     * @param {*} val
  2242     */
  2243  
  2244    function defineReactive(obj, key, val) {
  2245      var dep = new Dep();
  2246  
  2247      var property = Object.getOwnPropertyDescriptor(obj, key);
  2248      if (property && property.configurable === false) {
  2249        return;
  2250      }
  2251  
  2252      // cater for pre-defined getter/setters
  2253      var getter = property && property.get;
  2254      var setter = property && property.set;
  2255  
  2256      var childOb = observe(val);
  2257      Object.defineProperty(obj, key, {
  2258        enumerable: true,
  2259        configurable: true,
  2260        get: function reactiveGetter() {
  2261          var value = getter ? getter.call(obj) : val;
  2262          if (Dep.target) {
  2263            dep.depend();
  2264            if (childOb) {
  2265              childOb.dep.depend();
  2266            }
  2267            if (isArray(value)) {
  2268              for (var e, i = 0, l = value.length; i < l; i++) {
  2269                e = value[i];
  2270                e && e.__ob__ && e.__ob__.dep.depend();
  2271              }
  2272            }
  2273          }
  2274          return value;
  2275        },
  2276        set: function reactiveSetter(newVal) {
  2277          var value = getter ? getter.call(obj) : val;
  2278          if (newVal === value) {
  2279            return;
  2280          }
  2281          if (setter) {
  2282            setter.call(obj, newVal);
  2283          } else {
  2284            val = newVal;
  2285          }
  2286          childOb = observe(newVal);
  2287          dep.notify();
  2288        }
  2289      });
  2290    }
  2291  
  2292  
  2293  
  2294    var util = Object.freeze({
  2295    	defineReactive: defineReactive,
  2296    	set: set,
  2297    	del: del,
  2298    	hasOwn: hasOwn,
  2299    	isLiteral: isLiteral,
  2300    	isReserved: isReserved,
  2301    	_toString: _toString,
  2302    	toNumber: toNumber,
  2303    	toBoolean: toBoolean,
  2304    	stripQuotes: stripQuotes,
  2305    	camelize: camelize,
  2306    	hyphenate: hyphenate,
  2307    	classify: classify,
  2308    	bind: bind,
  2309    	toArray: toArray,
  2310    	extend: extend,
  2311    	isObject: isObject,
  2312    	isPlainObject: isPlainObject,
  2313    	def: def,
  2314    	debounce: _debounce,
  2315    	indexOf: indexOf,
  2316    	cancellable: cancellable,
  2317    	looseEqual: looseEqual,
  2318    	isArray: isArray,
  2319    	hasProto: hasProto,
  2320    	inBrowser: inBrowser,
  2321    	devtools: devtools,
  2322    	isIE9: isIE9,
  2323    	isAndroid: isAndroid,
  2324    	isIos: isIos,
  2325    	isWechat: isWechat,
  2326    	get transitionProp () { return transitionProp; },
  2327    	get transitionEndEvent () { return transitionEndEvent; },
  2328    	get animationProp () { return animationProp; },
  2329    	get animationEndEvent () { return animationEndEvent; },
  2330    	nextTick: nextTick,
  2331    	get _Set () { return _Set; },
  2332    	query: query,
  2333    	inDoc: inDoc,
  2334    	getAttr: getAttr,
  2335    	getBindAttr: getBindAttr,
  2336    	hasBindAttr: hasBindAttr,
  2337    	before: before,
  2338    	after: after,
  2339    	remove: remove,
  2340    	prepend: prepend,
  2341    	replace: replace,
  2342    	on: on,
  2343    	off: off,
  2344    	setClass: setClass,
  2345    	addClass: addClass,
  2346    	removeClass: removeClass,
  2347    	extractContent: extractContent,
  2348    	trimNode: trimNode,
  2349    	isTemplate: isTemplate,
  2350    	createAnchor: createAnchor,
  2351    	findRef: findRef,
  2352    	mapNodeRange: mapNodeRange,
  2353    	removeNodeRange: removeNodeRange,
  2354    	isFragment: isFragment,
  2355    	getOuterHTML: getOuterHTML,
  2356    	mergeOptions: mergeOptions,
  2357    	resolveAsset: resolveAsset,
  2358    	checkComponentAttr: checkComponentAttr,
  2359    	commonTagRE: commonTagRE,
  2360    	reservedTagRE: reservedTagRE,
  2361    	get warn () { return warn; }
  2362    });
  2363  
  2364    var uid = 0;
  2365  
  2366    function initMixin (Vue) {
  2367      /**
  2368       * The main init sequence. This is called for every
  2369       * instance, including ones that are created from extended
  2370       * constructors.
  2371       *
  2372       * @param {Object} options - this options object should be
  2373       *                           the result of merging class
  2374       *                           options and the options passed
  2375       *                           in to the constructor.
  2376       */
  2377  
  2378      Vue.prototype._init = function (options) {
  2379        options = options || {};
  2380  
  2381        this.$el = null;
  2382        this.$parent = options.parent;
  2383        this.$root = this.$parent ? this.$parent.$root : this;
  2384        this.$children = [];
  2385        this.$refs = {}; // child vm references
  2386        this.$els = {}; // element references
  2387        this._watchers = []; // all watchers as an array
  2388        this._directives = []; // all directives
  2389  
  2390        // a uid
  2391        this._uid = uid++;
  2392  
  2393        // a flag to avoid this being observed
  2394        this._isVue = true;
  2395  
  2396        // events bookkeeping
  2397        this._events = {}; // registered callbacks
  2398        this._eventsCount = {}; // for $broadcast optimization
  2399  
  2400        // fragment instance properties
  2401        this._isFragment = false;
  2402        this._fragment = // @type {DocumentFragment}
  2403        this._fragmentStart = // @type {Text|Comment}
  2404        this._fragmentEnd = null; // @type {Text|Comment}
  2405  
  2406        // lifecycle state
  2407        this._isCompiled = this._isDestroyed = this._isReady = this._isAttached = this._isBeingDestroyed = this._vForRemoving = false;
  2408        this._unlinkFn = null;
  2409  
  2410        // context:
  2411        // if this is a transcluded component, context
  2412        // will be the common parent vm of this instance
  2413        // and its host.
  2414        this._context = options._context || this.$parent;
  2415  
  2416        // scope:
  2417        // if this is inside an inline v-for, the scope
  2418        // will be the intermediate scope created for this
  2419        // repeat fragment. this is used for linking props
  2420        // and container directives.
  2421        this._scope = options._scope;
  2422  
  2423        // fragment:
  2424        // if this instance is compiled inside a Fragment, it
  2425        // needs to reigster itself as a child of that fragment
  2426        // for attach/detach to work properly.
  2427        this._frag = options._frag;
  2428        if (this._frag) {
  2429          this._frag.children.push(this);
  2430        }
  2431  
  2432        // push self into parent / transclusion host
  2433        if (this.$parent) {
  2434          this.$parent.$children.push(this);
  2435        }
  2436  
  2437        // merge options.
  2438        options = this.$options = mergeOptions(this.constructor.options, options, this);
  2439  
  2440        // set ref
  2441        this._updateRef();
  2442  
  2443        // initialize data as empty object.
  2444        // it will be filled up in _initData().
  2445        this._data = {};
  2446  
  2447        // call init hook
  2448        this._callHook('init');
  2449  
  2450        // initialize data observation and scope inheritance.
  2451        this._initState();
  2452  
  2453        // setup event system and option events.
  2454        this._initEvents();
  2455  
  2456        // call created hook
  2457        this._callHook('created');
  2458  
  2459        // if `el` option is passed, start compilation.
  2460        if (options.el) {
  2461          this.$mount(options.el);
  2462        }
  2463      };
  2464    }
  2465  
  2466    var pathCache = new Cache(1000);
  2467  
  2468    // actions
  2469    var APPEND = 0;
  2470    var PUSH = 1;
  2471    var INC_SUB_PATH_DEPTH = 2;
  2472    var PUSH_SUB_PATH = 3;
  2473  
  2474    // states
  2475    var BEFORE_PATH = 0;
  2476    var IN_PATH = 1;
  2477    var BEFORE_IDENT = 2;
  2478    var IN_IDENT = 3;
  2479    var IN_SUB_PATH = 4;
  2480    var IN_SINGLE_QUOTE = 5;
  2481    var IN_DOUBLE_QUOTE = 6;
  2482    var AFTER_PATH = 7;
  2483    var ERROR = 8;
  2484  
  2485    var pathStateMachine = [];
  2486  
  2487    pathStateMachine[BEFORE_PATH] = {
  2488      'ws': [BEFORE_PATH],
  2489      'ident': [IN_IDENT, APPEND],
  2490      '[': [IN_SUB_PATH],
  2491      'eof': [AFTER_PATH]
  2492    };
  2493  
  2494    pathStateMachine[IN_PATH] = {
  2495      'ws': [IN_PATH],
  2496      '.': [BEFORE_IDENT],
  2497      '[': [IN_SUB_PATH],
  2498      'eof': [AFTER_PATH]
  2499    };
  2500  
  2501    pathStateMachine[BEFORE_IDENT] = {
  2502      'ws': [BEFORE_IDENT],
  2503      'ident': [IN_IDENT, APPEND]
  2504    };
  2505  
  2506    pathStateMachine[IN_IDENT] = {
  2507      'ident': [IN_IDENT, APPEND],
  2508      '0': [IN_IDENT, APPEND],
  2509      'number': [IN_IDENT, APPEND],
  2510      'ws': [IN_PATH, PUSH],
  2511      '.': [BEFORE_IDENT, PUSH],
  2512      '[': [IN_SUB_PATH, PUSH],
  2513      'eof': [AFTER_PATH, PUSH]
  2514    };
  2515  
  2516    pathStateMachine[IN_SUB_PATH] = {
  2517      "'": [IN_SINGLE_QUOTE, APPEND],
  2518      '"': [IN_DOUBLE_QUOTE, APPEND],
  2519      '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
  2520      ']': [IN_PATH, PUSH_SUB_PATH],
  2521      'eof': ERROR,
  2522      'else': [IN_SUB_PATH, APPEND]
  2523    };
  2524  
  2525    pathStateMachine[IN_SINGLE_QUOTE] = {
  2526      "'": [IN_SUB_PATH, APPEND],
  2527      'eof': ERROR,
  2528      'else': [IN_SINGLE_QUOTE, APPEND]
  2529    };
  2530  
  2531    pathStateMachine[IN_DOUBLE_QUOTE] = {
  2532      '"': [IN_SUB_PATH, APPEND],
  2533      'eof': ERROR,
  2534      'else': [IN_DOUBLE_QUOTE, APPEND]
  2535    };
  2536  
  2537    /**
  2538     * Determine the type of a character in a keypath.
  2539     *
  2540     * @param {Char} ch
  2541     * @return {String} type
  2542     */
  2543  
  2544    function getPathCharType(ch) {
  2545      if (ch === undefined) {
  2546        return 'eof';
  2547      }
  2548  
  2549      var code = ch.charCodeAt(0);
  2550  
  2551      switch (code) {
  2552        case 0x5B: // [
  2553        case 0x5D: // ]
  2554        case 0x2E: // .
  2555        case 0x22: // "
  2556        case 0x27: // '
  2557        case 0x30:
  2558          // 0
  2559          return ch;
  2560  
  2561        case 0x5F: // _
  2562        case 0x24:
  2563          // $
  2564          return 'ident';
  2565  
  2566        case 0x20: // Space
  2567        case 0x09: // Tab
  2568        case 0x0A: // Newline
  2569        case 0x0D: // Return
  2570        case 0xA0: // No-break space
  2571        case 0xFEFF: // Byte Order Mark
  2572        case 0x2028: // Line Separator
  2573        case 0x2029:
  2574          // Paragraph Separator
  2575          return 'ws';
  2576      }
  2577  
  2578      // a-z, A-Z
  2579      if (code >= 0x61 && code <= 0x7A || code >= 0x41 && code <= 0x5A) {
  2580        return 'ident';
  2581      }
  2582  
  2583      // 1-9
  2584      if (code >= 0x31 && code <= 0x39) {
  2585        return 'number';
  2586      }
  2587  
  2588      return 'else';
  2589    }
  2590  
  2591    /**
  2592     * Format a subPath, return its plain form if it is
  2593     * a literal string or number. Otherwise prepend the
  2594     * dynamic indicator (*).
  2595     *
  2596     * @param {String} path
  2597     * @return {String}
  2598     */
  2599  
  2600    function formatSubPath(path) {
  2601      var trimmed = path.trim();
  2602      // invalid leading 0
  2603      if (path.charAt(0) === '0' && isNaN(path)) {
  2604        return false;
  2605      }
  2606      return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed;
  2607    }
  2608  
  2609    /**
  2610     * Parse a string path into an array of segments
  2611     *
  2612     * @param {String} path
  2613     * @return {Array|undefined}
  2614     */
  2615  
  2616    function parse(path) {
  2617      var keys = [];
  2618      var index = -1;
  2619      var mode = BEFORE_PATH;
  2620      var subPathDepth = 0;
  2621      var c, newChar, key, type, transition, action, typeMap;
  2622  
  2623      var actions = [];
  2624  
  2625      actions[PUSH] = function () {
  2626        if (key !== undefined) {
  2627          keys.push(key);
  2628          key = undefined;
  2629        }
  2630      };
  2631  
  2632      actions[APPEND] = function () {
  2633        if (key === undefined) {
  2634          key = newChar;
  2635        } else {
  2636          key += newChar;
  2637        }
  2638      };
  2639  
  2640      actions[INC_SUB_PATH_DEPTH] = function () {
  2641        actions[APPEND]();
  2642        subPathDepth++;
  2643      };
  2644  
  2645      actions[PUSH_SUB_PATH] = function () {
  2646        if (subPathDepth > 0) {
  2647          subPathDepth--;
  2648          mode = IN_SUB_PATH;
  2649          actions[APPEND]();
  2650        } else {
  2651          subPathDepth = 0;
  2652          key = formatSubPath(key);
  2653          if (key === false) {
  2654            return false;
  2655          } else {
  2656            actions[PUSH]();
  2657          }
  2658        }
  2659      };
  2660  
  2661      function maybeUnescapeQuote() {
  2662        var nextChar = path[index + 1];
  2663        if (mode === IN_SINGLE_QUOTE && nextChar === "'" || mode === IN_DOUBLE_QUOTE && nextChar === '"') {
  2664          index++;
  2665          newChar = '\\' + nextChar;
  2666          actions[APPEND]();
  2667          return true;
  2668        }
  2669      }
  2670  
  2671      while (mode != null) {
  2672        index++;
  2673        c = path[index];
  2674  
  2675        if (c === '\\' && maybeUnescapeQuote()) {
  2676          continue;
  2677        }
  2678  
  2679        type = getPathCharType(c);
  2680        typeMap = pathStateMachine[mode];
  2681        transition = typeMap[type] || typeMap['else'] || ERROR;
  2682  
  2683        if (transition === ERROR) {
  2684          return; // parse error
  2685        }
  2686  
  2687        mode = transition[0];
  2688        action = actions[transition[1]];
  2689        if (action) {
  2690          newChar = transition[2];
  2691          newChar = newChar === undefined ? c : newChar;
  2692          if (action() === false) {
  2693            return;
  2694          }
  2695        }
  2696  
  2697        if (mode === AFTER_PATH) {
  2698          keys.raw = path;
  2699          return keys;
  2700        }
  2701      }
  2702    }
  2703  
  2704    /**
  2705     * External parse that check for a cache hit first
  2706     *
  2707     * @param {String} path
  2708     * @return {Array|undefined}
  2709     */
  2710  
  2711    function parsePath(path) {
  2712      var hit = pathCache.get(path);
  2713      if (!hit) {
  2714        hit = parse(path);
  2715        if (hit) {
  2716          pathCache.put(path, hit);
  2717        }
  2718      }
  2719      return hit;
  2720    }
  2721  
  2722    /**
  2723     * Get from an object from a path string
  2724     *
  2725     * @param {Object} obj
  2726     * @param {String} path
  2727     */
  2728  
  2729    function getPath(obj, path) {
  2730      return parseExpression(path).get(obj);
  2731    }
  2732  
  2733    /**
  2734     * Warn against setting non-existent root path on a vm.
  2735     */
  2736  
  2737    var warnNonExistent;
  2738    if ('development' !== 'production') {
  2739      warnNonExistent = function (path, vm) {
  2740        warn('You are setting a non-existent path "' + path.raw + '" ' + 'on a vm instance. Consider pre-initializing the property ' + 'with the "data" option for more reliable reactivity ' + 'and better performance.', vm);
  2741      };
  2742    }
  2743  
  2744    /**
  2745     * Set on an object from a path
  2746     *
  2747     * @param {Object} obj
  2748     * @param {String | Array} path
  2749     * @param {*} val
  2750     */
  2751  
  2752    function setPath(obj, path, val) {
  2753      var original = obj;
  2754      if (typeof path === 'string') {
  2755        path = parse(path);
  2756      }
  2757      if (!path || !isObject(obj)) {
  2758        return false;
  2759      }
  2760      var last, key;
  2761      for (var i = 0, l = path.length; i < l; i++) {
  2762        last = obj;
  2763        key = path[i];
  2764        if (key.charAt(0) === '*') {
  2765          key = parseExpression(key.slice(1)).get.call(original, original);
  2766        }
  2767        if (i < l - 1) {
  2768          obj = obj[key];
  2769          if (!isObject(obj)) {
  2770            obj = {};
  2771            if ('development' !== 'production' && last._isVue) {
  2772              warnNonExistent(path, last);
  2773            }
  2774            set(last, key, obj);
  2775          }
  2776        } else {
  2777          if (isArray(obj)) {
  2778            obj.$set(key, val);
  2779          } else if (key in obj) {
  2780            obj[key] = val;
  2781          } else {
  2782            if ('development' !== 'production' && obj._isVue) {
  2783              warnNonExistent(path, obj);
  2784            }
  2785            set(obj, key, val);
  2786          }
  2787        }
  2788      }
  2789      return true;
  2790    }
  2791  
  2792  var path = Object.freeze({
  2793      parsePath: parsePath,
  2794      getPath: getPath,
  2795      setPath: setPath
  2796    });
  2797  
  2798    var expressionCache = new Cache(1000);
  2799  
  2800    var allowedKeywords = 'Math,Date,this,true,false,null,undefined,Infinity,NaN,' + 'isNaN,isFinite,decodeURI,decodeURIComponent,encodeURI,' + 'encodeURIComponent,parseInt,parseFloat';
  2801    var allowedKeywordsRE = new RegExp('^(' + allowedKeywords.replace(/,/g, '\\b|') + '\\b)');
  2802  
  2803    // keywords that don't make sense inside expressions
  2804    var improperKeywords = 'break,case,class,catch,const,continue,debugger,default,' + 'delete,do,else,export,extends,finally,for,function,if,' + 'import,in,instanceof,let,return,super,switch,throw,try,' + 'var,while,with,yield,enum,await,implements,package,' + 'protected,static,interface,private,public';
  2805    var improperKeywordsRE = new RegExp('^(' + improperKeywords.replace(/,/g, '\\b|') + '\\b)');
  2806  
  2807    var wsRE = /\s/g;
  2808    var newlineRE = /\n/g;
  2809    var saveRE = /[\{,]\s*[\w\$_]+\s*:|('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`)|new |typeof |void /g;
  2810    var restoreRE = /"(\d+)"/g;
  2811    var pathTestRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/;
  2812    var identRE = /[^\w$\.](?:[A-Za-z_$][\w$]*)/g;
  2813    var booleanLiteralRE = /^(?:true|false)$/;
  2814  
  2815    /**
  2816     * Save / Rewrite / Restore
  2817     *
  2818     * When rewriting paths found in an expression, it is
  2819     * possible for the same letter sequences to be found in
  2820     * strings and Object literal property keys. Therefore we
  2821     * remove and store these parts in a temporary array, and
  2822     * restore them after the path rewrite.
  2823     */
  2824  
  2825    var saved = [];
  2826  
  2827    /**
  2828     * Save replacer
  2829     *
  2830     * The save regex can match two possible cases:
  2831     * 1. An opening object literal
  2832     * 2. A string
  2833     * If matched as a plain string, we need to escape its
  2834     * newlines, since the string needs to be preserved when
  2835     * generating the function body.
  2836     *
  2837     * @param {String} str
  2838     * @param {String} isString - str if matched as a string
  2839     * @return {String} - placeholder with index
  2840     */
  2841  
  2842    function save(str, isString) {
  2843      var i = saved.length;
  2844      saved[i] = isString ? str.replace(newlineRE, '\\n') : str;
  2845      return '"' + i + '"';
  2846    }
  2847  
  2848    /**
  2849     * Path rewrite replacer
  2850     *
  2851     * @param {String} raw
  2852     * @return {String}
  2853     */
  2854  
  2855    function rewrite(raw) {
  2856      var c = raw.charAt(0);
  2857      var path = raw.slice(1);
  2858      if (allowedKeywordsRE.test(path)) {
  2859        return raw;
  2860      } else {
  2861        path = path.indexOf('"') > -1 ? path.replace(restoreRE, restore) : path;
  2862        return c + 'scope.' + path;
  2863      }
  2864    }
  2865  
  2866    /**
  2867     * Restore replacer
  2868     *
  2869     * @param {String} str
  2870     * @param {String} i - matched save index
  2871     * @return {String}
  2872     */
  2873  
  2874    function restore(str, i) {
  2875      return saved[i];
  2876    }
  2877  
  2878    /**
  2879     * Rewrite an expression, prefixing all path accessors with
  2880     * `scope.` and generate getter/setter functions.
  2881     *
  2882     * @param {String} exp
  2883     * @return {Function}
  2884     */
  2885  
  2886    function compileGetter(exp) {
  2887      if (improperKeywordsRE.test(exp)) {
  2888        'development' !== 'production' && warn('Avoid using reserved keywords in expression: ' + exp);
  2889      }
  2890      // reset state
  2891      saved.length = 0;
  2892      // save strings and object literal keys
  2893      var body = exp.replace(saveRE, save).replace(wsRE, '');
  2894      // rewrite all paths
  2895      // pad 1 space here becaue the regex matches 1 extra char
  2896      body = (' ' + body).replace(identRE, rewrite).replace(restoreRE, restore);
  2897      return makeGetterFn(body);
  2898    }
  2899  
  2900    /**
  2901     * Build a getter function. Requires eval.
  2902     *
  2903     * We isolate the try/catch so it doesn't affect the
  2904     * optimization of the parse function when it is not called.
  2905     *
  2906     * @param {String} body
  2907     * @return {Function|undefined}
  2908     */
  2909  
  2910    function makeGetterFn(body) {
  2911      try {
  2912        /* eslint-disable no-new-func */
  2913        return new Function('scope', 'return ' + body + ';');
  2914        /* eslint-enable no-new-func */
  2915      } catch (e) {
  2916        'development' !== 'production' && warn('Invalid expression. ' + 'Generated function body: ' + body);
  2917      }
  2918    }
  2919  
  2920    /**
  2921     * Compile a setter function for the expression.
  2922     *
  2923     * @param {String} exp
  2924     * @return {Function|undefined}
  2925     */
  2926  
  2927    function compileSetter(exp) {
  2928      var path = parsePath(exp);
  2929      if (path) {
  2930        return function (scope, val) {
  2931          setPath(scope, path, val);
  2932        };
  2933      } else {
  2934        'development' !== 'production' && warn('Invalid setter expression: ' + exp);
  2935      }
  2936    }
  2937  
  2938    /**
  2939     * Parse an expression into re-written getter/setters.
  2940     *
  2941     * @param {String} exp
  2942     * @param {Boolean} needSet
  2943     * @return {Function}
  2944     */
  2945  
  2946    function parseExpression(exp, needSet) {
  2947      exp = exp.trim();
  2948      // try cache
  2949      var hit = expressionCache.get(exp);
  2950      if (hit) {
  2951        if (needSet && !hit.set) {
  2952          hit.set = compileSetter(hit.exp);
  2953        }
  2954        return hit;
  2955      }
  2956      var res = { exp: exp };
  2957      res.get = isSimplePath(exp) && exp.indexOf('[') < 0
  2958      // optimized super simple getter
  2959      ? makeGetterFn('scope.' + exp)
  2960      // dynamic getter
  2961      : compileGetter(exp);
  2962      if (needSet) {
  2963        res.set = compileSetter(exp);
  2964      }
  2965      expressionCache.put(exp, res);
  2966      return res;
  2967    }
  2968  
  2969    /**
  2970     * Check if an expression is a simple path.
  2971     *
  2972     * @param {String} exp
  2973     * @return {Boolean}
  2974     */
  2975  
  2976    function isSimplePath(exp) {
  2977      return pathTestRE.test(exp) &&
  2978      // don't treat true/false as paths
  2979      !booleanLiteralRE.test(exp) &&
  2980      // Math constants e.g. Math.PI, Math.E etc.
  2981      exp.slice(0, 5) !== 'Math.';
  2982    }
  2983  
  2984  var expression = Object.freeze({
  2985      parseExpression: parseExpression,
  2986      isSimplePath: isSimplePath
  2987    });
  2988  
  2989    // we have two separate queues: one for directive updates
  2990    // and one for user watcher registered via $watch().
  2991    // we want to guarantee directive updates to be called
  2992    // before user watchers so that when user watchers are
  2993    // triggered, the DOM would have already been in updated
  2994    // state.
  2995  
  2996    var queue = [];
  2997    var userQueue = [];
  2998    var has = {};
  2999    var circular = {};
  3000    var waiting = false;
  3001  
  3002    /**
  3003     * Reset the batcher's state.
  3004     */
  3005  
  3006    function resetBatcherState() {
  3007      queue.length = 0;
  3008      userQueue.length = 0;
  3009      has = {};
  3010      circular = {};
  3011      waiting = false;
  3012    }
  3013  
  3014    /**
  3015     * Flush both queues and run the watchers.
  3016     */
  3017  
  3018    function flushBatcherQueue() {
  3019      var _again = true;
  3020  
  3021      _function: while (_again) {
  3022        _again = false;
  3023  
  3024        runBatcherQueue(queue);
  3025        runBatcherQueue(userQueue);
  3026        // user watchers triggered more watchers,
  3027        // keep flushing until it depletes
  3028        if (queue.length) {
  3029          _again = true;
  3030          continue _function;
  3031        }
  3032        // dev tool hook
  3033        /* istanbul ignore if */
  3034        if (devtools && config.devtools) {
  3035          devtools.emit('flush');
  3036        }
  3037        resetBatcherState();
  3038      }
  3039    }
  3040  
  3041    /**
  3042     * Run the watchers in a single queue.
  3043     *
  3044     * @param {Array} queue
  3045     */
  3046  
  3047    function runBatcherQueue(queue) {
  3048      // do not cache length because more watchers might be pushed
  3049      // as we run existing watchers
  3050      for (var i = 0; i < queue.length; i++) {
  3051        var watcher = queue[i];
  3052        var id = watcher.id;
  3053        has[id] = null;
  3054        watcher.run();
  3055        // in dev build, check and stop circular updates.
  3056        if ('development' !== 'production' && has[id] != null) {
  3057          circular[id] = (circular[id] || 0) + 1;
  3058          if (circular[id] > config._maxUpdateCount) {
  3059            warn('You may have an infinite update loop for watcher ' + 'with expression "' + watcher.expression + '"', watcher.vm);
  3060            break;
  3061          }
  3062        }
  3063      }
  3064      queue.length = 0;
  3065    }
  3066  
  3067    /**
  3068     * Push a watcher into the watcher queue.
  3069     * Jobs with duplicate IDs will be skipped unless it's
  3070     * pushed when the queue is being flushed.
  3071     *
  3072     * @param {Watcher} watcher
  3073     *   properties:
  3074     *   - {Number} id
  3075     *   - {Function} run
  3076     */
  3077  
  3078    function pushWatcher(watcher) {
  3079      var id = watcher.id;
  3080      if (has[id] == null) {
  3081        // push watcher into appropriate queue
  3082        var q = watcher.user ? userQueue : queue;
  3083        has[id] = q.length;
  3084        q.push(watcher);
  3085        // queue the flush
  3086        if (!waiting) {
  3087          waiting = true;
  3088          nextTick(flushBatcherQueue);
  3089        }
  3090      }
  3091    }
  3092  
  3093    var uid$2 = 0;
  3094  
  3095    /**
  3096     * A watcher parses an expression, collects dependencies,
  3097     * and fires callback when the expression value changes.
  3098     * This is used for both the $watch() api and directives.
  3099     *
  3100     * @param {Vue} vm
  3101     * @param {String|Function} expOrFn
  3102     * @param {Function} cb
  3103     * @param {Object} options
  3104     *                 - {Array} filters
  3105     *                 - {Boolean} twoWay
  3106     *                 - {Boolean} deep
  3107     *                 - {Boolean} user
  3108     *                 - {Boolean} sync
  3109     *                 - {Boolean} lazy
  3110     *                 - {Function} [preProcess]
  3111     *                 - {Function} [postProcess]
  3112     * @constructor
  3113     */
  3114    function Watcher(vm, expOrFn, cb, options) {
  3115      // mix in options
  3116      if (options) {
  3117        extend(this, options);
  3118      }
  3119      var isFn = typeof expOrFn === 'function';
  3120      this.vm = vm;
  3121      vm._watchers.push(this);
  3122      this.expression = expOrFn;
  3123      this.cb = cb;
  3124      this.id = ++uid$2; // uid for batching
  3125      this.active = true;
  3126      this.dirty = this.lazy; // for lazy watchers
  3127      this.deps = [];
  3128      this.newDeps = [];
  3129      this.depIds = new _Set();
  3130      this.newDepIds = new _Set();
  3131      this.prevError = null; // for async error stacks
  3132      // parse expression for getter/setter
  3133      if (isFn) {
  3134        this.getter = expOrFn;
  3135        this.setter = undefined;
  3136      } else {
  3137        var res = parseExpression(expOrFn, this.twoWay);
  3138        this.getter = res.get;
  3139        this.setter = res.set;
  3140      }
  3141      this.value = this.lazy ? undefined : this.get();
  3142      // state for avoiding false triggers for deep and Array
  3143      // watchers during vm._digest()
  3144      this.queued = this.shallow = false;
  3145    }
  3146  
  3147    /**
  3148     * Evaluate the getter, and re-collect dependencies.
  3149     */
  3150  
  3151    Watcher.prototype.get = function () {
  3152      this.beforeGet();
  3153      var scope = this.scope || this.vm;
  3154      var value;
  3155      try {
  3156        value = this.getter.call(scope, scope);
  3157      } catch (e) {
  3158        if ('development' !== 'production' && config.warnExpressionErrors) {
  3159          warn('Error when evaluating expression ' + '"' + this.expression + '": ' + e.toString(), this.vm);
  3160        }
  3161      }
  3162      // "touch" every property so they are all tracked as
  3163      // dependencies for deep watching
  3164      if (this.deep) {
  3165        traverse(value);
  3166      }
  3167      if (this.preProcess) {
  3168        value = this.preProcess(value);
  3169      }
  3170      if (this.filters) {
  3171        value = scope._applyFilters(value, null, this.filters, false);
  3172      }
  3173      if (this.postProcess) {
  3174        value = this.postProcess(value);
  3175      }
  3176      this.afterGet();
  3177      return value;
  3178    };
  3179  
  3180    /**
  3181     * Set the corresponding value with the setter.
  3182     *
  3183     * @param {*} value
  3184     */
  3185  
  3186    Watcher.prototype.set = function (value) {
  3187      var scope = this.scope || this.vm;
  3188      if (this.filters) {
  3189        value = scope._applyFilters(value, this.value, this.filters, true);
  3190      }
  3191      try {
  3192        this.setter.call(scope, scope, value);
  3193      } catch (e) {
  3194        if ('development' !== 'production' && config.warnExpressionErrors) {
  3195          warn('Error when evaluating setter ' + '"' + this.expression + '": ' + e.toString(), this.vm);
  3196        }
  3197      }
  3198      // two-way sync for v-for alias
  3199      var forContext = scope.$forContext;
  3200      if (forContext && forContext.alias === this.expression) {
  3201        if (forContext.filters) {
  3202          'development' !== 'production' && warn('It seems you are using two-way binding on ' + 'a v-for alias (' + this.expression + '), and the ' + 'v-for has filters. This will not work properly. ' + 'Either remove the filters or use an array of ' + 'objects and bind to object properties instead.', this.vm);
  3203          return;
  3204        }
  3205        forContext._withLock(function () {
  3206          if (scope.$key) {
  3207            // original is an object
  3208            forContext.rawValue[scope.$key] = value;
  3209          } else {
  3210            forContext.rawValue.$set(scope.$index, value);
  3211          }
  3212        });
  3213      }
  3214    };
  3215  
  3216    /**
  3217     * Prepare for dependency collection.
  3218     */
  3219  
  3220    Watcher.prototype.beforeGet = function () {
  3221      Dep.target = this;
  3222    };
  3223  
  3224    /**
  3225     * Add a dependency to this directive.
  3226     *
  3227     * @param {Dep} dep
  3228     */
  3229  
  3230    Watcher.prototype.addDep = function (dep) {
  3231      var id = dep.id;
  3232      if (!this.newDepIds.has(id)) {
  3233        this.newDepIds.add(id);
  3234        this.newDeps.push(dep);
  3235        if (!this.depIds.has(id)) {
  3236          dep.addSub(this);
  3237        }
  3238      }
  3239    };
  3240  
  3241    /**
  3242     * Clean up for dependency collection.
  3243     */
  3244  
  3245    Watcher.prototype.afterGet = function () {
  3246      Dep.target = null;
  3247      var i = this.deps.length;
  3248      while (i--) {
  3249        var dep = this.deps[i];
  3250        if (!this.newDepIds.has(dep.id)) {
  3251          dep.removeSub(this);
  3252        }
  3253      }
  3254      var tmp = this.depIds;
  3255      this.depIds = this.newDepIds;
  3256      this.newDepIds = tmp;
  3257      this.newDepIds.clear();
  3258      tmp = this.deps;
  3259      this.deps = this.newDeps;
  3260      this.newDeps = tmp;
  3261      this.newDeps.length = 0;
  3262    };
  3263  
  3264    /**
  3265     * Subscriber interface.
  3266     * Will be called when a dependency changes.
  3267     *
  3268     * @param {Boolean} shallow
  3269     */
  3270  
  3271    Watcher.prototype.update = function (shallow) {
  3272      if (this.lazy) {
  3273        this.dirty = true;
  3274      } else if (this.sync || !config.async) {
  3275        this.run();
  3276      } else {
  3277        // if queued, only overwrite shallow with non-shallow,
  3278        // but not the other way around.
  3279        this.shallow = this.queued ? shallow ? this.shallow : false : !!shallow;
  3280        this.queued = true;
  3281        // record before-push error stack in debug mode
  3282        /* istanbul ignore if */
  3283        if ('development' !== 'production' && config.debug) {
  3284          this.prevError = new Error('[vue] async stack trace');
  3285        }
  3286        pushWatcher(this);
  3287      }
  3288    };
  3289  
  3290    /**
  3291     * Batcher job interface.
  3292     * Will be called by the batcher.
  3293     */
  3294  
  3295    Watcher.prototype.run = function () {
  3296      if (this.active) {
  3297        var value = this.get();
  3298        if (value !== this.value ||
  3299        // Deep watchers and watchers on Object/Arrays should fire even
  3300        // when the value is the same, because the value may
  3301        // have mutated; but only do so if this is a
  3302        // non-shallow update (caused by a vm digest).
  3303        (isObject(value) || this.deep) && !this.shallow) {
  3304          // set new value
  3305          var oldValue = this.value;
  3306          this.value = value;
  3307          // in debug + async mode, when a watcher callbacks
  3308          // throws, we also throw the saved before-push error
  3309          // so the full cross-tick stack trace is available.
  3310          var prevError = this.prevError;
  3311          /* istanbul ignore if */
  3312          if ('development' !== 'production' && config.debug && prevError) {
  3313            this.prevError = null;
  3314            try {
  3315              this.cb.call(this.vm, value, oldValue);
  3316            } catch (e) {
  3317              nextTick(function () {
  3318                throw prevError;
  3319              }, 0);
  3320              throw e;
  3321            }
  3322          } else {
  3323            this.cb.call(this.vm, value, oldValue);
  3324          }
  3325        }
  3326        this.queued = this.shallow = false;
  3327      }
  3328    };
  3329  
  3330    /**
  3331     * Evaluate the value of the watcher.
  3332     * This only gets called for lazy watchers.
  3333     */
  3334  
  3335    Watcher.prototype.evaluate = function () {
  3336      // avoid overwriting another watcher that is being
  3337      // collected.
  3338      var current = Dep.target;
  3339      this.value = this.get();
  3340      this.dirty = false;
  3341      Dep.target = current;
  3342    };
  3343  
  3344    /**
  3345     * Depend on all deps collected by this watcher.
  3346     */
  3347  
  3348    Watcher.prototype.depend = function () {
  3349      var i = this.deps.length;
  3350      while (i--) {
  3351        this.deps[i].depend();
  3352      }
  3353    };
  3354  
  3355    /**
  3356     * Remove self from all dependencies' subcriber list.
  3357     */
  3358  
  3359    Watcher.prototype.teardown = function () {
  3360      if (this.active) {
  3361        // remove self from vm's watcher list
  3362        // this is a somewhat expensive operation so we skip it
  3363        // if the vm is being destroyed or is performing a v-for
  3364        // re-render (the watcher list is then filtered by v-for).
  3365        if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
  3366          this.vm._watchers.$remove(this);
  3367        }
  3368        var i = this.deps.length;
  3369        while (i--) {
  3370          this.deps[i].removeSub(this);
  3371        }
  3372        this.active = false;
  3373        this.vm = this.cb = this.value = null;
  3374      }
  3375    };
  3376  
  3377    /**
  3378     * Recrusively traverse an object to evoke all converted
  3379     * getters, so that every nested property inside the object
  3380     * is collected as a "deep" dependency.
  3381     *
  3382     * @param {*} val
  3383     */
  3384  
  3385    var seenObjects = new _Set();
  3386    function traverse(val, seen) {
  3387      var i = undefined,
  3388          keys = undefined;
  3389      if (!seen) {
  3390        seen = seenObjects;
  3391        seen.clear();
  3392      }
  3393      var isA = isArray(val);
  3394      var isO = isObject(val);
  3395      if (isA || isO) {
  3396        if (val.__ob__) {
  3397          var depId = val.__ob__.dep.id;
  3398          if (seen.has(depId)) {
  3399            return;
  3400          } else {
  3401            seen.add(depId);
  3402          }
  3403        }
  3404        if (isA) {
  3405          i = val.length;
  3406          while (i--) traverse(val[i], seen);
  3407        } else if (isO) {
  3408          keys = Object.keys(val);
  3409          i = keys.length;
  3410          while (i--) traverse(val[keys[i]], seen);
  3411        }
  3412      }
  3413    }
  3414  
  3415    var text$1 = {
  3416  
  3417      bind: function bind() {
  3418        this.attr = this.el.nodeType === 3 ? 'data' : 'textContent';
  3419      },
  3420  
  3421      update: function update(value) {
  3422        this.el[this.attr] = _toString(value);
  3423      }
  3424    };
  3425  
  3426    var templateCache = new Cache(1000);
  3427    var idSelectorCache = new Cache(1000);
  3428  
  3429    var map = {
  3430      efault: [0, '', ''],
  3431      legend: [1, '<fieldset>', '</fieldset>'],
  3432      tr: [2, '<table><tbody>', '</tbody></table>'],
  3433      col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>']
  3434    };
  3435  
  3436    map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
  3437  
  3438    map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
  3439  
  3440    map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
  3441  
  3442    map.g = map.defs = map.symbol = map.use = map.image = map.text = map.circle = map.ellipse = map.line = map.path = map.polygon = map.polyline = map.rect = [1, '<svg ' + 'xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'xmlns:ev="http://www.w3.org/2001/xml-events"' + 'version="1.1">', '</svg>'];
  3443  
  3444    /**
  3445     * Check if a node is a supported template node with a
  3446     * DocumentFragment content.
  3447     *
  3448     * @param {Node} node
  3449     * @return {Boolean}
  3450     */
  3451  
  3452    function isRealTemplate(node) {
  3453      return isTemplate(node) && isFragment(node.content);
  3454    }
  3455  
  3456    var tagRE$1 = /<([\w:-]+)/;
  3457    var entityRE = /&#?\w+?;/;
  3458  
  3459    /**
  3460     * Convert a string template to a DocumentFragment.
  3461     * Determines correct wrapping by tag types. Wrapping
  3462     * strategy found in jQuery & component/domify.
  3463     *
  3464     * @param {String} templateString
  3465     * @param {Boolean} raw
  3466     * @return {DocumentFragment}
  3467     */
  3468  
  3469    function stringToFragment(templateString, raw) {
  3470      // try a cache hit first
  3471      var cacheKey = raw ? templateString : templateString.trim();
  3472      var hit = templateCache.get(cacheKey);
  3473      if (hit) {
  3474        return hit;
  3475      }
  3476  
  3477      var frag = document.createDocumentFragment();
  3478      var tagMatch = templateString.match(tagRE$1);
  3479      var entityMatch = entityRE.test(templateString);
  3480  
  3481      if (!tagMatch && !entityMatch) {
  3482        // text only, return a single text node.
  3483        frag.appendChild(document.createTextNode(templateString));
  3484      } else {
  3485        var tag = tagMatch && tagMatch[1];
  3486        var wrap = map[tag] || map.efault;
  3487        var depth = wrap[0];
  3488        var prefix = wrap[1];
  3489        var suffix = wrap[2];
  3490        var node = document.createElement('div');
  3491  
  3492        node.innerHTML = prefix + templateString + suffix;
  3493        while (depth--) {
  3494          node = node.lastChild;
  3495        }
  3496  
  3497        var child;
  3498        /* eslint-disable no-cond-assign */
  3499        while (child = node.firstChild) {
  3500          /* eslint-enable no-cond-assign */
  3501          frag.appendChild(child);
  3502        }
  3503      }
  3504      if (!raw) {
  3505        trimNode(frag);
  3506      }
  3507      templateCache.put(cacheKey, frag);
  3508      return frag;
  3509    }
  3510  
  3511    /**
  3512     * Convert a template node to a DocumentFragment.
  3513     *
  3514     * @param {Node} node
  3515     * @return {DocumentFragment}
  3516     */
  3517  
  3518    function nodeToFragment(node) {
  3519      // if its a template tag and the browser supports it,
  3520      // its content is already a document fragment. However, iOS Safari has
  3521      // bug when using directly cloned template content with touch
  3522      // events and can cause crashes when the nodes are removed from DOM, so we
  3523      // have to treat template elements as string templates. (#2805)
  3524      /* istanbul ignore if */
  3525      if (isRealTemplate(node)) {
  3526        return stringToFragment(node.innerHTML);
  3527      }
  3528      // script template
  3529      if (node.tagName === 'SCRIPT') {
  3530        return stringToFragment(node.textContent);
  3531      }
  3532      // normal node, clone it to avoid mutating the original
  3533      var clonedNode = cloneNode(node);
  3534      var frag = document.createDocumentFragment();
  3535      var child;
  3536      /* eslint-disable no-cond-assign */
  3537      while (child = clonedNode.firstChild) {
  3538        /* eslint-enable no-cond-assign */
  3539        frag.appendChild(child);
  3540      }
  3541      trimNode(frag);
  3542      return frag;
  3543    }
  3544  
  3545    // Test for the presence of the Safari template cloning bug
  3546    // https://bugs.webkit.org/showug.cgi?id=137755
  3547    var hasBrokenTemplate = (function () {
  3548      /* istanbul ignore else */
  3549      if (inBrowser) {
  3550        var a = document.createElement('div');
  3551        a.innerHTML = '<template>1</template>';
  3552        return !a.cloneNode(true).firstChild.innerHTML;
  3553      } else {
  3554        return false;
  3555      }
  3556    })();
  3557  
  3558    // Test for IE10/11 textarea placeholder clone bug
  3559    var hasTextareaCloneBug = (function () {
  3560      /* istanbul ignore else */
  3561      if (inBrowser) {
  3562        var t = document.createElement('textarea');
  3563        t.placeholder = 't';
  3564        return t.cloneNode(true).value === 't';
  3565      } else {
  3566        return false;
  3567      }
  3568    })();
  3569  
  3570    /**
  3571     * 1. Deal with Safari cloning nested <template> bug by
  3572     *    manually cloning all template instances.
  3573     * 2. Deal with IE10/11 textarea placeholder bug by setting
  3574     *    the correct value after cloning.
  3575     *
  3576     * @param {Element|DocumentFragment} node
  3577     * @return {Element|DocumentFragment}
  3578     */
  3579  
  3580    function cloneNode(node) {
  3581      /* istanbul ignore if */
  3582      if (!node.querySelectorAll) {
  3583        return node.cloneNode();
  3584      }
  3585      var res = node.cloneNode(true);
  3586      var i, original, cloned;
  3587      /* istanbul ignore if */
  3588      if (hasBrokenTemplate) {
  3589        var tempClone = res;
  3590        if (isRealTemplate(node)) {
  3591          node = node.content;
  3592          tempClone = res.content;
  3593        }
  3594        original = node.querySelectorAll('template');
  3595        if (original.length) {
  3596          cloned = tempClone.querySelectorAll('template');
  3597          i = cloned.length;
  3598          while (i--) {
  3599            cloned[i].parentNode.replaceChild(cloneNode(original[i]), cloned[i]);
  3600          }
  3601        }
  3602      }
  3603      /* istanbul ignore if */
  3604      if (hasTextareaCloneBug) {
  3605        if (node.tagName === 'TEXTAREA') {
  3606          res.value = node.value;
  3607        } else {
  3608          original = node.querySelectorAll('textarea');
  3609          if (original.length) {
  3610            cloned = res.querySelectorAll('textarea');
  3611            i = cloned.length;
  3612            while (i--) {
  3613              cloned[i].value = original[i].value;
  3614            }
  3615          }
  3616        }
  3617      }
  3618      return res;
  3619    }
  3620  
  3621    /**
  3622     * Process the template option and normalizes it into a
  3623     * a DocumentFragment that can be used as a partial or a
  3624     * instance template.
  3625     *
  3626     * @param {*} template
  3627     *        Possible values include:
  3628     *        - DocumentFragment object
  3629     *        - Node object of type Template
  3630     *        - id selector: '#some-template-id'
  3631     *        - template string: '<div><span>{{msg}}</span></div>'
  3632     * @param {Boolean} shouldClone
  3633     * @param {Boolean} raw
  3634     *        inline HTML interpolation. Do not check for id
  3635     *        selector and keep whitespace in the string.
  3636     * @return {DocumentFragment|undefined}
  3637     */
  3638  
  3639    function parseTemplate(template, shouldClone, raw) {
  3640      var node, frag;
  3641  
  3642      // if the template is already a document fragment,
  3643      // do nothing
  3644      if (isFragment(template)) {
  3645        trimNode(template);
  3646        return shouldClone ? cloneNode(template) : template;
  3647      }
  3648  
  3649      if (typeof template === 'string') {
  3650        // id selector
  3651        if (!raw && template.charAt(0) === '#') {
  3652          // id selector can be cached too
  3653          frag = idSelectorCache.get(template);
  3654          if (!frag) {
  3655            node = document.getElementById(template.slice(1));
  3656            if (node) {
  3657              frag = nodeToFragment(node);
  3658              // save selector to cache
  3659              idSelectorCache.put(template, frag);
  3660            }
  3661          }
  3662        } else {
  3663          // normal string template
  3664          frag = stringToFragment(template, raw);
  3665        }
  3666      } else if (template.nodeType) {
  3667        // a direct node
  3668        frag = nodeToFragment(template);
  3669      }
  3670  
  3671      return frag && shouldClone ? cloneNode(frag) : frag;
  3672    }
  3673  
  3674  var template = Object.freeze({
  3675      cloneNode: cloneNode,
  3676      parseTemplate: parseTemplate
  3677    });
  3678  
  3679    var html = {
  3680  
  3681      bind: function bind() {
  3682        // a comment node means this is a binding for
  3683        // {{{ inline unescaped html }}}
  3684        if (this.el.nodeType === 8) {
  3685          // hold nodes
  3686          this.nodes = [];
  3687          // replace the placeholder with proper anchor
  3688          this.anchor = createAnchor('v-html');
  3689          replace(this.el, this.anchor);
  3690        }
  3691      },
  3692  
  3693      update: function update(value) {
  3694        value = _toString(value);
  3695        if (this.nodes) {
  3696          this.swap(value);
  3697        } else {
  3698          this.el.innerHTML = value;
  3699        }
  3700      },
  3701  
  3702      swap: function swap(value) {
  3703        // remove old nodes
  3704        var i = this.nodes.length;
  3705        while (i--) {
  3706          remove(this.nodes[i]);
  3707        }
  3708        // convert new value to a fragment
  3709        // do not attempt to retrieve from id selector
  3710        var frag = parseTemplate(value, true, true);
  3711        // save a reference to these nodes so we can remove later
  3712        this.nodes = toArray(frag.childNodes);
  3713        before(frag, this.anchor);
  3714      }
  3715    };
  3716  
  3717    /**
  3718     * Abstraction for a partially-compiled fragment.
  3719     * Can optionally compile content with a child scope.
  3720     *
  3721     * @param {Function} linker
  3722     * @param {Vue} vm
  3723     * @param {DocumentFragment} frag
  3724     * @param {Vue} [host]
  3725     * @param {Object} [scope]
  3726     * @param {Fragment} [parentFrag]
  3727     */
  3728    function Fragment(linker, vm, frag, host, scope, parentFrag) {
  3729      this.children = [];
  3730      this.childFrags = [];
  3731      this.vm = vm;
  3732      this.scope = scope;
  3733      this.inserted = false;
  3734      this.parentFrag = parentFrag;
  3735      if (parentFrag) {
  3736        parentFrag.childFrags.push(this);
  3737      }
  3738      this.unlink = linker(vm, frag, host, scope, this);
  3739      var single = this.single = frag.childNodes.length === 1 &&
  3740      // do not go single mode if the only node is an anchor
  3741      !frag.childNodes[0].__v_anchor;
  3742      if (single) {
  3743        this.node = frag.childNodes[0];
  3744        this.before = singleBefore;
  3745        this.remove = singleRemove;
  3746      } else {
  3747        this.node = createAnchor('fragment-start');
  3748        this.end = createAnchor('fragment-end');
  3749        this.frag = frag;
  3750        prepend(this.node, frag);
  3751        frag.appendChild(this.end);
  3752        this.before = multiBefore;
  3753        this.remove = multiRemove;
  3754      }
  3755      this.node.__v_frag = this;
  3756    }
  3757  
  3758    /**
  3759     * Call attach/detach for all components contained within
  3760     * this fragment. Also do so recursively for all child
  3761     * fragments.
  3762     *
  3763     * @param {Function} hook
  3764     */
  3765  
  3766    Fragment.prototype.callHook = function (hook) {
  3767      var i, l;
  3768      for (i = 0, l = this.childFrags.length; i < l; i++) {
  3769        this.childFrags[i].callHook(hook);
  3770      }
  3771      for (i = 0, l = this.children.length; i < l; i++) {
  3772        hook(this.children[i]);
  3773      }
  3774    };
  3775  
  3776    /**
  3777     * Insert fragment before target, single node version
  3778     *
  3779     * @param {Node} target
  3780     * @param {Boolean} withTransition
  3781     */
  3782  
  3783    function singleBefore(target, withTransition) {
  3784      this.inserted = true;
  3785      var method = withTransition !== false ? beforeWithTransition : before;
  3786      method(this.node, target, this.vm);
  3787      if (inDoc(this.node)) {
  3788        this.callHook(attach);
  3789      }
  3790    }
  3791  
  3792    /**
  3793     * Remove fragment, single node version
  3794     */
  3795  
  3796    function singleRemove() {
  3797      this.inserted = false;
  3798      var shouldCallRemove = inDoc(this.node);
  3799      var self = this;
  3800      this.beforeRemove();
  3801      removeWithTransition(this.node, this.vm, function () {
  3802        if (shouldCallRemove) {
  3803          self.callHook(detach);
  3804        }
  3805        self.destroy();
  3806      });
  3807    }
  3808  
  3809    /**
  3810     * Insert fragment before target, multi-nodes version
  3811     *
  3812     * @param {Node} target
  3813     * @param {Boolean} withTransition
  3814     */
  3815  
  3816    function multiBefore(target, withTransition) {
  3817      this.inserted = true;
  3818      var vm = this.vm;
  3819      var method = withTransition !== false ? beforeWithTransition : before;
  3820      mapNodeRange(this.node, this.end, function (node) {
  3821        method(node, target, vm);
  3822      });
  3823      if (inDoc(this.node)) {
  3824        this.callHook(attach);
  3825      }
  3826    }
  3827  
  3828    /**
  3829     * Remove fragment, multi-nodes version
  3830     */
  3831  
  3832    function multiRemove() {
  3833      this.inserted = false;
  3834      var self = this;
  3835      var shouldCallRemove = inDoc(this.node);
  3836      this.beforeRemove();
  3837      removeNodeRange(this.node, this.end, this.vm, this.frag, function () {
  3838        if (shouldCallRemove) {
  3839          self.callHook(detach);
  3840        }
  3841        self.destroy();
  3842      });
  3843    }
  3844  
  3845    /**
  3846     * Prepare the fragment for removal.
  3847     */
  3848  
  3849    Fragment.prototype.beforeRemove = function () {
  3850      var i, l;
  3851      for (i = 0, l = this.childFrags.length; i < l; i++) {
  3852        // call the same method recursively on child
  3853        // fragments, depth-first
  3854        this.childFrags[i].beforeRemove(false);
  3855      }
  3856      for (i = 0, l = this.children.length; i < l; i++) {
  3857        // Call destroy for all contained instances,
  3858        // with remove:false and defer:true.
  3859        // Defer is necessary because we need to
  3860        // keep the children to call detach hooks
  3861        // on them.
  3862        this.children[i].$destroy(false, true);
  3863      }
  3864      var dirs = this.unlink.dirs;
  3865      for (i = 0, l = dirs.length; i < l; i++) {
  3866        // disable the watchers on all the directives
  3867        // so that the rendered content stays the same
  3868        // during removal.
  3869        dirs[i]._watcher && dirs[i]._watcher.teardown();
  3870      }
  3871    };
  3872  
  3873    /**
  3874     * Destroy the fragment.
  3875     */
  3876  
  3877    Fragment.prototype.destroy = function () {
  3878      if (this.parentFrag) {
  3879        this.parentFrag.childFrags.$remove(this);
  3880      }
  3881      this.node.__v_frag = null;
  3882      this.unlink();
  3883    };
  3884  
  3885    /**
  3886     * Call attach hook for a Vue instance.
  3887     *
  3888     * @param {Vue} child
  3889     */
  3890  
  3891    function attach(child) {
  3892      if (!child._isAttached && inDoc(child.$el)) {
  3893        child._callHook('attached');
  3894      }
  3895    }
  3896  
  3897    /**
  3898     * Call detach hook for a Vue instance.
  3899     *
  3900     * @param {Vue} child
  3901     */
  3902  
  3903    function detach(child) {
  3904      if (child._isAttached && !inDoc(child.$el)) {
  3905        child._callHook('detached');
  3906      }
  3907    }
  3908  
  3909    var linkerCache = new Cache(5000);
  3910  
  3911    /**
  3912     * A factory that can be used to create instances of a
  3913     * fragment. Caches the compiled linker if possible.
  3914     *
  3915     * @param {Vue} vm
  3916     * @param {Element|String} el
  3917     */
  3918    function FragmentFactory(vm, el) {
  3919      this.vm = vm;
  3920      var template;
  3921      var isString = typeof el === 'string';
  3922      if (isString || isTemplate(el) && !el.hasAttribute('v-if')) {
  3923        template = parseTemplate(el, true);
  3924      } else {
  3925        template = document.createDocumentFragment();
  3926        template.appendChild(el);
  3927      }
  3928      this.template = template;
  3929      // linker can be cached, but only for components
  3930      var linker;
  3931      var cid = vm.constructor.cid;
  3932      if (cid > 0) {
  3933        var cacheId = cid + (isString ? el : getOuterHTML(el));
  3934        linker = linkerCache.get(cacheId);
  3935        if (!linker) {
  3936          linker = compile(template, vm.$options, true);
  3937          linkerCache.put(cacheId, linker);
  3938        }
  3939      } else {
  3940        linker = compile(template, vm.$options, true);
  3941      }
  3942      this.linker = linker;
  3943    }
  3944  
  3945    /**
  3946     * Create a fragment instance with given host and scope.
  3947     *
  3948     * @param {Vue} host
  3949     * @param {Object} scope
  3950     * @param {Fragment} parentFrag
  3951     */
  3952  
  3953    FragmentFactory.prototype.create = function (host, scope, parentFrag) {
  3954      var frag = cloneNode(this.template);
  3955      return new Fragment(this.linker, this.vm, frag, host, scope, parentFrag);
  3956    };
  3957  
  3958    var ON = 700;
  3959    var MODEL = 800;
  3960    var BIND = 850;
  3961    var TRANSITION = 1100;
  3962    var EL = 1500;
  3963    var COMPONENT = 1500;
  3964    var PARTIAL = 1750;
  3965    var IF = 2100;
  3966    var FOR = 2200;
  3967    var SLOT = 2300;
  3968  
  3969    var uid$3 = 0;
  3970  
  3971    var vFor = {
  3972  
  3973      priority: FOR,
  3974      terminal: true,
  3975  
  3976      params: ['track-by', 'stagger', 'enter-stagger', 'leave-stagger'],
  3977  
  3978      bind: function bind() {
  3979        // support "item in/of items" syntax
  3980        var inMatch = this.expression.match(/(.*) (?:in|of) (.*)/);
  3981        if (inMatch) {
  3982          var itMatch = inMatch[1].match(/\((.*),(.*)\)/);
  3983          if (itMatch) {
  3984            this.iterator = itMatch[1].trim();
  3985            this.alias = itMatch[2].trim();
  3986          } else {
  3987            this.alias = inMatch[1].trim();
  3988          }
  3989          this.expression = inMatch[2];
  3990        }
  3991  
  3992        if (!this.alias) {
  3993          'development' !== 'production' && warn('Invalid v-for expression "' + this.descriptor.raw + '": ' + 'alias is required.', this.vm);
  3994          return;
  3995        }
  3996  
  3997        // uid as a cache identifier
  3998        this.id = '__v-for__' + ++uid$3;
  3999  
  4000        // check if this is an option list,
  4001        // so that we know if we need to update the <select>'s
  4002        // v-model when the option list has changed.
  4003        // because v-model has a lower priority than v-for,
  4004        // the v-model is not bound here yet, so we have to
  4005        // retrive it in the actual updateModel() function.
  4006        var tag = this.el.tagName;
  4007        this.isOption = (tag === 'OPTION' || tag === 'OPTGROUP') && this.el.parentNode.tagName === 'SELECT';
  4008  
  4009        // setup anchor nodes
  4010        this.start = createAnchor('v-for-start');
  4011        this.end = createAnchor('v-for-end');
  4012        replace(this.el, this.end);
  4013        before(this.start, this.end);
  4014  
  4015        // cache
  4016        this.cache = Object.create(null);
  4017  
  4018        // fragment factory
  4019        this.factory = new FragmentFactory(this.vm, this.el);
  4020      },
  4021  
  4022      update: function update(data) {
  4023        this.diff(data);
  4024        this.updateRef();
  4025        this.updateModel();
  4026      },
  4027  
  4028      /**
  4029       * Diff, based on new data and old data, determine the
  4030       * minimum amount of DOM manipulations needed to make the
  4031       * DOM reflect the new data Array.
  4032       *
  4033       * The algorithm diffs the new data Array by storing a
  4034       * hidden reference to an owner vm instance on previously
  4035       * seen data. This allows us to achieve O(n) which is
  4036       * better than a levenshtein distance based algorithm,
  4037       * which is O(m * n).
  4038       *
  4039       * @param {Array} data
  4040       */
  4041  
  4042      diff: function diff(data) {
  4043        // check if the Array was converted from an Object
  4044        var item = data[0];
  4045        var convertedFromObject = this.fromObject = isObject(item) && hasOwn(item, '$key') && hasOwn(item, '$value');
  4046  
  4047        var trackByKey = this.params.trackBy;
  4048        var oldFrags = this.frags;
  4049        var frags = this.frags = new Array(data.length);
  4050        var alias = this.alias;
  4051        var iterator = this.iterator;
  4052        var start = this.start;
  4053        var end = this.end;
  4054        var inDocument = inDoc(start);
  4055        var init = !oldFrags;
  4056        var i, l, frag, key, value, primitive;
  4057  
  4058        // First pass, go through the new Array and fill up
  4059        // the new frags array. If a piece of data has a cached
  4060        // instance for it, we reuse it. Otherwise build a new
  4061        // instance.
  4062        for (i = 0, l = data.length; i < l; i++) {
  4063          item = data[i];
  4064          key = convertedFromObject ? item.$key : null;
  4065          value = convertedFromObject ? item.$value : item;
  4066          primitive = !isObject(value);
  4067          frag = !init && this.getCachedFrag(value, i, key);
  4068          if (frag) {
  4069            // reusable fragment
  4070            frag.reused = true;
  4071            // update $index
  4072            frag.scope.$index = i;
  4073            // update $key
  4074            if (key) {
  4075              frag.scope.$key = key;
  4076            }
  4077            // update iterator
  4078            if (iterator) {
  4079              frag.scope[iterator] = key !== null ? key : i;
  4080            }
  4081            // update data for track-by, object repeat &
  4082            // primitive values.
  4083            if (trackByKey || convertedFromObject || primitive) {
  4084              withoutConversion(function () {
  4085                frag.scope[alias] = value;
  4086              });
  4087            }
  4088          } else {
  4089            // new isntance
  4090            frag = this.create(value, alias, i, key);
  4091            frag.fresh = !init;
  4092          }
  4093          frags[i] = frag;
  4094          if (init) {
  4095            frag.before(end);
  4096          }
  4097        }
  4098  
  4099        // we're done for the initial render.
  4100        if (init) {
  4101          return;
  4102        }
  4103  
  4104        // Second pass, go through the old fragments and
  4105        // destroy those who are not reused (and remove them
  4106        // from cache)
  4107        var removalIndex = 0;
  4108        var totalRemoved = oldFrags.length - frags.length;
  4109        // when removing a large number of fragments, watcher removal
  4110        // turns out to be a perf bottleneck, so we batch the watcher
  4111        // removals into a single filter call!
  4112        this.vm._vForRemoving = true;
  4113        for (i = 0, l = oldFrags.length; i < l; i++) {
  4114          frag = oldFrags[i];
  4115          if (!frag.reused) {
  4116            this.deleteCachedFrag(frag);
  4117            this.remove(frag, removalIndex++, totalRemoved, inDocument);
  4118          }
  4119        }
  4120        this.vm._vForRemoving = false;
  4121        if (removalIndex) {
  4122          this.vm._watchers = this.vm._watchers.filter(function (w) {
  4123            return w.active;
  4124          });
  4125        }
  4126  
  4127        // Final pass, move/insert new fragments into the
  4128        // right place.
  4129        var targetPrev, prevEl, currentPrev;
  4130        var insertionIndex = 0;
  4131        for (i = 0, l = frags.length; i < l; i++) {
  4132          frag = frags[i];
  4133          // this is the frag that we should be after
  4134          targetPrev = frags[i - 1];
  4135          prevEl = targetPrev ? targetPrev.staggerCb ? targetPrev.staggerAnchor : targetPrev.end || targetPrev.node : start;
  4136          if (frag.reused && !frag.staggerCb) {
  4137            currentPrev = findPrevFrag(frag, start, this.id);
  4138            if (currentPrev !== targetPrev && (!currentPrev ||
  4139            // optimization for moving a single item.
  4140            // thanks to suggestions by @livoras in #1807
  4141            findPrevFrag(currentPrev, start, this.id) !== targetPrev)) {
  4142              this.move(frag, prevEl);
  4143            }
  4144          } else {
  4145            // new instance, or still in stagger.
  4146            // insert with updated stagger index.
  4147            this.insert(frag, insertionIndex++, prevEl, inDocument);
  4148          }
  4149          frag.reused = frag.fresh = false;
  4150        }
  4151      },
  4152  
  4153      /**
  4154       * Create a new fragment instance.
  4155       *
  4156       * @param {*} value
  4157       * @param {String} alias
  4158       * @param {Number} index
  4159       * @param {String} [key]
  4160       * @return {Fragment}
  4161       */
  4162  
  4163      create: function create(value, alias, index, key) {
  4164        var host = this._host;
  4165        // create iteration scope
  4166        var parentScope = this._scope || this.vm;
  4167        var scope = Object.create(parentScope);
  4168        // ref holder for the scope
  4169        scope.$refs = Object.create(parentScope.$refs);
  4170        scope.$els = Object.create(parentScope.$els);
  4171        // make sure point $parent to parent scope
  4172        scope.$parent = parentScope;
  4173        // for two-way binding on alias
  4174        scope.$forContext = this;
  4175        // define scope properties
  4176        // important: define the scope alias without forced conversion
  4177        // so that frozen data structures remain non-reactive.
  4178        withoutConversion(function () {
  4179          defineReactive(scope, alias, value);
  4180        });
  4181        defineReactive(scope, '$index', index);
  4182        if (key) {
  4183          defineReactive(scope, '$key', key);
  4184        } else if (scope.$key) {
  4185          // avoid accidental fallback
  4186          def(scope, '$key', null);
  4187        }
  4188        if (this.iterator) {
  4189          defineReactive(scope, this.iterator, key !== null ? key : index);
  4190        }
  4191        var frag = this.factory.create(host, scope, this._frag);
  4192        frag.forId = this.id;
  4193        this.cacheFrag(value, frag, index, key);
  4194        return frag;
  4195      },
  4196  
  4197      /**
  4198       * Update the v-ref on owner vm.
  4199       */
  4200  
  4201      updateRef: function updateRef() {
  4202        var ref = this.descriptor.ref;
  4203        if (!ref) return;
  4204        var hash = (this._scope || this.vm).$refs;
  4205        var refs;
  4206        if (!this.fromObject) {
  4207          refs = this.frags.map(findVmFromFrag);
  4208        } else {
  4209          refs = {};
  4210          this.frags.forEach(function (frag) {
  4211            refs[frag.scope.$key] = findVmFromFrag(frag);
  4212          });
  4213        }
  4214        hash[ref] = refs;
  4215      },
  4216  
  4217      /**
  4218       * For option lists, update the containing v-model on
  4219       * parent <select>.
  4220       */
  4221  
  4222      updateModel: function updateModel() {
  4223        if (this.isOption) {
  4224          var parent = this.start.parentNode;
  4225          var model = parent && parent.__v_model;
  4226          if (model) {
  4227            model.forceUpdate();
  4228          }
  4229        }
  4230      },
  4231  
  4232      /**
  4233       * Insert a fragment. Handles staggering.
  4234       *
  4235       * @param {Fragment} frag
  4236       * @param {Number} index
  4237       * @param {Node} prevEl
  4238       * @param {Boolean} inDocument
  4239       */
  4240  
  4241      insert: function insert(frag, index, prevEl, inDocument) {
  4242        if (frag.staggerCb) {
  4243          frag.staggerCb.cancel();
  4244          frag.staggerCb = null;
  4245        }
  4246        var staggerAmount = this.getStagger(frag, index, null, 'enter');
  4247        if (inDocument && staggerAmount) {
  4248          // create an anchor and insert it synchronously,
  4249          // so that we can resolve the correct order without
  4250          // worrying about some elements not inserted yet
  4251          var anchor = frag.staggerAnchor;
  4252          if (!anchor) {
  4253            anchor = frag.staggerAnchor = createAnchor('stagger-anchor');
  4254            anchor.__v_frag = frag;
  4255          }
  4256          after(anchor, prevEl);
  4257          var op = frag.staggerCb = cancellable(function () {
  4258            frag.staggerCb = null;
  4259            frag.before(anchor);
  4260            remove(anchor);
  4261          });
  4262          setTimeout(op, staggerAmount);
  4263        } else {
  4264          var target = prevEl.nextSibling;
  4265          /* istanbul ignore if */
  4266          if (!target) {
  4267            // reset end anchor position in case the position was messed up
  4268            // by an external drag-n-drop library.
  4269            after(this.end, prevEl);
  4270            target = this.end;
  4271          }
  4272          frag.before(target);
  4273        }
  4274      },
  4275  
  4276      /**
  4277       * Remove a fragment. Handles staggering.
  4278       *
  4279       * @param {Fragment} frag
  4280       * @param {Number} index
  4281       * @param {Number} total
  4282       * @param {Boolean} inDocument
  4283       */
  4284  
  4285      remove: function remove(frag, index, total, inDocument) {
  4286        if (frag.staggerCb) {
  4287          frag.staggerCb.cancel();
  4288          frag.staggerCb = null;
  4289          // it's not possible for the same frag to be removed
  4290          // twice, so if we have a pending stagger callback,
  4291          // it means this frag is queued for enter but removed
  4292          // before its transition started. Since it is already
  4293          // destroyed, we can just leave it in detached state.
  4294          return;
  4295        }
  4296        var staggerAmount = this.getStagger(frag, index, total, 'leave');
  4297        if (inDocument && staggerAmount) {
  4298          var op = frag.staggerCb = cancellable(function () {
  4299            frag.staggerCb = null;
  4300            frag.remove();
  4301          });
  4302          setTimeout(op, staggerAmount);
  4303        } else {
  4304          frag.remove();
  4305        }
  4306      },
  4307  
  4308      /**
  4309       * Move a fragment to a new position.
  4310       * Force no transition.
  4311       *
  4312       * @param {Fragment} frag
  4313       * @param {Node} prevEl
  4314       */
  4315  
  4316      move: function move(frag, prevEl) {
  4317        // fix a common issue with Sortable:
  4318        // if prevEl doesn't have nextSibling, this means it's
  4319        // been dragged after the end anchor. Just re-position
  4320        // the end anchor to the end of the container.
  4321        /* istanbul ignore if */
  4322        if (!prevEl.nextSibling) {
  4323          this.end.parentNode.appendChild(this.end);
  4324        }
  4325        frag.before(prevEl.nextSibling, false);
  4326      },
  4327  
  4328      /**
  4329       * Cache a fragment using track-by or the object key.
  4330       *
  4331       * @param {*} value
  4332       * @param {Fragment} frag
  4333       * @param {Number} index
  4334       * @param {String} [key]
  4335       */
  4336  
  4337      cacheFrag: function cacheFrag(value, frag, index, key) {
  4338        var trackByKey = this.params.trackBy;
  4339        var cache = this.cache;
  4340        var primitive = !isObject(value);
  4341        var id;
  4342        if (key || trackByKey || primitive) {
  4343          id = getTrackByKey(index, key, value, trackByKey);
  4344          if (!cache[id]) {
  4345            cache[id] = frag;
  4346          } else if (trackByKey !== '$index') {
  4347            'development' !== 'production' && this.warnDuplicate(value);
  4348          }
  4349        } else {
  4350          id = this.id;
  4351          if (hasOwn(value, id)) {
  4352            if (value[id] === null) {
  4353              value[id] = frag;
  4354            } else {
  4355              'development' !== 'production' && this.warnDuplicate(value);
  4356            }
  4357          } else if (Object.isExtensible(value)) {
  4358            def(value, id, frag);
  4359          } else if ('development' !== 'production') {
  4360            warn('Frozen v-for objects cannot be automatically tracked, make sure to ' + 'provide a track-by key.');
  4361          }
  4362        }
  4363        frag.raw = value;
  4364      },
  4365  
  4366      /**
  4367       * Get a cached fragment from the value/index/key
  4368       *
  4369       * @param {*} value
  4370       * @param {Number} index
  4371       * @param {String} key
  4372       * @return {Fragment}
  4373       */
  4374  
  4375      getCachedFrag: function getCachedFrag(value, index, key) {
  4376        var trackByKey = this.params.trackBy;
  4377        var primitive = !isObject(value);
  4378        var frag;
  4379        if (key || trackByKey || primitive) {
  4380          var id = getTrackByKey(index, key, value, trackByKey);
  4381          frag = this.cache[id];
  4382        } else {
  4383          frag = value[this.id];
  4384        }
  4385        if (frag && (frag.reused || frag.fresh)) {
  4386          'development' !== 'production' && this.warnDuplicate(value);
  4387        }
  4388        return frag;
  4389      },
  4390  
  4391      /**
  4392       * Delete a fragment from cache.
  4393       *
  4394       * @param {Fragment} frag
  4395       */
  4396  
  4397      deleteCachedFrag: function deleteCachedFrag(frag) {
  4398        var value = frag.raw;
  4399        var trackByKey = this.params.trackBy;
  4400        var scope = frag.scope;
  4401        var index = scope.$index;
  4402        // fix #948: avoid accidentally fall through to
  4403        // a parent repeater which happens to have $key.
  4404        var key = hasOwn(scope, '$key') && scope.$key;
  4405        var primitive = !isObject(value);
  4406        if (trackByKey || key || primitive) {
  4407          var id = getTrackByKey(index, key, value, trackByKey);
  4408          this.cache[id] = null;
  4409        } else {
  4410          value[this.id] = null;
  4411          frag.raw = null;
  4412        }
  4413      },
  4414  
  4415      /**
  4416       * Get the stagger amount for an insertion/removal.
  4417       *
  4418       * @param {Fragment} frag
  4419       * @param {Number} index
  4420       * @param {Number} total
  4421       * @param {String} type
  4422       */
  4423  
  4424      getStagger: function getStagger(frag, index, total, type) {
  4425        type = type + 'Stagger';
  4426        var trans = frag.node.__v_trans;
  4427        var hooks = trans && trans.hooks;
  4428        var hook = hooks && (hooks[type] || hooks.stagger);
  4429        return hook ? hook.call(frag, index, total) : index * parseInt(this.params[type] || this.params.stagger, 10);
  4430      },
  4431  
  4432      /**
  4433       * Pre-process the value before piping it through the
  4434       * filters. This is passed to and called by the watcher.
  4435       */
  4436  
  4437      _preProcess: function _preProcess(value) {
  4438        // regardless of type, store the un-filtered raw value.
  4439        this.rawValue = value;
  4440        return value;
  4441      },
  4442  
  4443      /**
  4444       * Post-process the value after it has been piped through
  4445       * the filters. This is passed to and called by the watcher.
  4446       *
  4447       * It is necessary for this to be called during the
  4448       * wathcer's dependency collection phase because we want
  4449       * the v-for to update when the source Object is mutated.
  4450       */
  4451  
  4452      _postProcess: function _postProcess(value) {
  4453        if (isArray(value)) {
  4454          return value;
  4455        } else if (isPlainObject(value)) {
  4456          // convert plain object to array.
  4457          var keys = Object.keys(value);
  4458          var i = keys.length;
  4459          var res = new Array(i);
  4460          var key;
  4461          while (i--) {
  4462            key = keys[i];
  4463            res[i] = {
  4464              $key: key,
  4465              $value: value[key]
  4466            };
  4467          }
  4468          return res;
  4469        } else {
  4470          if (typeof value === 'number' && !isNaN(value)) {
  4471            value = range(value);
  4472          }
  4473          return value || [];
  4474        }
  4475      },
  4476  
  4477      unbind: function unbind() {
  4478        if (this.descriptor.ref) {
  4479          (this._scope || this.vm).$refs[this.descriptor.ref] = null;
  4480        }
  4481        if (this.frags) {
  4482          var i = this.frags.length;
  4483          var frag;
  4484          while (i--) {
  4485            frag = this.frags[i];
  4486            this.deleteCachedFrag(frag);
  4487            frag.destroy();
  4488          }
  4489        }
  4490      }
  4491    };
  4492  
  4493    /**
  4494     * Helper to find the previous element that is a fragment
  4495     * anchor. This is necessary because a destroyed frag's
  4496     * element could still be lingering in the DOM before its
  4497     * leaving transition finishes, but its inserted flag
  4498     * should have been set to false so we can skip them.
  4499     *
  4500     * If this is a block repeat, we want to make sure we only
  4501     * return frag that is bound to this v-for. (see #929)
  4502     *
  4503     * @param {Fragment} frag
  4504     * @param {Comment|Text} anchor
  4505     * @param {String} id
  4506     * @return {Fragment}
  4507     */
  4508  
  4509    function findPrevFrag(frag, anchor, id) {
  4510      var el = frag.node.previousSibling;
  4511      /* istanbul ignore if */
  4512      if (!el) return;
  4513      frag = el.__v_frag;
  4514      while ((!frag || frag.forId !== id || !frag.inserted) && el !== anchor) {
  4515        el = el.previousSibling;
  4516        /* istanbul ignore if */
  4517        if (!el) return;
  4518        frag = el.__v_frag;
  4519      }
  4520      return frag;
  4521    }
  4522  
  4523    /**
  4524     * Find a vm from a fragment.
  4525     *
  4526     * @param {Fragment} frag
  4527     * @return {Vue|undefined}
  4528     */
  4529  
  4530    function findVmFromFrag(frag) {
  4531      var node = frag.node;
  4532      // handle multi-node frag
  4533      if (frag.end) {
  4534        while (!node.__vue__ && node !== frag.end && node.nextSibling) {
  4535          node = node.nextSibling;
  4536        }
  4537      }
  4538      return node.__vue__;
  4539    }
  4540  
  4541    /**
  4542     * Create a range array from given number.
  4543     *
  4544     * @param {Number} n
  4545     * @return {Array}
  4546     */
  4547  
  4548    function range(n) {
  4549      var i = -1;
  4550      var ret = new Array(Math.floor(n));
  4551      while (++i < n) {
  4552        ret[i] = i;
  4553      }
  4554      return ret;
  4555    }
  4556  
  4557    /**
  4558     * Get the track by key for an item.
  4559     *
  4560     * @param {Number} index
  4561     * @param {String} key
  4562     * @param {*} value
  4563     * @param {String} [trackByKey]
  4564     */
  4565  
  4566    function getTrackByKey(index, key, value, trackByKey) {
  4567      return trackByKey ? trackByKey === '$index' ? index : trackByKey.charAt(0).match(/\w/) ? getPath(value, trackByKey) : value[trackByKey] : key || value;
  4568    }
  4569  
  4570    if ('development' !== 'production') {
  4571      vFor.warnDuplicate = function (value) {
  4572        warn('Duplicate value found in v-for="' + this.descriptor.raw + '": ' + JSON.stringify(value) + '. Use track-by="$index" if ' + 'you are expecting duplicate values.', this.vm);
  4573      };
  4574    }
  4575  
  4576    var vIf = {
  4577  
  4578      priority: IF,
  4579      terminal: true,
  4580  
  4581      bind: function bind() {
  4582        var el = this.el;
  4583        if (!el.__vue__) {
  4584          // check else block
  4585          var next = el.nextElementSibling;
  4586          if (next && getAttr(next, 'v-else') !== null) {
  4587            remove(next);
  4588            this.elseEl = next;
  4589          }
  4590          // check main block
  4591          this.anchor = createAnchor('v-if');
  4592          replace(el, this.anchor);
  4593        } else {
  4594          'development' !== 'production' && warn('v-if="' + this.expression + '" cannot be ' + 'used on an instance root element.', this.vm);
  4595          this.invalid = true;
  4596        }
  4597      },
  4598  
  4599      update: function update(value) {
  4600        if (this.invalid) return;
  4601        if (value) {
  4602          if (!this.frag) {
  4603            this.insert();
  4604          }
  4605        } else {
  4606          this.remove();
  4607        }
  4608      },
  4609  
  4610      insert: function insert() {
  4611        if (this.elseFrag) {
  4612          this.elseFrag.remove();
  4613          this.elseFrag = null;
  4614        }
  4615        // lazy init factory
  4616        if (!this.factory) {
  4617          this.factory = new FragmentFactory(this.vm, this.el);
  4618        }
  4619        this.frag = this.factory.create(this._host, this._scope, this._frag);
  4620        this.frag.before(this.anchor);
  4621      },
  4622  
  4623      remove: function remove() {
  4624        if (this.frag) {
  4625          this.frag.remove();
  4626          this.frag = null;
  4627        }
  4628        if (this.elseEl && !this.elseFrag) {
  4629          if (!this.elseFactory) {
  4630            this.elseFactory = new FragmentFactory(this.elseEl._context || this.vm, this.elseEl);
  4631          }
  4632          this.elseFrag = this.elseFactory.create(this._host, this._scope, this._frag);
  4633          this.elseFrag.before(this.anchor);
  4634        }
  4635      },
  4636  
  4637      unbind: function unbind() {
  4638        if (this.frag) {
  4639          this.frag.destroy();
  4640        }
  4641        if (this.elseFrag) {
  4642          this.elseFrag.destroy();
  4643        }
  4644      }
  4645    };
  4646  
  4647    var show = {
  4648  
  4649      bind: function bind() {
  4650        // check else block
  4651        var next = this.el.nextElementSibling;
  4652        if (next && getAttr(next, 'v-else') !== null) {
  4653          this.elseEl = next;
  4654        }
  4655      },
  4656  
  4657      update: function update(value) {
  4658        this.apply(this.el, value);
  4659        if (this.elseEl) {
  4660          this.apply(this.elseEl, !value);
  4661        }
  4662      },
  4663  
  4664      apply: function apply(el, value) {
  4665        if (inDoc(el)) {
  4666          applyTransition(el, value ? 1 : -1, toggle, this.vm);
  4667        } else {
  4668          toggle();
  4669        }
  4670        function toggle() {
  4671          el.style.display = value ? '' : 'none';
  4672        }
  4673      }
  4674    };
  4675  
  4676    var text$2 = {
  4677  
  4678      bind: function bind() {
  4679        var self = this;
  4680        var el = this.el;
  4681        var isRange = el.type === 'range';
  4682        var lazy = this.params.lazy;
  4683        var number = this.params.number;
  4684        var debounce = this.params.debounce;
  4685  
  4686        // handle composition events.
  4687        //   http://blog.evanyou.me/2014/01/03/composition-event/
  4688        // skip this for Android because it handles composition
  4689        // events quite differently. Android doesn't trigger
  4690        // composition events for language input methods e.g.
  4691        // Chinese, but instead triggers them for spelling
  4692        // suggestions... (see Discussion/#162)
  4693        var composing = false;
  4694        if (!isAndroid && !isRange) {
  4695          this.on('compositionstart', function () {
  4696            composing = true;
  4697          });
  4698          this.on('compositionend', function () {
  4699            composing = false;
  4700            // in IE11 the "compositionend" event fires AFTER
  4701            // the "input" event, so the input handler is blocked
  4702            // at the end... have to call it here.
  4703            //
  4704            // #1327: in lazy mode this is unecessary.
  4705            if (!lazy) {
  4706              self.listener();
  4707            }
  4708          });
  4709        }
  4710  
  4711        // prevent messing with the input when user is typing,
  4712        // and force update on blur.
  4713        this.focused = false;
  4714        if (!isRange && !lazy) {
  4715          this.on('focus', function () {
  4716            self.focused = true;
  4717          });
  4718          this.on('blur', function () {
  4719            self.focused = false;
  4720            // do not sync value after fragment removal (#2017)
  4721            if (!self._frag || self._frag.inserted) {
  4722              self.rawListener();
  4723            }
  4724          });
  4725        }
  4726  
  4727        // Now attach the main listener
  4728        this.listener = this.rawListener = function () {
  4729          if (composing || !self._bound) {
  4730            return;
  4731          }
  4732          var val = number || isRange ? toNumber(el.value) : el.value;
  4733          self.set(val);
  4734          // force update on next tick to avoid lock & same value
  4735          // also only update when user is not typing
  4736          nextTick(function () {
  4737            if (self._bound && !self.focused) {
  4738              self.update(self._watcher.value);
  4739            }
  4740          });
  4741        };
  4742  
  4743        // apply debounce
  4744        if (debounce) {
  4745          this.listener = _debounce(this.listener, debounce);
  4746        }
  4747  
  4748        // Support jQuery events, since jQuery.trigger() doesn't
  4749        // trigger native events in some cases and some plugins
  4750        // rely on $.trigger()
  4751        //
  4752        // We want to make sure if a listener is attached using
  4753        // jQuery, it is also removed with jQuery, that's why
  4754        // we do the check for each directive instance and
  4755        // store that check result on itself. This also allows
  4756        // easier test coverage control by unsetting the global
  4757        // jQuery variable in tests.
  4758        this.hasjQuery = typeof jQuery === 'function';
  4759        if (this.hasjQuery) {
  4760          var method = jQuery.fn.on ? 'on' : 'bind';
  4761          jQuery(el)[method]('change', this.rawListener);
  4762          if (!lazy) {
  4763            jQuery(el)[method]('input', this.listener);
  4764          }
  4765        } else {
  4766          this.on('change', this.rawListener);
  4767          if (!lazy) {
  4768            this.on('input', this.listener);
  4769          }
  4770        }
  4771  
  4772        // IE9 doesn't fire input event on backspace/del/cut
  4773        if (!lazy && isIE9) {
  4774          this.on('cut', function () {
  4775            nextTick(self.listener);
  4776          });
  4777          this.on('keyup', function (e) {
  4778            if (e.keyCode === 46 || e.keyCode === 8) {
  4779              self.listener();
  4780            }
  4781          });
  4782        }
  4783  
  4784        // set initial value if present
  4785        if (el.hasAttribute('value') || el.tagName === 'TEXTAREA' && el.value.trim()) {
  4786          this.afterBind = this.listener;
  4787        }
  4788      },
  4789  
  4790      update: function update(value) {
  4791        this.el.value = _toString(value);
  4792      },
  4793  
  4794      unbind: function unbind() {
  4795        var el = this.el;
  4796        if (this.hasjQuery) {
  4797          var method = jQuery.fn.off ? 'off' : 'unbind';
  4798          jQuery(el)[method]('change', this.listener);
  4799          jQuery(el)[method]('input', this.listener);
  4800        }
  4801      }
  4802    };
  4803  
  4804    var radio = {
  4805  
  4806      bind: function bind() {
  4807        var self = this;
  4808        var el = this.el;
  4809  
  4810        this.getValue = function () {
  4811          // value overwrite via v-bind:value
  4812          if (el.hasOwnProperty('_value')) {
  4813            return el._value;
  4814          }
  4815          var val = el.value;
  4816          if (self.params.number) {
  4817            val = toNumber(val);
  4818          }
  4819          return val;
  4820        };
  4821  
  4822        this.listener = function () {
  4823          self.set(self.getValue());
  4824        };
  4825        this.on('change', this.listener);
  4826  
  4827        if (el.hasAttribute('checked')) {
  4828          this.afterBind = this.listener;
  4829        }
  4830      },
  4831  
  4832      update: function update(value) {
  4833        this.el.checked = looseEqual(value, this.getValue());
  4834      }
  4835    };
  4836  
  4837    var select = {
  4838  
  4839      bind: function bind() {
  4840        var self = this;
  4841        var el = this.el;
  4842  
  4843        // method to force update DOM using latest value.
  4844        this.forceUpdate = function () {
  4845          if (self._watcher) {
  4846            self.update(self._watcher.get());
  4847          }
  4848        };
  4849  
  4850        // check if this is a multiple select
  4851        var multiple = this.multiple = el.hasAttribute('multiple');
  4852  
  4853        // attach listener
  4854        this.listener = function () {
  4855          var value = getValue(el, multiple);
  4856          value = self.params.number ? isArray(value) ? value.map(toNumber) : toNumber(value) : value;
  4857          self.set(value);
  4858        };
  4859        this.on('change', this.listener);
  4860  
  4861        // if has initial value, set afterBind
  4862        var initValue = getValue(el, multiple, true);
  4863        if (multiple && initValue.length || !multiple && initValue !== null) {
  4864          this.afterBind = this.listener;
  4865        }
  4866  
  4867        // All major browsers except Firefox resets
  4868        // selectedIndex with value -1 to 0 when the element
  4869        // is appended to a new parent, therefore we have to
  4870        // force a DOM update whenever that happens...
  4871        this.vm.$on('hook:attached', this.forceUpdate);
  4872      },
  4873  
  4874      update: function update(value) {
  4875        var el = this.el;
  4876        el.selectedIndex = -1;
  4877        var multi = this.multiple && isArray(value);
  4878        var options = el.options;
  4879        var i = options.length;
  4880        var op, val;
  4881        while (i--) {
  4882          op = options[i];
  4883          val = op.hasOwnProperty('_value') ? op._value : op.value;
  4884          /* eslint-disable eqeqeq */
  4885          op.selected = multi ? indexOf$1(value, val) > -1 : looseEqual(value, val);
  4886          /* eslint-enable eqeqeq */
  4887        }
  4888      },
  4889  
  4890      unbind: function unbind() {
  4891        /* istanbul ignore next */
  4892        this.vm.$off('hook:attached', this.forceUpdate);
  4893      }
  4894    };
  4895  
  4896    /**
  4897     * Get select value
  4898     *
  4899     * @param {SelectElement} el
  4900     * @param {Boolean} multi
  4901     * @param {Boolean} init
  4902     * @return {Array|*}
  4903     */
  4904  
  4905    function getValue(el, multi, init) {
  4906      var res = multi ? [] : null;
  4907      var op, val, selected;
  4908      for (var i = 0, l = el.options.length; i < l; i++) {
  4909        op = el.options[i];
  4910        selected = init ? op.hasAttribute('selected') : op.selected;
  4911        if (selected) {
  4912          val = op.hasOwnProperty('_value') ? op._value : op.value;
  4913          if (multi) {
  4914            res.push(val);
  4915          } else {
  4916            return val;
  4917          }
  4918        }
  4919      }
  4920      return res;
  4921    }
  4922  
  4923    /**
  4924     * Native Array.indexOf uses strict equal, but in this
  4925     * case we need to match string/numbers with custom equal.
  4926     *
  4927     * @param {Array} arr
  4928     * @param {*} val
  4929     */
  4930  
  4931    function indexOf$1(arr, val) {
  4932      var i = arr.length;
  4933      while (i--) {
  4934        if (looseEqual(arr[i], val)) {
  4935          return i;
  4936        }
  4937      }
  4938      return -1;
  4939    }
  4940  
  4941    var checkbox = {
  4942  
  4943      bind: function bind() {
  4944        var self = this;
  4945        var el = this.el;
  4946  
  4947        this.getValue = function () {
  4948          return el.hasOwnProperty('_value') ? el._value : self.params.number ? toNumber(el.value) : el.value;
  4949        };
  4950  
  4951        function getBooleanValue() {
  4952          var val = el.checked;
  4953          if (val && el.hasOwnProperty('_trueValue')) {
  4954            return el._trueValue;
  4955          }
  4956          if (!val && el.hasOwnProperty('_falseValue')) {
  4957            return el._falseValue;
  4958          }
  4959          return val;
  4960        }
  4961  
  4962        this.listener = function () {
  4963          var model = self._watcher.value;
  4964          if (isArray(model)) {
  4965            var val = self.getValue();
  4966            if (el.checked) {
  4967              if (indexOf(model, val) < 0) {
  4968                model.push(val);
  4969              }
  4970            } else {
  4971              model.$remove(val);
  4972            }
  4973          } else {
  4974            self.set(getBooleanValue());
  4975          }
  4976        };
  4977  
  4978        this.on('change', this.listener);
  4979        if (el.hasAttribute('checked')) {
  4980          this.afterBind = this.listener;
  4981        }
  4982      },
  4983  
  4984      update: function update(value) {
  4985        var el = this.el;
  4986        if (isArray(value)) {
  4987          el.checked = indexOf(value, this.getValue()) > -1;
  4988        } else {
  4989          if (el.hasOwnProperty('_trueValue')) {
  4990            el.checked = looseEqual(value, el._trueValue);
  4991          } else {
  4992            el.checked = !!value;
  4993          }
  4994        }
  4995      }
  4996    };
  4997  
  4998    var handlers = {
  4999      text: text$2,
  5000      radio: radio,
  5001      select: select,
  5002      checkbox: checkbox
  5003    };
  5004  
  5005    var model = {
  5006  
  5007      priority: MODEL,
  5008      twoWay: true,
  5009      handlers: handlers,
  5010      params: ['lazy', 'number', 'debounce'],
  5011  
  5012      /**
  5013       * Possible elements:
  5014       *   <select>
  5015       *   <textarea>
  5016       *   <input type="*">
  5017       *     - text
  5018       *     - checkbox
  5019       *     - radio
  5020       *     - number
  5021       */
  5022  
  5023      bind: function bind() {
  5024        // friendly warning...
  5025        this.checkFilters();
  5026        if (this.hasRead && !this.hasWrite) {
  5027          'development' !== 'production' && warn('It seems you are using a read-only filter with ' + 'v-model="' + this.descriptor.raw + '". ' + 'You might want to use a two-way filter to ensure correct behavior.', this.vm);
  5028        }
  5029        var el = this.el;
  5030        var tag = el.tagName;
  5031        var handler;
  5032        if (tag === 'INPUT') {
  5033          handler = handlers[el.type] || handlers.text;
  5034        } else if (tag === 'SELECT') {
  5035          handler = handlers.select;
  5036        } else if (tag === 'TEXTAREA') {
  5037          handler = handlers.text;
  5038        } else {
  5039          'development' !== 'production' && warn('v-model does not support element type: ' + tag, this.vm);
  5040          return;
  5041        }
  5042        el.__v_model = this;
  5043        handler.bind.call(this);
  5044        this.update = handler.update;
  5045        this._unbind = handler.unbind;
  5046      },
  5047  
  5048      /**
  5049       * Check read/write filter stats.
  5050       */
  5051  
  5052      checkFilters: function checkFilters() {
  5053        var filters = this.filters;
  5054        if (!filters) return;
  5055        var i = filters.length;
  5056        while (i--) {
  5057          var filter = resolveAsset(this.vm.$options, 'filters', filters[i].name);
  5058          if (typeof filter === 'function' || filter.read) {
  5059            this.hasRead = true;
  5060          }
  5061          if (filter.write) {
  5062            this.hasWrite = true;
  5063          }
  5064        }
  5065      },
  5066  
  5067      unbind: function unbind() {
  5068        this.el.__v_model = null;
  5069        this._unbind && this._unbind();
  5070      }
  5071    };
  5072  
  5073    // keyCode aliases
  5074    var keyCodes = {
  5075      esc: 27,
  5076      tab: 9,
  5077      enter: 13,
  5078      space: 32,
  5079      'delete': [8, 46],
  5080      up: 38,
  5081      left: 37,
  5082      right: 39,
  5083      down: 40
  5084    };
  5085  
  5086    function keyFilter(handler, keys) {
  5087      var codes = keys.map(function (key) {
  5088        var charCode = key.charCodeAt(0);
  5089        if (charCode > 47 && charCode < 58) {
  5090          return parseInt(key, 10);
  5091        }
  5092        if (key.length === 1) {
  5093          charCode = key.toUpperCase().charCodeAt(0);
  5094          if (charCode > 64 && charCode < 91) {
  5095            return charCode;
  5096          }
  5097        }
  5098        return keyCodes[key];
  5099      });
  5100      codes = [].concat.apply([], codes);
  5101      return function keyHandler(e) {
  5102        if (codes.indexOf(e.keyCode) > -1) {
  5103          return handler.call(this, e);
  5104        }
  5105      };
  5106    }
  5107  
  5108    function stopFilter(handler) {
  5109      return function stopHandler(e) {
  5110        e.stopPropagation();
  5111        return handler.call(this, e);
  5112      };
  5113    }
  5114  
  5115    function preventFilter(handler) {
  5116      return function preventHandler(e) {
  5117        e.preventDefault();
  5118        return handler.call(this, e);
  5119      };
  5120    }
  5121  
  5122    function selfFilter(handler) {
  5123      return function selfHandler(e) {
  5124        if (e.target === e.currentTarget) {
  5125          return handler.call(this, e);
  5126        }
  5127      };
  5128    }
  5129  
  5130    var on$1 = {
  5131  
  5132      priority: ON,
  5133      acceptStatement: true,
  5134      keyCodes: keyCodes,
  5135  
  5136      bind: function bind() {
  5137        // deal with iframes
  5138        if (this.el.tagName === 'IFRAME' && this.arg !== 'load') {
  5139          var self = this;
  5140          this.iframeBind = function () {
  5141            on(self.el.contentWindow, self.arg, self.handler, self.modifiers.capture);
  5142          };
  5143          this.on('load', this.iframeBind);
  5144        }
  5145      },
  5146  
  5147      update: function update(handler) {
  5148        // stub a noop for v-on with no value,
  5149        // e.g. @mousedown.prevent
  5150        if (!this.descriptor.raw) {
  5151          handler = function () {};
  5152        }
  5153  
  5154        if (typeof handler !== 'function') {
  5155          'development' !== 'production' && warn('v-on:' + this.arg + '="' + this.expression + '" expects a function value, ' + 'got ' + handler, this.vm);
  5156          return;
  5157        }
  5158  
  5159        // apply modifiers
  5160        if (this.modifiers.stop) {
  5161          handler = stopFilter(handler);
  5162        }
  5163        if (this.modifiers.prevent) {
  5164          handler = preventFilter(handler);
  5165        }
  5166        if (this.modifiers.self) {
  5167          handler = selfFilter(handler);
  5168        }
  5169        // key filter
  5170        var keys = Object.keys(this.modifiers).filter(function (key) {
  5171          return key !== 'stop' && key !== 'prevent' && key !== 'self' && key !== 'capture';
  5172        });
  5173        if (keys.length) {
  5174          handler = keyFilter(handler, keys);
  5175        }
  5176  
  5177        this.reset();
  5178        this.handler = handler;
  5179  
  5180        if (this.iframeBind) {
  5181          this.iframeBind();
  5182        } else {
  5183          on(this.el, this.arg, this.handler, this.modifiers.capture);
  5184        }
  5185      },
  5186  
  5187      reset: function reset() {
  5188        var el = this.iframeBind ? this.el.contentWindow : this.el;
  5189        if (this.handler) {
  5190          off(el, this.arg, this.handler);
  5191        }
  5192      },
  5193  
  5194      unbind: function unbind() {
  5195        this.reset();
  5196      }
  5197    };
  5198  
  5199    var prefixes = ['-webkit-', '-moz-', '-ms-'];
  5200    var camelPrefixes = ['Webkit', 'Moz', 'ms'];
  5201    var importantRE = /!important;?$/;
  5202    var propCache = Object.create(null);
  5203  
  5204    var testEl = null;
  5205  
  5206    var style = {
  5207  
  5208      deep: true,
  5209  
  5210      update: function update(value) {
  5211        if (typeof value === 'string') {
  5212          this.el.style.cssText = value;
  5213        } else if (isArray(value)) {
  5214          this.handleObject(value.reduce(extend, {}));
  5215        } else {
  5216          this.handleObject(value || {});
  5217        }
  5218      },
  5219  
  5220      handleObject: function handleObject(value) {
  5221        // cache object styles so that only changed props
  5222        // are actually updated.
  5223        var cache = this.cache || (this.cache = {});
  5224        var name, val;
  5225        for (name in cache) {
  5226          if (!(name in value)) {
  5227            this.handleSingle(name, null);
  5228            delete cache[name];
  5229          }
  5230        }
  5231        for (name in value) {
  5232          val = value[name];
  5233          if (val !== cache[name]) {
  5234            cache[name] = val;
  5235            this.handleSingle(name, val);
  5236          }
  5237        }
  5238      },
  5239  
  5240      handleSingle: function handleSingle(prop, value) {
  5241        prop = normalize(prop);
  5242        if (!prop) return; // unsupported prop
  5243        // cast possible numbers/booleans into strings
  5244        if (value != null) value += '';
  5245        if (value) {
  5246          var isImportant = importantRE.test(value) ? 'important' : '';
  5247          if (isImportant) {
  5248            /* istanbul ignore if */
  5249            if ('development' !== 'production') {
  5250              warn('It\'s probably a bad idea to use !important with inline rules. ' + 'This feature will be deprecated in a future version of Vue.');
  5251            }
  5252            value = value.replace(importantRE, '').trim();
  5253            this.el.style.setProperty(prop.kebab, value, isImportant);
  5254          } else {
  5255            this.el.style[prop.camel] = value;
  5256          }
  5257        } else {
  5258          this.el.style[prop.camel] = '';
  5259        }
  5260      }
  5261  
  5262    };
  5263  
  5264    /**
  5265     * Normalize a CSS property name.
  5266     * - cache result
  5267     * - auto prefix
  5268     * - camelCase -> dash-case
  5269     *
  5270     * @param {String} prop
  5271     * @return {String}
  5272     */
  5273  
  5274    function normalize(prop) {
  5275      if (propCache[prop]) {
  5276        return propCache[prop];
  5277      }
  5278      var res = prefix(prop);
  5279      propCache[prop] = propCache[res] = res;
  5280      return res;
  5281    }
  5282  
  5283    /**
  5284     * Auto detect the appropriate prefix for a CSS property.
  5285     * https://gist.github.com/paulirish/523692
  5286     *
  5287     * @param {String} prop
  5288     * @return {String}
  5289     */
  5290  
  5291    function prefix(prop) {
  5292      prop = hyphenate(prop);
  5293      var camel = camelize(prop);
  5294      var upper = camel.charAt(0).toUpperCase() + camel.slice(1);
  5295      if (!testEl) {
  5296        testEl = document.createElement('div');
  5297      }
  5298      var i = prefixes.length;
  5299      var prefixed;
  5300      if (camel !== 'filter' && camel in testEl.style) {
  5301        return {
  5302          kebab: prop,
  5303          camel: camel
  5304        };
  5305      }
  5306      while (i--) {
  5307        prefixed = camelPrefixes[i] + upper;
  5308        if (prefixed in testEl.style) {
  5309          return {
  5310            kebab: prefixes[i] + prop,
  5311            camel: prefixed
  5312          };
  5313        }
  5314      }
  5315    }
  5316  
  5317    // xlink
  5318    var xlinkNS = 'http://www.w3.org/1999/xlink';
  5319    var xlinkRE = /^xlink:/;
  5320  
  5321    // check for attributes that prohibit interpolations
  5322    var disallowedInterpAttrRE = /^v-|^:|^@|^(?:is|transition|transition-mode|debounce|track-by|stagger|enter-stagger|leave-stagger)$/;
  5323    // these attributes should also set their corresponding properties
  5324    // because they only affect the initial state of the element
  5325    var attrWithPropsRE = /^(?:value|checked|selected|muted)$/;
  5326    // these attributes expect enumrated values of "true" or "false"
  5327    // but are not boolean attributes
  5328    var enumeratedAttrRE = /^(?:draggable|contenteditable|spellcheck)$/;
  5329  
  5330    // these attributes should set a hidden property for
  5331    // binding v-model to object values
  5332    var modelProps = {
  5333      value: '_value',
  5334      'true-value': '_trueValue',
  5335      'false-value': '_falseValue'
  5336    };
  5337  
  5338    var bind$1 = {
  5339  
  5340      priority: BIND,
  5341  
  5342      bind: function bind() {
  5343        var attr = this.arg;
  5344        var tag = this.el.tagName;
  5345        // should be deep watch on object mode
  5346        if (!attr) {
  5347          this.deep = true;
  5348        }
  5349        // handle interpolation bindings
  5350        var descriptor = this.descriptor;
  5351        var tokens = descriptor.interp;
  5352        if (tokens) {
  5353          // handle interpolations with one-time tokens
  5354          if (descriptor.hasOneTime) {
  5355            this.expression = tokensToExp(tokens, this._scope || this.vm);
  5356          }
  5357  
  5358          // only allow binding on native attributes
  5359          if (disallowedInterpAttrRE.test(attr) || attr === 'name' && (tag === 'PARTIAL' || tag === 'SLOT')) {
  5360            'development' !== 'production' && warn(attr + '="' + descriptor.raw + '": ' + 'attribute interpolation is not allowed in Vue.js ' + 'directives and special attributes.', this.vm);
  5361            this.el.removeAttribute(attr);
  5362            this.invalid = true;
  5363          }
  5364  
  5365          /* istanbul ignore if */
  5366          if ('development' !== 'production') {
  5367            var raw = attr + '="' + descriptor.raw + '": ';
  5368            // warn src
  5369            if (attr === 'src') {
  5370              warn(raw + 'interpolation in "src" attribute will cause ' + 'a 404 request. Use v-bind:src instead.', this.vm);
  5371            }
  5372  
  5373            // warn style
  5374            if (attr === 'style') {
  5375              warn(raw + 'interpolation in "style" attribute will cause ' + 'the attribute to be discarded in Internet Explorer. ' + 'Use v-bind:style instead.', this.vm);
  5376            }
  5377          }
  5378        }
  5379      },
  5380  
  5381      update: function update(value) {
  5382        if (this.invalid) {
  5383          return;
  5384        }
  5385        var attr = this.arg;
  5386        if (this.arg) {
  5387          this.handleSingle(attr, value);
  5388        } else {
  5389          this.handleObject(value || {});
  5390        }
  5391      },
  5392  
  5393      // share object handler with v-bind:class
  5394      handleObject: style.handleObject,
  5395  
  5396      handleSingle: function handleSingle(attr, value) {
  5397        var el = this.el;
  5398        var interp = this.descriptor.interp;
  5399        if (this.modifiers.camel) {
  5400          attr = camelize(attr);
  5401        }
  5402        if (!interp && attrWithPropsRE.test(attr) && attr in el) {
  5403          var attrValue = attr === 'value' ? value == null // IE9 will set input.value to "null" for null...
  5404          ? '' : value : value;
  5405  
  5406          if (el[attr] !== attrValue) {
  5407            el[attr] = attrValue;
  5408          }
  5409        }
  5410        // set model props
  5411        var modelProp = modelProps[attr];
  5412        if (!interp && modelProp) {
  5413          el[modelProp] = value;
  5414          // update v-model if present
  5415          var model = el.__v_model;
  5416          if (model) {
  5417            model.listener();
  5418          }
  5419        }
  5420        // do not set value attribute for textarea
  5421        if (attr === 'value' && el.tagName === 'TEXTAREA') {
  5422          el.removeAttribute(attr);
  5423          return;
  5424        }
  5425        // update attribute
  5426        if (enumeratedAttrRE.test(attr)) {
  5427          el.setAttribute(attr, value ? 'true' : 'false');
  5428        } else if (value != null && value !== false) {
  5429          if (attr === 'class') {
  5430            // handle edge case #1960:
  5431            // class interpolation should not overwrite Vue transition class
  5432            if (el.__v_trans) {
  5433              value += ' ' + el.__v_trans.id + '-transition';
  5434            }
  5435            setClass(el, value);
  5436          } else if (xlinkRE.test(attr)) {
  5437            el.setAttributeNS(xlinkNS, attr, value === true ? '' : value);
  5438          } else {
  5439            el.setAttribute(attr, value === true ? '' : value);
  5440          }
  5441        } else {
  5442          el.removeAttribute(attr);
  5443        }
  5444      }
  5445    };
  5446  
  5447    var el = {
  5448  
  5449      priority: EL,
  5450  
  5451      bind: function bind() {
  5452        /* istanbul ignore if */
  5453        if (!this.arg) {
  5454          return;
  5455        }
  5456        var id = this.id = camelize(this.arg);
  5457        var refs = (this._scope || this.vm).$els;
  5458        if (hasOwn(refs, id)) {
  5459          refs[id] = this.el;
  5460        } else {
  5461          defineReactive(refs, id, this.el);
  5462        }
  5463      },
  5464  
  5465      unbind: function unbind() {
  5466        var refs = (this._scope || this.vm).$els;
  5467        if (refs[this.id] === this.el) {
  5468          refs[this.id] = null;
  5469        }
  5470      }
  5471    };
  5472  
  5473    var ref = {
  5474      bind: function bind() {
  5475        'development' !== 'production' && warn('v-ref:' + this.arg + ' must be used on a child ' + 'component. Found on <' + this.el.tagName.toLowerCase() + '>.', this.vm);
  5476      }
  5477    };
  5478  
  5479    var cloak = {
  5480      bind: function bind() {
  5481        var el = this.el;
  5482        this.vm.$once('pre-hook:compiled', function () {
  5483          el.removeAttribute('v-cloak');
  5484        });
  5485      }
  5486    };
  5487  
  5488    // must export plain object
  5489    var directives = {
  5490      text: text$1,
  5491      html: html,
  5492      'for': vFor,
  5493      'if': vIf,
  5494      show: show,
  5495      model: model,
  5496      on: on$1,
  5497      bind: bind$1,
  5498      el: el,
  5499      ref: ref,
  5500      cloak: cloak
  5501    };
  5502  
  5503    var vClass = {
  5504  
  5505      deep: true,
  5506  
  5507      update: function update(value) {
  5508        if (!value) {
  5509          this.cleanup();
  5510        } else if (typeof value === 'string') {
  5511          this.setClass(value.trim().split(/\s+/));
  5512        } else {
  5513          this.setClass(normalize$1(value));
  5514        }
  5515      },
  5516  
  5517      setClass: function setClass(value) {
  5518        this.cleanup(value);
  5519        for (var i = 0, l = value.length; i < l; i++) {
  5520          var val = value[i];
  5521          if (val) {
  5522            apply(this.el, val, addClass);
  5523          }
  5524        }
  5525        this.prevKeys = value;
  5526      },
  5527  
  5528      cleanup: function cleanup(value) {
  5529        var prevKeys = this.prevKeys;
  5530        if (!prevKeys) return;
  5531        var i = prevKeys.length;
  5532        while (i--) {
  5533          var key = prevKeys[i];
  5534          if (!value || value.indexOf(key) < 0) {
  5535            apply(this.el, key, removeClass);
  5536          }
  5537        }
  5538      }
  5539    };
  5540  
  5541    /**
  5542     * Normalize objects and arrays (potentially containing objects)
  5543     * into array of strings.
  5544     *
  5545     * @param {Object|Array<String|Object>} value
  5546     * @return {Array<String>}
  5547     */
  5548  
  5549    function normalize$1(value) {
  5550      var res = [];
  5551      if (isArray(value)) {
  5552        for (var i = 0, l = value.length; i < l; i++) {
  5553          var _key = value[i];
  5554          if (_key) {
  5555            if (typeof _key === 'string') {
  5556              res.push(_key);
  5557            } else {
  5558              for (var k in _key) {
  5559                if (_key[k]) res.push(k);
  5560              }
  5561            }
  5562          }
  5563        }
  5564      } else if (isObject(value)) {
  5565        for (var key in value) {
  5566          if (value[key]) res.push(key);
  5567        }
  5568      }
  5569      return res;
  5570    }
  5571  
  5572    /**
  5573     * Add or remove a class/classes on an element
  5574     *
  5575     * @param {Element} el
  5576     * @param {String} key The class name. This may or may not
  5577     *                     contain a space character, in such a
  5578     *                     case we'll deal with multiple class
  5579     *                     names at once.
  5580     * @param {Function} fn
  5581     */
  5582  
  5583    function apply(el, key, fn) {
  5584      key = key.trim();
  5585      if (key.indexOf(' ') === -1) {
  5586        fn(el, key);
  5587        return;
  5588      }
  5589      // The key contains one or more space characters.
  5590      // Since a class name doesn't accept such characters, we
  5591      // treat it as multiple classes.
  5592      var keys = key.split(/\s+/);
  5593      for (var i = 0, l = keys.length; i < l; i++) {
  5594        fn(el, keys[i]);
  5595      }
  5596    }
  5597  
  5598    var component = {
  5599  
  5600      priority: COMPONENT,
  5601  
  5602      params: ['keep-alive', 'transition-mode', 'inline-template'],
  5603  
  5604      /**
  5605       * Setup. Two possible usages:
  5606       *
  5607       * - static:
  5608       *   <comp> or <div v-component="comp">
  5609       *
  5610       * - dynamic:
  5611       *   <component :is="view">
  5612       */
  5613  
  5614      bind: function bind() {
  5615        if (!this.el.__vue__) {
  5616          // keep-alive cache
  5617          this.keepAlive = this.params.keepAlive;
  5618          if (this.keepAlive) {
  5619            this.cache = {};
  5620          }
  5621          // check inline-template
  5622          if (this.params.inlineTemplate) {
  5623            // extract inline template as a DocumentFragment
  5624            this.inlineTemplate = extractContent(this.el, true);
  5625          }
  5626          // component resolution related state
  5627          this.pendingComponentCb = this.Component = null;
  5628          // transition related state
  5629          this.pendingRemovals = 0;
  5630          this.pendingRemovalCb = null;
  5631          // create a ref anchor
  5632          this.anchor = createAnchor('v-component');
  5633          replace(this.el, this.anchor);
  5634          // remove is attribute.
  5635          // this is removed during compilation, but because compilation is
  5636          // cached, when the component is used elsewhere this attribute
  5637          // will remain at link time.
  5638          this.el.removeAttribute('is');
  5639          this.el.removeAttribute(':is');
  5640          // remove ref, same as above
  5641          if (this.descriptor.ref) {
  5642            this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref));
  5643          }
  5644          // if static, build right now.
  5645          if (this.literal) {
  5646            this.setComponent(this.expression);
  5647          }
  5648        } else {
  5649          'development' !== 'production' && warn('cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el);
  5650        }
  5651      },
  5652  
  5653      /**
  5654       * Public update, called by the watcher in the dynamic
  5655       * literal scenario, e.g. <component :is="view">
  5656       */
  5657  
  5658      update: function update(value) {
  5659        if (!this.literal) {
  5660          this.setComponent(value);
  5661        }
  5662      },
  5663  
  5664      /**
  5665       * Switch dynamic components. May resolve the component
  5666       * asynchronously, and perform transition based on
  5667       * specified transition mode. Accepts a few additional
  5668       * arguments specifically for vue-router.
  5669       *
  5670       * The callback is called when the full transition is
  5671       * finished.
  5672       *
  5673       * @param {String} value
  5674       * @param {Function} [cb]
  5675       */
  5676  
  5677      setComponent: function setComponent(value, cb) {
  5678        this.invalidatePending();
  5679        if (!value) {
  5680          // just remove current
  5681          this.unbuild(true);
  5682          this.remove(this.childVM, cb);
  5683          this.childVM = null;
  5684        } else {
  5685          var self = this;
  5686          this.resolveComponent(value, function () {
  5687            self.mountComponent(cb);
  5688          });
  5689        }
  5690      },
  5691  
  5692      /**
  5693       * Resolve the component constructor to use when creating
  5694       * the child vm.
  5695       *
  5696       * @param {String|Function} value
  5697       * @param {Function} cb
  5698       */
  5699  
  5700      resolveComponent: function resolveComponent(value, cb) {
  5701        var self = this;
  5702        this.pendingComponentCb = cancellable(function (Component) {
  5703          self.ComponentName = Component.options.name || (typeof value === 'string' ? value : null);
  5704          self.Component = Component;
  5705          cb();
  5706        });
  5707        this.vm._resolveComponent(value, this.pendingComponentCb);
  5708      },
  5709  
  5710      /**
  5711       * Create a new instance using the current constructor and
  5712       * replace the existing instance. This method doesn't care
  5713       * whether the new component and the old one are actually
  5714       * the same.
  5715       *
  5716       * @param {Function} [cb]
  5717       */
  5718  
  5719      mountComponent: function mountComponent(cb) {
  5720        // actual mount
  5721        this.unbuild(true);
  5722        var self = this;
  5723        var activateHooks = this.Component.options.activate;
  5724        var cached = this.getCached();
  5725        var newComponent = this.build();
  5726        if (activateHooks && !cached) {
  5727          this.waitingFor = newComponent;
  5728          callActivateHooks(activateHooks, newComponent, function () {
  5729            if (self.waitingFor !== newComponent) {
  5730              return;
  5731            }
  5732            self.waitingFor = null;
  5733            self.transition(newComponent, cb);
  5734          });
  5735        } else {
  5736          // update ref for kept-alive component
  5737          if (cached) {
  5738            newComponent._updateRef();
  5739          }
  5740          this.transition(newComponent, cb);
  5741        }
  5742      },
  5743  
  5744      /**
  5745       * When the component changes or unbinds before an async
  5746       * constructor is resolved, we need to invalidate its
  5747       * pending callback.
  5748       */
  5749  
  5750      invalidatePending: function invalidatePending() {
  5751        if (this.pendingComponentCb) {
  5752          this.pendingComponentCb.cancel();
  5753          this.pendingComponentCb = null;
  5754        }
  5755      },
  5756  
  5757      /**
  5758       * Instantiate/insert a new child vm.
  5759       * If keep alive and has cached instance, insert that
  5760       * instance; otherwise build a new one and cache it.
  5761       *
  5762       * @param {Object} [extraOptions]
  5763       * @return {Vue} - the created instance
  5764       */
  5765  
  5766      build: function build(extraOptions) {
  5767        var cached = this.getCached();
  5768        if (cached) {
  5769          return cached;
  5770        }
  5771        if (this.Component) {
  5772          // default options
  5773          var options = {
  5774            name: this.ComponentName,
  5775            el: cloneNode(this.el),
  5776            template: this.inlineTemplate,
  5777            // make sure to add the child with correct parent
  5778            // if this is a transcluded component, its parent
  5779            // should be the transclusion host.
  5780            parent: this._host || this.vm,
  5781            // if no inline-template, then the compiled
  5782            // linker can be cached for better performance.
  5783            _linkerCachable: !this.inlineTemplate,
  5784            _ref: this.descriptor.ref,
  5785            _asComponent: true,
  5786            _isRouterView: this._isRouterView,
  5787            // if this is a transcluded component, context
  5788            // will be the common parent vm of this instance
  5789            // and its host.
  5790            _context: this.vm,
  5791            // if this is inside an inline v-for, the scope
  5792            // will be the intermediate scope created for this
  5793            // repeat fragment. this is used for linking props
  5794            // and container directives.
  5795            _scope: this._scope,
  5796            // pass in the owner fragment of this component.
  5797            // this is necessary so that the fragment can keep
  5798            // track of its contained components in order to
  5799            // call attach/detach hooks for them.
  5800            _frag: this._frag
  5801          };
  5802          // extra options
  5803          // in 1.0.0 this is used by vue-router only
  5804          /* istanbul ignore if */
  5805          if (extraOptions) {
  5806            extend(options, extraOptions);
  5807          }
  5808          var child = new this.Component(options);
  5809          if (this.keepAlive) {
  5810            this.cache[this.Component.cid] = child;
  5811          }
  5812          /* istanbul ignore if */
  5813          if ('development' !== 'production' && this.el.hasAttribute('transition') && child._isFragment) {
  5814            warn('Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template, child);
  5815          }
  5816          return child;
  5817        }
  5818      },
  5819  
  5820      /**
  5821       * Try to get a cached instance of the current component.
  5822       *
  5823       * @return {Vue|undefined}
  5824       */
  5825  
  5826      getCached: function getCached() {
  5827        return this.keepAlive && this.cache[this.Component.cid];
  5828      },
  5829  
  5830      /**
  5831       * Teardown the current child, but defers cleanup so
  5832       * that we can separate the destroy and removal steps.
  5833       *
  5834       * @param {Boolean} defer
  5835       */
  5836  
  5837      unbuild: function unbuild(defer) {
  5838        if (this.waitingFor) {
  5839          if (!this.keepAlive) {
  5840            this.waitingFor.$destroy();
  5841          }
  5842          this.waitingFor = null;
  5843        }
  5844        var child = this.childVM;
  5845        if (!child || this.keepAlive) {
  5846          if (child) {
  5847            // remove ref
  5848            child._inactive = true;
  5849            child._updateRef(true);
  5850          }
  5851          return;
  5852        }
  5853        // the sole purpose of `deferCleanup` is so that we can
  5854        // "deactivate" the vm right now and perform DOM removal
  5855        // later.
  5856        child.$destroy(false, defer);
  5857      },
  5858  
  5859      /**
  5860       * Remove current destroyed child and manually do
  5861       * the cleanup after removal.
  5862       *
  5863       * @param {Function} cb
  5864       */
  5865  
  5866      remove: function remove(child, cb) {
  5867        var keepAlive = this.keepAlive;
  5868        if (child) {
  5869          // we may have a component switch when a previous
  5870          // component is still being transitioned out.
  5871          // we want to trigger only one lastest insertion cb
  5872          // when the existing transition finishes. (#1119)
  5873          this.pendingRemovals++;
  5874          this.pendingRemovalCb = cb;
  5875          var self = this;
  5876          child.$remove(function () {
  5877            self.pendingRemovals--;
  5878            if (!keepAlive) child._cleanup();
  5879            if (!self.pendingRemovals && self.pendingRemovalCb) {
  5880              self.pendingRemovalCb();
  5881              self.pendingRemovalCb = null;
  5882            }
  5883          });
  5884        } else if (cb) {
  5885          cb();
  5886        }
  5887      },
  5888  
  5889      /**
  5890       * Actually swap the components, depending on the
  5891       * transition mode. Defaults to simultaneous.
  5892       *
  5893       * @param {Vue} target
  5894       * @param {Function} [cb]
  5895       */
  5896  
  5897      transition: function transition(target, cb) {
  5898        var self = this;
  5899        var current = this.childVM;
  5900        // for devtool inspection
  5901        if (current) current._inactive = true;
  5902        target._inactive = false;
  5903        this.childVM = target;
  5904        switch (self.params.transitionMode) {
  5905          case 'in-out':
  5906            target.$before(self.anchor, function () {
  5907              self.remove(current, cb);
  5908            });
  5909            break;
  5910          case 'out-in':
  5911            self.remove(current, function () {
  5912              target.$before(self.anchor, cb);
  5913            });
  5914            break;
  5915          default:
  5916            self.remove(current);
  5917            target.$before(self.anchor, cb);
  5918        }
  5919      },
  5920  
  5921      /**
  5922       * Unbind.
  5923       */
  5924  
  5925      unbind: function unbind() {
  5926        this.invalidatePending();
  5927        // Do not defer cleanup when unbinding
  5928        this.unbuild();
  5929        // destroy all keep-alive cached instances
  5930        if (this.cache) {
  5931          for (var key in this.cache) {
  5932            this.cache[key].$destroy();
  5933          }
  5934          this.cache = null;
  5935        }
  5936      }
  5937    };
  5938  
  5939    /**
  5940     * Call activate hooks in order (asynchronous)
  5941     *
  5942     * @param {Array} hooks
  5943     * @param {Vue} vm
  5944     * @param {Function} cb
  5945     */
  5946  
  5947    function callActivateHooks(hooks, vm, cb) {
  5948      var total = hooks.length;
  5949      var called = 0;
  5950      hooks[0].call(vm, next);
  5951      function next() {
  5952        if (++called >= total) {
  5953          cb();
  5954        } else {
  5955          hooks[called].call(vm, next);
  5956        }
  5957      }
  5958    }
  5959  
  5960    var propBindingModes = config._propBindingModes;
  5961    var empty = {};
  5962  
  5963    // regexes
  5964    var identRE$1 = /^[$_a-zA-Z]+[\w$]*$/;
  5965    var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/;
  5966  
  5967    /**
  5968     * Compile props on a root element and return
  5969     * a props link function.
  5970     *
  5971     * @param {Element|DocumentFragment} el
  5972     * @param {Array} propOptions
  5973     * @param {Vue} vm
  5974     * @return {Function} propsLinkFn
  5975     */
  5976  
  5977    function compileProps(el, propOptions, vm) {
  5978      var props = [];
  5979      var names = Object.keys(propOptions);
  5980      var i = names.length;
  5981      var options, name, attr, value, path, parsed, prop;
  5982      while (i--) {
  5983        name = names[i];
  5984        options = propOptions[name] || empty;
  5985  
  5986        if ('development' !== 'production' && name === '$data') {
  5987          warn('Do not use $data as prop.', vm);
  5988          continue;
  5989        }
  5990  
  5991        // props could contain dashes, which will be
  5992        // interpreted as minus calculations by the parser
  5993        // so we need to camelize the path here
  5994        path = camelize(name);
  5995        if (!identRE$1.test(path)) {
  5996          'development' !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.', vm);
  5997          continue;
  5998        }
  5999  
  6000        prop = {
  6001          name: name,
  6002          path: path,
  6003          options: options,
  6004          mode: propBindingModes.ONE_WAY,
  6005          raw: null
  6006        };
  6007  
  6008        attr = hyphenate(name);
  6009        // first check dynamic version
  6010        if ((value = getBindAttr(el, attr)) === null) {
  6011          if ((value = getBindAttr(el, attr + '.sync')) !== null) {
  6012            prop.mode = propBindingModes.TWO_WAY;
  6013          } else if ((value = getBindAttr(el, attr + '.once')) !== null) {
  6014            prop.mode = propBindingModes.ONE_TIME;
  6015          }
  6016        }
  6017        if (value !== null) {
  6018          // has dynamic binding!
  6019          prop.raw = value;
  6020          parsed = parseDirective(value);
  6021          value = parsed.expression;
  6022          prop.filters = parsed.filters;
  6023          // check binding type
  6024          if (isLiteral(value) && !parsed.filters) {
  6025            // for expressions containing literal numbers and
  6026            // booleans, there's no need to setup a prop binding,
  6027            // so we can optimize them as a one-time set.
  6028            prop.optimizedLiteral = true;
  6029          } else {
  6030            prop.dynamic = true;
  6031            // check non-settable path for two-way bindings
  6032            if ('development' !== 'production' && prop.mode === propBindingModes.TWO_WAY && !settablePathRE.test(value)) {
  6033              prop.mode = propBindingModes.ONE_WAY;
  6034              warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value, vm);
  6035            }
  6036          }
  6037          prop.parentPath = value;
  6038  
  6039          // warn required two-way
  6040          if ('development' !== 'production' && options.twoWay && prop.mode !== propBindingModes.TWO_WAY) {
  6041            warn('Prop "' + name + '" expects a two-way binding type.', vm);
  6042          }
  6043        } else if ((value = getAttr(el, attr)) !== null) {
  6044          // has literal binding!
  6045          prop.raw = value;
  6046        } else if ('development' !== 'production') {
  6047          // check possible camelCase prop usage
  6048          var lowerCaseName = path.toLowerCase();
  6049          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'));
  6050          if (value) {
  6051            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);
  6052          } else if (options.required) {
  6053            // warn missing required
  6054            warn('Missing required prop: ' + name, vm);
  6055          }
  6056        }
  6057        // push prop
  6058        props.push(prop);
  6059      }
  6060      return makePropsLinkFn(props);
  6061    }
  6062  
  6063    /**
  6064     * Build a function that applies props to a vm.
  6065     *
  6066     * @param {Array} props
  6067     * @return {Function} propsLinkFn
  6068     */
  6069  
  6070    function makePropsLinkFn(props) {
  6071      return function propsLinkFn(vm, scope) {
  6072        // store resolved props info
  6073        vm._props = {};
  6074        var inlineProps = vm.$options.propsData;
  6075        var i = props.length;
  6076        var prop, path, options, value, raw;
  6077        while (i--) {
  6078          prop = props[i];
  6079          raw = prop.raw;
  6080          path = prop.path;
  6081          options = prop.options;
  6082          vm._props[path] = prop;
  6083          if (inlineProps && hasOwn(inlineProps, path)) {
  6084            initProp(vm, prop, inlineProps[path]);
  6085          }if (raw === null) {
  6086            // initialize absent prop
  6087            initProp(vm, prop, undefined);
  6088          } else if (prop.dynamic) {
  6089            // dynamic prop
  6090            if (prop.mode === propBindingModes.ONE_TIME) {
  6091              // one time binding
  6092              value = (scope || vm._context || vm).$get(prop.parentPath);
  6093              initProp(vm, prop, value);
  6094            } else {
  6095              if (vm._context) {
  6096                // dynamic binding
  6097                vm._bindDir({
  6098                  name: 'prop',
  6099                  def: propDef,
  6100                  prop: prop
  6101                }, null, null, scope); // el, host, scope
  6102              } else {
  6103                  // root instance
  6104                  initProp(vm, prop, vm.$get(prop.parentPath));
  6105                }
  6106            }
  6107          } else if (prop.optimizedLiteral) {
  6108            // optimized literal, cast it and just set once
  6109            var stripped = stripQuotes(raw);
  6110            value = stripped === raw ? toBoolean(toNumber(raw)) : stripped;
  6111            initProp(vm, prop, value);
  6112          } else {
  6113            // string literal, but we need to cater for
  6114            // Boolean props with no value, or with same
  6115            // literal value (e.g. disabled="disabled")
  6116            // see https://github.com/vuejs/vue-loader/issues/182
  6117            value = options.type === Boolean && (raw === '' || raw === hyphenate(prop.name)) ? true : raw;
  6118            initProp(vm, prop, value);
  6119          }
  6120        }
  6121      };
  6122    }
  6123  
  6124    /**
  6125     * Process a prop with a rawValue, applying necessary coersions,
  6126     * default values & assertions and call the given callback with
  6127     * processed value.
  6128     *
  6129     * @param {Vue} vm
  6130     * @param {Object} prop
  6131     * @param {*} rawValue
  6132     * @param {Function} fn
  6133     */
  6134  
  6135    function processPropValue(vm, prop, rawValue, fn) {
  6136      var isSimple = prop.dynamic && isSimplePath(prop.parentPath);
  6137      var value = rawValue;
  6138      if (value === undefined) {
  6139        value = getPropDefaultValue(vm, prop);
  6140      }
  6141      value = coerceProp(prop, value);
  6142      var coerced = value !== rawValue;
  6143      if (!assertProp(prop, value, vm)) {
  6144        value = undefined;
  6145      }
  6146      if (isSimple && !coerced) {
  6147        withoutConversion(function () {
  6148          fn(value);
  6149        });
  6150      } else {
  6151        fn(value);
  6152      }
  6153    }
  6154  
  6155    /**
  6156     * Set a prop's initial value on a vm and its data object.
  6157     *
  6158     * @param {Vue} vm
  6159     * @param {Object} prop
  6160     * @param {*} value
  6161     */
  6162  
  6163    function initProp(vm, prop, value) {
  6164      processPropValue(vm, prop, value, function (value) {
  6165        defineReactive(vm, prop.path, value);
  6166      });
  6167    }
  6168  
  6169    /**
  6170     * Update a prop's value on a vm.
  6171     *
  6172     * @param {Vue} vm
  6173     * @param {Object} prop
  6174     * @param {*} value
  6175     */
  6176  
  6177    function updateProp(vm, prop, value) {
  6178      processPropValue(vm, prop, value, function (value) {
  6179        vm[prop.path] = value;
  6180      });
  6181    }
  6182  
  6183    /**
  6184     * Get the default value of a prop.
  6185     *
  6186     * @param {Vue} vm
  6187     * @param {Object} prop
  6188     * @return {*}
  6189     */
  6190  
  6191    function getPropDefaultValue(vm, prop) {
  6192      // no default, return undefined
  6193      var options = prop.options;
  6194      if (!hasOwn(options, 'default')) {
  6195        // absent boolean value defaults to false
  6196        return options.type === Boolean ? false : undefined;
  6197      }
  6198      var def = options['default'];
  6199      // warn against non-factory defaults for Object & Array
  6200      if (isObject(def)) {
  6201        'development' !== '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);
  6202      }
  6203      // call factory function for non-Function types
  6204      return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
  6205    }
  6206  
  6207    /**
  6208     * Assert whether a prop is valid.
  6209     *
  6210     * @param {Object} prop
  6211     * @param {*} value
  6212     * @param {Vue} vm
  6213     */
  6214  
  6215    function assertProp(prop, value, vm) {
  6216      if (!prop.options.required && ( // non-required
  6217      prop.raw === null || // abscent
  6218      value == null) // null or undefined
  6219      ) {
  6220          return true;
  6221        }
  6222      var options = prop.options;
  6223      var type = options.type;
  6224      var valid = !type;
  6225      var expectedTypes = [];
  6226      if (type) {
  6227        if (!isArray(type)) {
  6228          type = [type];
  6229        }
  6230        for (var i = 0; i < type.length && !valid; i++) {
  6231          var assertedType = assertType(value, type[i]);
  6232          expectedTypes.push(assertedType.expectedType);
  6233          valid = assertedType.valid;
  6234        }
  6235      }
  6236      if (!valid) {
  6237        if ('development' !== 'production') {
  6238          warn('Invalid prop: type check failed for prop "' + prop.name + '".' + ' Expected ' + expectedTypes.map(formatType).join(', ') + ', got ' + formatValue(value) + '.', vm);
  6239        }
  6240        return false;
  6241      }
  6242      var validator = options.validator;
  6243      if (validator) {
  6244        if (!validator(value)) {
  6245          'development' !== 'production' && warn('Invalid prop: custom validator check failed for prop "' + prop.name + '".', vm);
  6246          return false;
  6247        }
  6248      }
  6249      return true;
  6250    }
  6251  
  6252    /**
  6253     * Force parsing value with coerce option.
  6254     *
  6255     * @param {*} value
  6256     * @param {Object} options
  6257     * @return {*}
  6258     */
  6259  
  6260    function coerceProp(prop, value) {
  6261      var coerce = prop.options.coerce;
  6262      if (!coerce) {
  6263        return value;
  6264      }
  6265      // coerce is a function
  6266      return coerce(value);
  6267    }
  6268  
  6269    /**
  6270     * Assert the type of a value
  6271     *
  6272     * @param {*} value
  6273     * @param {Function} type
  6274     * @return {Object}
  6275     */
  6276  
  6277    function assertType(value, type) {
  6278      var valid;
  6279      var expectedType;
  6280      if (type === String) {
  6281        expectedType = 'string';
  6282        valid = typeof value === expectedType;
  6283      } else if (type === Number) {
  6284        expectedType = 'number';
  6285        valid = typeof value === expectedType;
  6286      } else if (type === Boolean) {
  6287        expectedType = 'boolean';
  6288        valid = typeof value === expectedType;
  6289      } else if (type === Function) {
  6290        expectedType = 'function';
  6291        valid = typeof value === expectedType;
  6292      } else if (type === Object) {
  6293        expectedType = 'object';
  6294        valid = isPlainObject(value);
  6295      } else if (type === Array) {
  6296        expectedType = 'array';
  6297        valid = isArray(value);
  6298      } else {
  6299        valid = value instanceof type;
  6300      }
  6301      return {
  6302        valid: valid,
  6303        expectedType: expectedType
  6304      };
  6305    }
  6306  
  6307    /**
  6308     * Format type for output
  6309     *
  6310     * @param {String} type
  6311     * @return {String}
  6312     */
  6313  
  6314    function formatType(type) {
  6315      return type ? type.charAt(0).toUpperCase() + type.slice(1) : 'custom type';
  6316    }
  6317  
  6318    /**
  6319     * Format value
  6320     *
  6321     * @param {*} value
  6322     * @return {String}
  6323     */
  6324  
  6325    function formatValue(val) {
  6326      return Object.prototype.toString.call(val).slice(8, -1);
  6327    }
  6328  
  6329    var bindingModes = config._propBindingModes;
  6330  
  6331    var propDef = {
  6332  
  6333      bind: function bind() {
  6334        var child = this.vm;
  6335        var parent = child._context;
  6336        // passed in from compiler directly
  6337        var prop = this.descriptor.prop;
  6338        var childKey = prop.path;
  6339        var parentKey = prop.parentPath;
  6340        var twoWay = prop.mode === bindingModes.TWO_WAY;
  6341  
  6342        var parentWatcher = this.parentWatcher = new Watcher(parent, parentKey, function (val) {
  6343          updateProp(child, prop, val);
  6344        }, {
  6345          twoWay: twoWay,
  6346          filters: prop.filters,
  6347          // important: props need to be observed on the
  6348          // v-for scope if present
  6349          scope: this._scope
  6350        });
  6351  
  6352        // set the child initial value.
  6353        initProp(child, prop, parentWatcher.value);
  6354  
  6355        // setup two-way binding
  6356        if (twoWay) {
  6357          // important: defer the child watcher creation until
  6358          // the created hook (after data observation)
  6359          var self = this;
  6360          child.$once('pre-hook:created', function () {
  6361            self.childWatcher = new Watcher(child, childKey, function (val) {
  6362              parentWatcher.set(val);
  6363            }, {
  6364              // ensure sync upward before parent sync down.
  6365              // this is necessary in cases e.g. the child
  6366              // mutates a prop array, then replaces it. (#1683)
  6367              sync: true
  6368            });
  6369          });
  6370        }
  6371      },
  6372  
  6373      unbind: function unbind() {
  6374        this.parentWatcher.teardown();
  6375        if (this.childWatcher) {
  6376          this.childWatcher.teardown();
  6377        }
  6378      }
  6379    };
  6380  
  6381    var queue$1 = [];
  6382    var queued = false;
  6383  
  6384    /**
  6385     * Push a job into the queue.
  6386     *
  6387     * @param {Function} job
  6388     */
  6389  
  6390    function pushJob(job) {
  6391      queue$1.push(job);
  6392      if (!queued) {
  6393        queued = true;
  6394        nextTick(flush);
  6395      }
  6396    }
  6397  
  6398    /**
  6399     * Flush the queue, and do one forced reflow before
  6400     * triggering transitions.
  6401     */
  6402  
  6403    function flush() {
  6404      // Force layout
  6405      var f = document.documentElement.offsetHeight;
  6406      for (var i = 0; i < queue$1.length; i++) {
  6407        queue$1[i]();
  6408      }
  6409      queue$1 = [];
  6410      queued = false;
  6411      // dummy return, so js linters don't complain about
  6412      // unused variable f
  6413      return f;
  6414    }
  6415  
  6416    var TYPE_TRANSITION = 'transition';
  6417    var TYPE_ANIMATION = 'animation';
  6418    var transDurationProp = transitionProp + 'Duration';
  6419    var animDurationProp = animationProp + 'Duration';
  6420  
  6421    /**
  6422     * If a just-entered element is applied the
  6423     * leave class while its enter transition hasn't started yet,
  6424     * and the transitioned property has the same value for both
  6425     * enter/leave, then the leave transition will be skipped and
  6426     * the transitionend event never fires. This function ensures
  6427     * its callback to be called after a transition has started
  6428     * by waiting for double raf.
  6429     *
  6430     * It falls back to setTimeout on devices that support CSS
  6431     * transitions but not raf (e.g. Android 4.2 browser) - since
  6432     * these environments are usually slow, we are giving it a
  6433     * relatively large timeout.
  6434     */
  6435  
  6436    var raf = inBrowser && window.requestAnimationFrame;
  6437    var waitForTransitionStart = raf
  6438    /* istanbul ignore next */
  6439    ? function (fn) {
  6440      raf(function () {
  6441        raf(fn);
  6442      });
  6443    } : function (fn) {
  6444      setTimeout(fn, 50);
  6445    };
  6446  
  6447    /**
  6448     * A Transition object that encapsulates the state and logic
  6449     * of the transition.
  6450     *
  6451     * @param {Element} el
  6452     * @param {String} id
  6453     * @param {Object} hooks
  6454     * @param {Vue} vm
  6455     */
  6456    function Transition(el, id, hooks, vm) {
  6457      this.id = id;
  6458      this.el = el;
  6459      this.enterClass = hooks && hooks.enterClass || id + '-enter';
  6460      this.leaveClass = hooks && hooks.leaveClass || id + '-leave';
  6461      this.hooks = hooks;
  6462      this.vm = vm;
  6463      // async state
  6464      this.pendingCssEvent = this.pendingCssCb = this.cancel = this.pendingJsCb = this.op = this.cb = null;
  6465      this.justEntered = false;
  6466      this.entered = this.left = false;
  6467      this.typeCache = {};
  6468      // check css transition type
  6469      this.type = hooks && hooks.type;
  6470      /* istanbul ignore if */
  6471      if ('development' !== 'production') {
  6472        if (this.type && this.type !== TYPE_TRANSITION && this.type !== TYPE_ANIMATION) {
  6473          warn('invalid CSS transition type for transition="' + this.id + '": ' + this.type, vm);
  6474        }
  6475      }
  6476      // bind
  6477      var self = this;['enterNextTick', 'enterDone', 'leaveNextTick', 'leaveDone'].forEach(function (m) {
  6478        self[m] = bind(self[m], self);
  6479      });
  6480    }
  6481  
  6482    var p$1 = Transition.prototype;
  6483  
  6484    /**
  6485     * Start an entering transition.
  6486     *
  6487     * 1. enter transition triggered
  6488     * 2. call beforeEnter hook
  6489     * 3. add enter class
  6490     * 4. insert/show element
  6491     * 5. call enter hook (with possible explicit js callback)
  6492     * 6. reflow
  6493     * 7. based on transition type:
  6494     *    - transition:
  6495     *        remove class now, wait for transitionend,
  6496     *        then done if there's no explicit js callback.
  6497     *    - animation:
  6498     *        wait for animationend, remove class,
  6499     *        then done if there's no explicit js callback.
  6500     *    - no css transition:
  6501     *        done now if there's no explicit js callback.
  6502     * 8. wait for either done or js callback, then call
  6503     *    afterEnter hook.
  6504     *
  6505     * @param {Function} op - insert/show the element
  6506     * @param {Function} [cb]
  6507     */
  6508  
  6509    p$1.enter = function (op, cb) {
  6510      this.cancelPending();
  6511      this.callHook('beforeEnter');
  6512      this.cb = cb;
  6513      addClass(this.el, this.enterClass);
  6514      op();
  6515      this.entered = false;
  6516      this.callHookWithCb('enter');
  6517      if (this.entered) {
  6518        return; // user called done synchronously.
  6519      }
  6520      this.cancel = this.hooks && this.hooks.enterCancelled;
  6521      pushJob(this.enterNextTick);
  6522    };
  6523  
  6524    /**
  6525     * The "nextTick" phase of an entering transition, which is
  6526     * to be pushed into a queue and executed after a reflow so
  6527     * that removing the class can trigger a CSS transition.
  6528     */
  6529  
  6530    p$1.enterNextTick = function () {
  6531      var _this = this;
  6532  
  6533      // prevent transition skipping
  6534      this.justEntered = true;
  6535      waitForTransitionStart(function () {
  6536        _this.justEntered = false;
  6537      });
  6538      var enterDone = this.enterDone;
  6539      var type = this.getCssTransitionType(this.enterClass);
  6540      if (!this.pendingJsCb) {
  6541        if (type === TYPE_TRANSITION) {
  6542          // trigger transition by removing enter class now
  6543          removeClass(this.el, this.enterClass);
  6544          this.setupCssCb(transitionEndEvent, enterDone);
  6545        } else if (type === TYPE_ANIMATION) {
  6546          this.setupCssCb(animationEndEvent, enterDone);
  6547        } else {
  6548          enterDone();
  6549        }
  6550      } else if (type === TYPE_TRANSITION) {
  6551        removeClass(this.el, this.enterClass);
  6552      }
  6553    };
  6554  
  6555    /**
  6556     * The "cleanup" phase of an entering transition.
  6557     */
  6558  
  6559    p$1.enterDone = function () {
  6560      this.entered = true;
  6561      this.cancel = this.pendingJsCb = null;
  6562      removeClass(this.el, this.enterClass);
  6563      this.callHook('afterEnter');
  6564      if (this.cb) this.cb();
  6565    };
  6566  
  6567    /**
  6568     * Start a leaving transition.
  6569     *
  6570     * 1. leave transition triggered.
  6571     * 2. call beforeLeave hook
  6572     * 3. add leave class (trigger css transition)
  6573     * 4. call leave hook (with possible explicit js callback)
  6574     * 5. reflow if no explicit js callback is provided
  6575     * 6. based on transition type:
  6576     *    - transition or animation:
  6577     *        wait for end event, remove class, then done if
  6578     *        there's no explicit js callback.
  6579     *    - no css transition:
  6580     *        done if there's no explicit js callback.
  6581     * 7. wait for either done or js callback, then call
  6582     *    afterLeave hook.
  6583     *
  6584     * @param {Function} op - remove/hide the element
  6585     * @param {Function} [cb]
  6586     */
  6587  
  6588    p$1.leave = function (op, cb) {
  6589      this.cancelPending();
  6590      this.callHook('beforeLeave');
  6591      this.op = op;
  6592      this.cb = cb;
  6593      addClass(this.el, this.leaveClass);
  6594      this.left = false;
  6595      this.callHookWithCb('leave');
  6596      if (this.left) {
  6597        return; // user called done synchronously.
  6598      }
  6599      this.cancel = this.hooks && this.hooks.leaveCancelled;
  6600      // only need to handle leaveDone if
  6601      // 1. the transition is already done (synchronously called
  6602      //    by the user, which causes this.op set to null)
  6603      // 2. there's no explicit js callback
  6604      if (this.op && !this.pendingJsCb) {
  6605        // if a CSS transition leaves immediately after enter,
  6606        // the transitionend event never fires. therefore we
  6607        // detect such cases and end the leave immediately.
  6608        if (this.justEntered) {
  6609          this.leaveDone();
  6610        } else {
  6611          pushJob(this.leaveNextTick);
  6612        }
  6613      }
  6614    };
  6615  
  6616    /**
  6617     * The "nextTick" phase of a leaving transition.
  6618     */
  6619  
  6620    p$1.leaveNextTick = function () {
  6621      var type = this.getCssTransitionType(this.leaveClass);
  6622      if (type) {
  6623        var event = type === TYPE_TRANSITION ? transitionEndEvent : animationEndEvent;
  6624        this.setupCssCb(event, this.leaveDone);
  6625      } else {
  6626        this.leaveDone();
  6627      }
  6628    };
  6629  
  6630    /**
  6631     * The "cleanup" phase of a leaving transition.
  6632     */
  6633  
  6634    p$1.leaveDone = function () {
  6635      this.left = true;
  6636      this.cancel = this.pendingJsCb = null;
  6637      this.op();
  6638      removeClass(this.el, this.leaveClass);
  6639      this.callHook('afterLeave');
  6640      if (this.cb) this.cb();
  6641      this.op = null;
  6642    };
  6643  
  6644    /**
  6645     * Cancel any pending callbacks from a previously running
  6646     * but not finished transition.
  6647     */
  6648  
  6649    p$1.cancelPending = function () {
  6650      this.op = this.cb = null;
  6651      var hasPending = false;
  6652      if (this.pendingCssCb) {
  6653        hasPending = true;
  6654        off(this.el, this.pendingCssEvent, this.pendingCssCb);
  6655        this.pendingCssEvent = this.pendingCssCb = null;
  6656      }
  6657      if (this.pendingJsCb) {
  6658        hasPending = true;
  6659        this.pendingJsCb.cancel();
  6660        this.pendingJsCb = null;
  6661      }
  6662      if (hasPending) {
  6663        removeClass(this.el, this.enterClass);
  6664        removeClass(this.el, this.leaveClass);
  6665      }
  6666      if (this.cancel) {
  6667        this.cancel.call(this.vm, this.el);
  6668        this.cancel = null;
  6669      }
  6670    };
  6671  
  6672    /**
  6673     * Call a user-provided synchronous hook function.
  6674     *
  6675     * @param {String} type
  6676     */
  6677  
  6678    p$1.callHook = function (type) {
  6679      if (this.hooks && this.hooks[type]) {
  6680        this.hooks[type].call(this.vm, this.el);
  6681      }
  6682    };
  6683  
  6684    /**
  6685     * Call a user-provided, potentially-async hook function.
  6686     * We check for the length of arguments to see if the hook
  6687     * expects a `done` callback. If true, the transition's end
  6688     * will be determined by when the user calls that callback;
  6689     * otherwise, the end is determined by the CSS transition or
  6690     * animation.
  6691     *
  6692     * @param {String} type
  6693     */
  6694  
  6695    p$1.callHookWithCb = function (type) {
  6696      var hook = this.hooks && this.hooks[type];
  6697      if (hook) {
  6698        if (hook.length > 1) {
  6699          this.pendingJsCb = cancellable(this[type + 'Done']);
  6700        }
  6701        hook.call(this.vm, this.el, this.pendingJsCb);
  6702      }
  6703    };
  6704  
  6705    /**
  6706     * Get an element's transition type based on the
  6707     * calculated styles.
  6708     *
  6709     * @param {String} className
  6710     * @return {Number}
  6711     */
  6712  
  6713    p$1.getCssTransitionType = function (className) {
  6714      /* istanbul ignore if */
  6715      if (!transitionEndEvent ||
  6716      // skip CSS transitions if page is not visible -
  6717      // this solves the issue of transitionend events not
  6718      // firing until the page is visible again.
  6719      // pageVisibility API is supported in IE10+, same as
  6720      // CSS transitions.
  6721      document.hidden ||
  6722      // explicit js-only transition
  6723      this.hooks && this.hooks.css === false ||
  6724      // element is hidden
  6725      isHidden(this.el)) {
  6726        return;
  6727      }
  6728      var type = this.type || this.typeCache[className];
  6729      if (type) return type;
  6730      var inlineStyles = this.el.style;
  6731      var computedStyles = window.getComputedStyle(this.el);
  6732      var transDuration = inlineStyles[transDurationProp] || computedStyles[transDurationProp];
  6733      if (transDuration && transDuration !== '0s') {
  6734        type = TYPE_TRANSITION;
  6735      } else {
  6736        var animDuration = inlineStyles[animDurationProp] || computedStyles[animDurationProp];
  6737        if (animDuration && animDuration !== '0s') {
  6738          type = TYPE_ANIMATION;
  6739        }
  6740      }
  6741      if (type) {
  6742        this.typeCache[className] = type;
  6743      }
  6744      return type;
  6745    };
  6746  
  6747    /**
  6748     * Setup a CSS transitionend/animationend callback.
  6749     *
  6750     * @param {String} event
  6751     * @param {Function} cb
  6752     */
  6753  
  6754    p$1.setupCssCb = function (event, cb) {
  6755      this.pendingCssEvent = event;
  6756      var self = this;
  6757      var el = this.el;
  6758      var onEnd = this.pendingCssCb = function (e) {
  6759        if (e.target === el) {
  6760          off(el, event, onEnd);
  6761          self.pendingCssEvent = self.pendingCssCb = null;
  6762          if (!self.pendingJsCb && cb) {
  6763            cb();
  6764          }
  6765        }
  6766      };
  6767      on(el, event, onEnd);
  6768    };
  6769  
  6770    /**
  6771     * Check if an element is hidden - in that case we can just
  6772     * skip the transition alltogether.
  6773     *
  6774     * @param {Element} el
  6775     * @return {Boolean}
  6776     */
  6777  
  6778    function isHidden(el) {
  6779      if (/svg$/.test(el.namespaceURI)) {
  6780        // SVG elements do not have offset(Width|Height)
  6781        // so we need to check the client rect
  6782        var rect = el.getBoundingClientRect();
  6783        return !(rect.width || rect.height);
  6784      } else {
  6785        return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
  6786      }
  6787    }
  6788  
  6789    var transition$1 = {
  6790  
  6791      priority: TRANSITION,
  6792  
  6793      update: function update(id, oldId) {
  6794        var el = this.el;
  6795        // resolve on owner vm
  6796        var hooks = resolveAsset(this.vm.$options, 'transitions', id);
  6797        id = id || 'v';
  6798        el.__v_trans = new Transition(el, id, hooks, this.vm);
  6799        if (oldId) {
  6800          removeClass(el, oldId + '-transition');
  6801        }
  6802        addClass(el, id + '-transition');
  6803      }
  6804    };
  6805  
  6806    var internalDirectives = {
  6807      style: style,
  6808      'class': vClass,
  6809      component: component,
  6810      prop: propDef,
  6811      transition: transition$1
  6812    };
  6813  
  6814    // special binding prefixes
  6815    var bindRE = /^v-bind:|^:/;
  6816    var onRE = /^v-on:|^@/;
  6817    var dirAttrRE = /^v-([^:]+)(?:$|:(.*)$)/;
  6818    var modifierRE = /\.[^\.]+/g;
  6819    var transitionRE = /^(v-bind:|:)?transition$/;
  6820  
  6821    // default directive priority
  6822    var DEFAULT_PRIORITY = 1000;
  6823    var DEFAULT_TERMINAL_PRIORITY = 2000;
  6824  
  6825    /**
  6826     * Compile a template and return a reusable composite link
  6827     * function, which recursively contains more link functions
  6828     * inside. This top level compile function would normally
  6829     * be called on instance root nodes, but can also be used
  6830     * for partial compilation if the partial argument is true.
  6831     *
  6832     * The returned composite link function, when called, will
  6833     * return an unlink function that tearsdown all directives
  6834     * created during the linking phase.
  6835     *
  6836     * @param {Element|DocumentFragment} el
  6837     * @param {Object} options
  6838     * @param {Boolean} partial
  6839     * @return {Function}
  6840     */
  6841  
  6842    function compile(el, options, partial) {
  6843      // link function for the node itself.
  6844      var nodeLinkFn = partial || !options._asComponent ? compileNode(el, options) : null;
  6845      // link function for the childNodes
  6846      var childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && !isScript(el) && el.hasChildNodes() ? compileNodeList(el.childNodes, options) : null;
  6847  
  6848      /**
  6849       * A composite linker function to be called on a already
  6850       * compiled piece of DOM, which instantiates all directive
  6851       * instances.
  6852       *
  6853       * @param {Vue} vm
  6854       * @param {Element|DocumentFragment} el
  6855       * @param {Vue} [host] - host vm of transcluded content
  6856       * @param {Object} [scope] - v-for scope
  6857       * @param {Fragment} [frag] - link context fragment
  6858       * @return {Function|undefined}
  6859       */
  6860  
  6861      return function compositeLinkFn(vm, el, host, scope, frag) {
  6862        // cache childNodes before linking parent, fix #657
  6863        var childNodes = toArray(el.childNodes);
  6864        // link
  6865        var dirs = linkAndCapture(function compositeLinkCapturer() {
  6866          if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag);
  6867          if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag);
  6868        }, vm);
  6869        return makeUnlinkFn(vm, dirs);
  6870      };
  6871    }
  6872  
  6873    /**
  6874     * Apply a linker to a vm/element pair and capture the
  6875     * directives created during the process.
  6876     *
  6877     * @param {Function} linker
  6878     * @param {Vue} vm
  6879     */
  6880  
  6881    function linkAndCapture(linker, vm) {
  6882      /* istanbul ignore if */
  6883      if ('development' === 'production') {}
  6884      var originalDirCount = vm._directives.length;
  6885      linker();
  6886      var dirs = vm._directives.slice(originalDirCount);
  6887      dirs.sort(directiveComparator);
  6888      for (var i = 0, l = dirs.length; i < l; i++) {
  6889        dirs[i]._bind();
  6890      }
  6891      return dirs;
  6892    }
  6893  
  6894    /**
  6895     * Directive priority sort comparator
  6896     *
  6897     * @param {Object} a
  6898     * @param {Object} b
  6899     */
  6900  
  6901    function directiveComparator(a, b) {
  6902      a = a.descriptor.def.priority || DEFAULT_PRIORITY;
  6903      b = b.descriptor.def.priority || DEFAULT_PRIORITY;
  6904      return a > b ? -1 : a === b ? 0 : 1;
  6905    }
  6906  
  6907    /**
  6908     * Linker functions return an unlink function that
  6909     * tearsdown all directives instances generated during
  6910     * the process.
  6911     *
  6912     * We create unlink functions with only the necessary
  6913     * information to avoid retaining additional closures.
  6914     *
  6915     * @param {Vue} vm
  6916     * @param {Array} dirs
  6917     * @param {Vue} [context]
  6918     * @param {Array} [contextDirs]
  6919     * @return {Function}
  6920     */
  6921  
  6922    function makeUnlinkFn(vm, dirs, context, contextDirs) {
  6923      function unlink(destroying) {
  6924        teardownDirs(vm, dirs, destroying);
  6925        if (context && contextDirs) {
  6926          teardownDirs(context, contextDirs);
  6927        }
  6928      }
  6929      // expose linked directives
  6930      unlink.dirs = dirs;
  6931      return unlink;
  6932    }
  6933  
  6934    /**
  6935     * Teardown partial linked directives.
  6936     *
  6937     * @param {Vue} vm
  6938     * @param {Array} dirs
  6939     * @param {Boolean} destroying
  6940     */
  6941  
  6942    function teardownDirs(vm, dirs, destroying) {
  6943      var i = dirs.length;
  6944      while (i--) {
  6945        dirs[i]._teardown();
  6946        if ('development' !== 'production' && !destroying) {
  6947          vm._directives.$remove(dirs[i]);
  6948        }
  6949      }
  6950    }
  6951  
  6952    /**
  6953     * Compile link props on an instance.
  6954     *
  6955     * @param {Vue} vm
  6956     * @param {Element} el
  6957     * @param {Object} props
  6958     * @param {Object} [scope]
  6959     * @return {Function}
  6960     */
  6961  
  6962    function compileAndLinkProps(vm, el, props, scope) {
  6963      var propsLinkFn = compileProps(el, props, vm);
  6964      var propDirs = linkAndCapture(function () {
  6965        propsLinkFn(vm, scope);
  6966      }, vm);
  6967      return makeUnlinkFn(vm, propDirs);
  6968    }
  6969  
  6970    /**
  6971     * Compile the root element of an instance.
  6972     *
  6973     * 1. attrs on context container (context scope)
  6974     * 2. attrs on the component template root node, if
  6975     *    replace:true (child scope)
  6976     *
  6977     * If this is a fragment instance, we only need to compile 1.
  6978     *
  6979     * @param {Element} el
  6980     * @param {Object} options
  6981     * @param {Object} contextOptions
  6982     * @return {Function}
  6983     */
  6984  
  6985    function compileRoot(el, options, contextOptions) {
  6986      var containerAttrs = options._containerAttrs;
  6987      var replacerAttrs = options._replacerAttrs;
  6988      var contextLinkFn, replacerLinkFn;
  6989  
  6990      // only need to compile other attributes for
  6991      // non-fragment instances
  6992      if (el.nodeType !== 11) {
  6993        // for components, container and replacer need to be
  6994        // compiled separately and linked in different scopes.
  6995        if (options._asComponent) {
  6996          // 2. container attributes
  6997          if (containerAttrs && contextOptions) {
  6998            contextLinkFn = compileDirectives(containerAttrs, contextOptions);
  6999          }
  7000          if (replacerAttrs) {
  7001            // 3. replacer attributes
  7002            replacerLinkFn = compileDirectives(replacerAttrs, options);
  7003          }
  7004        } else {
  7005          // non-component, just compile as a normal element.
  7006          replacerLinkFn = compileDirectives(el.attributes, options);
  7007        }
  7008      } else if ('development' !== 'production' && containerAttrs) {
  7009        // warn container directives for fragment instances
  7010        var names = containerAttrs.filter(function (attr) {
  7011          // allow vue-loader/vueify scoped css attributes
  7012          return attr.name.indexOf('_v-') < 0 &&
  7013          // allow event listeners
  7014          !onRE.test(attr.name) &&
  7015          // allow slots
  7016          attr.name !== 'slot';
  7017        }).map(function (attr) {
  7018          return '"' + attr.name + '"';
  7019        });
  7020        if (names.length) {
  7021          var plural = names.length > 1;
  7022          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');
  7023        }
  7024      }
  7025  
  7026      options._containerAttrs = options._replacerAttrs = null;
  7027      return function rootLinkFn(vm, el, scope) {
  7028        // link context scope dirs
  7029        var context = vm._context;
  7030        var contextDirs;
  7031        if (context && contextLinkFn) {
  7032          contextDirs = linkAndCapture(function () {
  7033            contextLinkFn(context, el, null, scope);
  7034          }, context);
  7035        }
  7036  
  7037        // link self
  7038        var selfDirs = linkAndCapture(function () {
  7039          if (replacerLinkFn) replacerLinkFn(vm, el);
  7040        }, vm);
  7041  
  7042        // return the unlink function that tearsdown context
  7043        // container directives.
  7044        return makeUnlinkFn(vm, selfDirs, context, contextDirs);
  7045      };
  7046    }
  7047  
  7048    /**
  7049     * Compile a node and return a nodeLinkFn based on the
  7050     * node type.
  7051     *
  7052     * @param {Node} node
  7053     * @param {Object} options
  7054     * @return {Function|null}
  7055     */
  7056  
  7057    function compileNode(node, options) {
  7058      var type = node.nodeType;
  7059      if (type === 1 && !isScript(node)) {
  7060        return compileElement(node, options);
  7061      } else if (type === 3 && node.data.trim()) {
  7062        return compileTextNode(node, options);
  7063      } else {
  7064        return null;
  7065      }
  7066    }
  7067  
  7068    /**
  7069     * Compile an element and return a nodeLinkFn.
  7070     *
  7071     * @param {Element} el
  7072     * @param {Object} options
  7073     * @return {Function|null}
  7074     */
  7075  
  7076    function compileElement(el, options) {
  7077      // preprocess textareas.
  7078      // textarea treats its text content as the initial value.
  7079      // just bind it as an attr directive for value.
  7080      if (el.tagName === 'TEXTAREA') {
  7081        var tokens = parseText(el.value);
  7082        if (tokens) {
  7083          el.setAttribute(':value', tokensToExp(tokens));
  7084          el.value = '';
  7085        }
  7086      }
  7087      var linkFn;
  7088      var hasAttrs = el.hasAttributes();
  7089      var attrs = hasAttrs && toArray(el.attributes);
  7090      // check terminal directives (for & if)
  7091      if (hasAttrs) {
  7092        linkFn = checkTerminalDirectives(el, attrs, options);
  7093      }
  7094      // check element directives
  7095      if (!linkFn) {
  7096        linkFn = checkElementDirectives(el, options);
  7097      }
  7098      // check component
  7099      if (!linkFn) {
  7100        linkFn = checkComponent(el, options);
  7101      }
  7102      // normal directives
  7103      if (!linkFn && hasAttrs) {
  7104        linkFn = compileDirectives(attrs, options);
  7105      }
  7106      return linkFn;
  7107    }
  7108  
  7109    /**
  7110     * Compile a textNode and return a nodeLinkFn.
  7111     *
  7112     * @param {TextNode} node
  7113     * @param {Object} options
  7114     * @return {Function|null} textNodeLinkFn
  7115     */
  7116  
  7117    function compileTextNode(node, options) {
  7118      // skip marked text nodes
  7119      if (node._skip) {
  7120        return removeText;
  7121      }
  7122  
  7123      var tokens = parseText(node.wholeText);
  7124      if (!tokens) {
  7125        return null;
  7126      }
  7127  
  7128      // mark adjacent text nodes as skipped,
  7129      // because we are using node.wholeText to compile
  7130      // all adjacent text nodes together. This fixes
  7131      // issues in IE where sometimes it splits up a single
  7132      // text node into multiple ones.
  7133      var next = node.nextSibling;
  7134      while (next && next.nodeType === 3) {
  7135        next._skip = true;
  7136        next = next.nextSibling;
  7137      }
  7138  
  7139      var frag = document.createDocumentFragment();
  7140      var el, token;
  7141      for (var i = 0, l = tokens.length; i < l; i++) {
  7142        token = tokens[i];
  7143        el = token.tag ? processTextToken(token, options) : document.createTextNode(token.value);
  7144        frag.appendChild(el);
  7145      }
  7146      return makeTextNodeLinkFn(tokens, frag, options);
  7147    }
  7148  
  7149    /**
  7150     * Linker for an skipped text node.
  7151     *
  7152     * @param {Vue} vm
  7153     * @param {Text} node
  7154     */
  7155  
  7156    function removeText(vm, node) {
  7157      remove(node);
  7158    }
  7159  
  7160    /**
  7161     * Process a single text token.
  7162     *
  7163     * @param {Object} token
  7164     * @param {Object} options
  7165     * @return {Node}
  7166     */
  7167  
  7168    function processTextToken(token, options) {
  7169      var el;
  7170      if (token.oneTime) {
  7171        el = document.createTextNode(token.value);
  7172      } else {
  7173        if (token.html) {
  7174          el = document.createComment('v-html');
  7175          setTokenType('html');
  7176        } else {
  7177          // IE will clean up empty textNodes during
  7178          // frag.cloneNode(true), so we have to give it
  7179          // something here...
  7180          el = document.createTextNode(' ');
  7181          setTokenType('text');
  7182        }
  7183      }
  7184      function setTokenType(type) {
  7185        if (token.descriptor) return;
  7186        var parsed = parseDirective(token.value);
  7187        token.descriptor = {
  7188          name: type,
  7189          def: directives[type],
  7190          expression: parsed.expression,
  7191          filters: parsed.filters
  7192        };
  7193      }
  7194      return el;
  7195    }
  7196  
  7197    /**
  7198     * Build a function that processes a textNode.
  7199     *
  7200     * @param {Array<Object>} tokens
  7201     * @param {DocumentFragment} frag
  7202     */
  7203  
  7204    function makeTextNodeLinkFn(tokens, frag) {
  7205      return function textNodeLinkFn(vm, el, host, scope) {
  7206        var fragClone = frag.cloneNode(true);
  7207        var childNodes = toArray(fragClone.childNodes);
  7208        var token, value, node;
  7209        for (var i = 0, l = tokens.length; i < l; i++) {
  7210          token = tokens[i];
  7211          value = token.value;
  7212          if (token.tag) {
  7213            node = childNodes[i];
  7214            if (token.oneTime) {
  7215              value = (scope || vm).$eval(value);
  7216              if (token.html) {
  7217                replace(node, parseTemplate(value, true));
  7218              } else {
  7219                node.data = value;
  7220              }
  7221            } else {
  7222              vm._bindDir(token.descriptor, node, host, scope);
  7223            }
  7224          }
  7225        }
  7226        replace(el, fragClone);
  7227      };
  7228    }
  7229  
  7230    /**
  7231     * Compile a node list and return a childLinkFn.
  7232     *
  7233     * @param {NodeList} nodeList
  7234     * @param {Object} options
  7235     * @return {Function|undefined}
  7236     */
  7237  
  7238    function compileNodeList(nodeList, options) {
  7239      var linkFns = [];
  7240      var nodeLinkFn, childLinkFn, node;
  7241      for (var i = 0, l = nodeList.length; i < l; i++) {
  7242        node = nodeList[i];
  7243        nodeLinkFn = compileNode(node, options);
  7244        childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && node.tagName !== 'SCRIPT' && node.hasChildNodes() ? compileNodeList(node.childNodes, options) : null;
  7245        linkFns.push(nodeLinkFn, childLinkFn);
  7246      }
  7247      return linkFns.length ? makeChildLinkFn(linkFns) : null;
  7248    }
  7249  
  7250    /**
  7251     * Make a child link function for a node's childNodes.
  7252     *
  7253     * @param {Array<Function>} linkFns
  7254     * @return {Function} childLinkFn
  7255     */
  7256  
  7257    function makeChildLinkFn(linkFns) {
  7258      return function childLinkFn(vm, nodes, host, scope, frag) {
  7259        var node, nodeLinkFn, childrenLinkFn;
  7260        for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
  7261          node = nodes[n];
  7262          nodeLinkFn = linkFns[i++];
  7263          childrenLinkFn = linkFns[i++];
  7264          // cache childNodes before linking parent, fix #657
  7265          var childNodes = toArray(node.childNodes);
  7266          if (nodeLinkFn) {
  7267            nodeLinkFn(vm, node, host, scope, frag);
  7268          }
  7269          if (childrenLinkFn) {
  7270            childrenLinkFn(vm, childNodes, host, scope, frag);
  7271          }
  7272        }
  7273      };
  7274    }
  7275  
  7276    /**
  7277     * Check for element directives (custom elements that should
  7278     * be resovled as terminal directives).
  7279     *
  7280     * @param {Element} el
  7281     * @param {Object} options
  7282     */
  7283  
  7284    function checkElementDirectives(el, options) {
  7285      var tag = el.tagName.toLowerCase();
  7286      if (commonTagRE.test(tag)) {
  7287        return;
  7288      }
  7289      var def = resolveAsset(options, 'elementDirectives', tag);
  7290      if (def) {
  7291        return makeTerminalNodeLinkFn(el, tag, '', options, def);
  7292      }
  7293    }
  7294  
  7295    /**
  7296     * Check if an element is a component. If yes, return
  7297     * a component link function.
  7298     *
  7299     * @param {Element} el
  7300     * @param {Object} options
  7301     * @return {Function|undefined}
  7302     */
  7303  
  7304    function checkComponent(el, options) {
  7305      var component = checkComponentAttr(el, options);
  7306      if (component) {
  7307        var ref = findRef(el);
  7308        var descriptor = {
  7309          name: 'component',
  7310          ref: ref,
  7311          expression: component.id,
  7312          def: internalDirectives.component,
  7313          modifiers: {
  7314            literal: !component.dynamic
  7315          }
  7316        };
  7317        var componentLinkFn = function componentLinkFn(vm, el, host, scope, frag) {
  7318          if (ref) {
  7319            defineReactive((scope || vm).$refs, ref, null);
  7320          }
  7321          vm._bindDir(descriptor, el, host, scope, frag);
  7322        };
  7323        componentLinkFn.terminal = true;
  7324        return componentLinkFn;
  7325      }
  7326    }
  7327  
  7328    /**
  7329     * Check an element for terminal directives in fixed order.
  7330     * If it finds one, return a terminal link function.
  7331     *
  7332     * @param {Element} el
  7333     * @param {Array} attrs
  7334     * @param {Object} options
  7335     * @return {Function} terminalLinkFn
  7336     */
  7337  
  7338    function checkTerminalDirectives(el, attrs, options) {
  7339      // skip v-pre
  7340      if (getAttr(el, 'v-pre') !== null) {
  7341        return skip;
  7342      }
  7343      // skip v-else block, but only if following v-if
  7344      if (el.hasAttribute('v-else')) {
  7345        var prev = el.previousElementSibling;
  7346        if (prev && prev.hasAttribute('v-if')) {
  7347          return skip;
  7348        }
  7349      }
  7350  
  7351      var attr, name, value, modifiers, matched, dirName, rawName, arg, def, termDef;
  7352      for (var i = 0, j = attrs.length; i < j; i++) {
  7353        attr = attrs[i];
  7354        name = attr.name.replace(modifierRE, '');
  7355        if (matched = name.match(dirAttrRE)) {
  7356          def = resolveAsset(options, 'directives', matched[1]);
  7357          if (def && def.terminal) {
  7358            if (!termDef || (def.priority || DEFAULT_TERMINAL_PRIORITY) > termDef.priority) {
  7359              termDef = def;
  7360              rawName = attr.name;
  7361              modifiers = parseModifiers(attr.name);
  7362              value = attr.value;
  7363              dirName = matched[1];
  7364              arg = matched[2];
  7365            }
  7366          }
  7367        }
  7368      }
  7369  
  7370      if (termDef) {
  7371        return makeTerminalNodeLinkFn(el, dirName, value, options, termDef, rawName, arg, modifiers);
  7372      }
  7373    }
  7374  
  7375    function skip() {}
  7376    skip.terminal = true;
  7377  
  7378    /**
  7379     * Build a node link function for a terminal directive.
  7380     * A terminal link function terminates the current
  7381     * compilation recursion and handles compilation of the
  7382     * subtree in the directive.
  7383     *
  7384     * @param {Element} el
  7385     * @param {String} dirName
  7386     * @param {String} value
  7387     * @param {Object} options
  7388     * @param {Object} def
  7389     * @param {String} [rawName]
  7390     * @param {String} [arg]
  7391     * @param {Object} [modifiers]
  7392     * @return {Function} terminalLinkFn
  7393     */
  7394  
  7395    function makeTerminalNodeLinkFn(el, dirName, value, options, def, rawName, arg, modifiers) {
  7396      var parsed = parseDirective(value);
  7397      var descriptor = {
  7398        name: dirName,
  7399        arg: arg,
  7400        expression: parsed.expression,
  7401        filters: parsed.filters,
  7402        raw: value,
  7403        attr: rawName,
  7404        modifiers: modifiers,
  7405        def: def
  7406      };
  7407      // check ref for v-for and router-view
  7408      if (dirName === 'for' || dirName === 'router-view') {
  7409        descriptor.ref = findRef(el);
  7410      }
  7411      var fn = function terminalNodeLinkFn(vm, el, host, scope, frag) {
  7412        if (descriptor.ref) {
  7413          defineReactive((scope || vm).$refs, descriptor.ref, null);
  7414        }
  7415        vm._bindDir(descriptor, el, host, scope, frag);
  7416      };
  7417      fn.terminal = true;
  7418      return fn;
  7419    }
  7420  
  7421    /**
  7422     * Compile the directives on an element and return a linker.
  7423     *
  7424     * @param {Array|NamedNodeMap} attrs
  7425     * @param {Object} options
  7426     * @return {Function}
  7427     */
  7428  
  7429    function compileDirectives(attrs, options) {
  7430      var i = attrs.length;
  7431      var dirs = [];
  7432      var attr, name, value, rawName, rawValue, dirName, arg, modifiers, dirDef, tokens, matched;
  7433      while (i--) {
  7434        attr = attrs[i];
  7435        name = rawName = attr.name;
  7436        value = rawValue = attr.value;
  7437        tokens = parseText(value);
  7438        // reset arg
  7439        arg = null;
  7440        // check modifiers
  7441        modifiers = parseModifiers(name);
  7442        name = name.replace(modifierRE, '');
  7443  
  7444        // attribute interpolations
  7445        if (tokens) {
  7446          value = tokensToExp(tokens);
  7447          arg = name;
  7448          pushDir('bind', directives.bind, tokens);
  7449          // warn against mixing mustaches with v-bind
  7450          if ('development' !== 'production') {
  7451            if (name === 'class' && Array.prototype.some.call(attrs, function (attr) {
  7452              return attr.name === ':class' || attr.name === 'v-bind:class';
  7453            })) {
  7454              warn('class="' + rawValue + '": Do not mix mustache interpolation ' + 'and v-bind for "class" on the same element. Use one or the other.', options);
  7455            }
  7456          }
  7457        } else
  7458  
  7459          // special attribute: transition
  7460          if (transitionRE.test(name)) {
  7461            modifiers.literal = !bindRE.test(name);
  7462            pushDir('transition', internalDirectives.transition);
  7463          } else
  7464  
  7465            // event handlers
  7466            if (onRE.test(name)) {
  7467              arg = name.replace(onRE, '');
  7468              pushDir('on', directives.on);
  7469            } else
  7470  
  7471              // attribute bindings
  7472              if (bindRE.test(name)) {
  7473                dirName = name.replace(bindRE, '');
  7474                if (dirName === 'style' || dirName === 'class') {
  7475                  pushDir(dirName, internalDirectives[dirName]);
  7476                } else {
  7477                  arg = dirName;
  7478                  pushDir('bind', directives.bind);
  7479                }
  7480              } else
  7481  
  7482                // normal directives
  7483                if (matched = name.match(dirAttrRE)) {
  7484                  dirName = matched[1];
  7485                  arg = matched[2];
  7486  
  7487                  // skip v-else (when used with v-show)
  7488                  if (dirName === 'else') {
  7489                    continue;
  7490                  }
  7491  
  7492                  dirDef = resolveAsset(options, 'directives', dirName, true);
  7493                  if (dirDef) {
  7494                    pushDir(dirName, dirDef);
  7495                  }
  7496                }
  7497      }
  7498  
  7499      /**
  7500       * Push a directive.
  7501       *
  7502       * @param {String} dirName
  7503       * @param {Object|Function} def
  7504       * @param {Array} [interpTokens]
  7505       */
  7506  
  7507      function pushDir(dirName, def, interpTokens) {
  7508        var hasOneTimeToken = interpTokens && hasOneTime(interpTokens);
  7509        var parsed = !hasOneTimeToken && parseDirective(value);
  7510        dirs.push({
  7511          name: dirName,
  7512          attr: rawName,
  7513          raw: rawValue,
  7514          def: def,
  7515          arg: arg,
  7516          modifiers: modifiers,
  7517          // conversion from interpolation strings with one-time token
  7518          // to expression is differed until directive bind time so that we
  7519          // have access to the actual vm context for one-time bindings.
  7520          expression: parsed && parsed.expression,
  7521          filters: parsed && parsed.filters,
  7522          interp: interpTokens,
  7523          hasOneTime: hasOneTimeToken
  7524        });
  7525      }
  7526  
  7527      if (dirs.length) {
  7528        return makeNodeLinkFn(dirs);
  7529      }
  7530    }
  7531  
  7532    /**
  7533     * Parse modifiers from directive attribute name.
  7534     *
  7535     * @param {String} name
  7536     * @return {Object}
  7537     */
  7538  
  7539    function parseModifiers(name) {
  7540      var res = Object.create(null);
  7541      var match = name.match(modifierRE);
  7542      if (match) {
  7543        var i = match.length;
  7544        while (i--) {
  7545          res[match[i].slice(1)] = true;
  7546        }
  7547      }
  7548      return res;
  7549    }
  7550  
  7551    /**
  7552     * Build a link function for all directives on a single node.
  7553     *
  7554     * @param {Array} directives
  7555     * @return {Function} directivesLinkFn
  7556     */
  7557  
  7558    function makeNodeLinkFn(directives) {
  7559      return function nodeLinkFn(vm, el, host, scope, frag) {
  7560        // reverse apply because it's sorted low to high
  7561        var i = directives.length;
  7562        while (i--) {
  7563          vm._bindDir(directives[i], el, host, scope, frag);
  7564        }
  7565      };
  7566    }
  7567  
  7568    /**
  7569     * Check if an interpolation string contains one-time tokens.
  7570     *
  7571     * @param {Array} tokens
  7572     * @return {Boolean}
  7573     */
  7574  
  7575    function hasOneTime(tokens) {
  7576      var i = tokens.length;
  7577      while (i--) {
  7578        if (tokens[i].oneTime) return true;
  7579      }
  7580    }
  7581  
  7582    function isScript(el) {
  7583      return el.tagName === 'SCRIPT' && (!el.hasAttribute('type') || el.getAttribute('type') === 'text/javascript');
  7584    }
  7585  
  7586    var specialCharRE = /[^\w\-:\.]/;
  7587  
  7588    /**
  7589     * Process an element or a DocumentFragment based on a
  7590     * instance option object. This allows us to transclude
  7591     * a template node/fragment before the instance is created,
  7592     * so the processed fragment can then be cloned and reused
  7593     * in v-for.
  7594     *
  7595     * @param {Element} el
  7596     * @param {Object} options
  7597     * @return {Element|DocumentFragment}
  7598     */
  7599  
  7600    function transclude(el, options) {
  7601      // extract container attributes to pass them down
  7602      // to compiler, because they need to be compiled in
  7603      // parent scope. we are mutating the options object here
  7604      // assuming the same object will be used for compile
  7605      // right after this.
  7606      if (options) {
  7607        options._containerAttrs = extractAttrs(el);
  7608      }
  7609      // for template tags, what we want is its content as
  7610      // a documentFragment (for fragment instances)
  7611      if (isTemplate(el)) {
  7612        el = parseTemplate(el);
  7613      }
  7614      if (options) {
  7615        if (options._asComponent && !options.template) {
  7616          options.template = '<slot></slot>';
  7617        }
  7618        if (options.template) {
  7619          options._content = extractContent(el);
  7620          el = transcludeTemplate(el, options);
  7621        }
  7622      }
  7623      if (isFragment(el)) {
  7624        // anchors for fragment instance
  7625        // passing in `persist: true` to avoid them being
  7626        // discarded by IE during template cloning
  7627        prepend(createAnchor('v-start', true), el);
  7628        el.appendChild(createAnchor('v-end', true));
  7629      }
  7630      return el;
  7631    }
  7632  
  7633    /**
  7634     * Process the template option.
  7635     * If the replace option is true this will swap the $el.
  7636     *
  7637     * @param {Element} el
  7638     * @param {Object} options
  7639     * @return {Element|DocumentFragment}
  7640     */
  7641  
  7642    function transcludeTemplate(el, options) {
  7643      var template = options.template;
  7644      var frag = parseTemplate(template, true);
  7645      if (frag) {
  7646        var replacer = frag.firstChild;
  7647        var tag = replacer.tagName && replacer.tagName.toLowerCase();
  7648        if (options.replace) {
  7649          /* istanbul ignore if */
  7650          if (el === document.body) {
  7651            'development' !== 'production' && warn('You are mounting an instance with a template to ' + '<body>. This will replace <body> entirely. You ' + 'should probably use `replace: false` here.');
  7652          }
  7653          // there are many cases where the instance must
  7654          // become a fragment instance: basically anything that
  7655          // can create more than 1 root nodes.
  7656          if (
  7657          // multi-children template
  7658          frag.childNodes.length > 1 ||
  7659          // non-element template
  7660          replacer.nodeType !== 1 ||
  7661          // single nested component
  7662          tag === 'component' || resolveAsset(options, 'components', tag) || hasBindAttr(replacer, 'is') ||
  7663          // element directive
  7664          resolveAsset(options, 'elementDirectives', tag) ||
  7665          // for block
  7666          replacer.hasAttribute('v-for') ||
  7667          // if block
  7668          replacer.hasAttribute('v-if')) {
  7669            return frag;
  7670          } else {
  7671            options._replacerAttrs = extractAttrs(replacer);
  7672            mergeAttrs(el, replacer);
  7673            return replacer;
  7674          }
  7675        } else {
  7676          el.appendChild(frag);
  7677          return el;
  7678        }
  7679      } else {
  7680        'development' !== 'production' && warn('Invalid template option: ' + template);
  7681      }
  7682    }
  7683  
  7684    /**
  7685     * Helper to extract a component container's attributes
  7686     * into a plain object array.
  7687     *
  7688     * @param {Element} el
  7689     * @return {Array}
  7690     */
  7691  
  7692    function extractAttrs(el) {
  7693      if (el.nodeType === 1 && el.hasAttributes()) {
  7694        return toArray(el.attributes);
  7695      }
  7696    }
  7697  
  7698    /**
  7699     * Merge the attributes of two elements, and make sure
  7700     * the class names are merged properly.
  7701     *
  7702     * @param {Element} from
  7703     * @param {Element} to
  7704     */
  7705  
  7706    function mergeAttrs(from, to) {
  7707      var attrs = from.attributes;
  7708      var i = attrs.length;
  7709      var name, value;
  7710      while (i--) {
  7711        name = attrs[i].name;
  7712        value = attrs[i].value;
  7713        if (!to.hasAttribute(name) && !specialCharRE.test(name)) {
  7714          to.setAttribute(name, value);
  7715        } else if (name === 'class' && !parseText(value) && (value = value.trim())) {
  7716          value.split(/\s+/).forEach(function (cls) {
  7717            addClass(to, cls);
  7718          });
  7719        }
  7720      }
  7721    }
  7722  
  7723    /**
  7724     * Scan and determine slot content distribution.
  7725     * We do this during transclusion instead at compile time so that
  7726     * the distribution is decoupled from the compilation order of
  7727     * the slots.
  7728     *
  7729     * @param {Element|DocumentFragment} template
  7730     * @param {Element} content
  7731     * @param {Vue} vm
  7732     */
  7733  
  7734    function resolveSlots(vm, content) {
  7735      if (!content) {
  7736        return;
  7737      }
  7738      var contents = vm._slotContents = Object.create(null);
  7739      var el, name;
  7740      for (var i = 0, l = content.children.length; i < l; i++) {
  7741        el = content.children[i];
  7742        /* eslint-disable no-cond-assign */
  7743        if (name = el.getAttribute('slot')) {
  7744          (contents[name] || (contents[name] = [])).push(el);
  7745        }
  7746        /* eslint-enable no-cond-assign */
  7747        if ('development' !== 'production' && getBindAttr(el, 'slot')) {
  7748          warn('The "slot" attribute must be static.', vm.$parent);
  7749        }
  7750      }
  7751      for (name in contents) {
  7752        contents[name] = extractFragment(contents[name], content);
  7753      }
  7754      if (content.hasChildNodes()) {
  7755        var nodes = content.childNodes;
  7756        if (nodes.length === 1 && nodes[0].nodeType === 3 && !nodes[0].data.trim()) {
  7757          return;
  7758        }
  7759        contents['default'] = extractFragment(content.childNodes, content);
  7760      }
  7761    }
  7762  
  7763    /**
  7764     * Extract qualified content nodes from a node list.
  7765     *
  7766     * @param {NodeList} nodes
  7767     * @return {DocumentFragment}
  7768     */
  7769  
  7770    function extractFragment(nodes, parent) {
  7771      var frag = document.createDocumentFragment();
  7772      nodes = toArray(nodes);
  7773      for (var i = 0, l = nodes.length; i < l; i++) {
  7774        var node = nodes[i];
  7775        if (isTemplate(node) && !node.hasAttribute('v-if') && !node.hasAttribute('v-for')) {
  7776          parent.removeChild(node);
  7777          node = parseTemplate(node, true);
  7778        }
  7779        frag.appendChild(node);
  7780      }
  7781      return frag;
  7782    }
  7783  
  7784  
  7785  
  7786    var compiler = Object.freeze({
  7787    	compile: compile,
  7788    	compileAndLinkProps: compileAndLinkProps,
  7789    	compileRoot: compileRoot,
  7790    	transclude: transclude,
  7791    	resolveSlots: resolveSlots
  7792    });
  7793  
  7794    function stateMixin (Vue) {
  7795      /**
  7796       * Accessor for `$data` property, since setting $data
  7797       * requires observing the new object and updating
  7798       * proxied properties.
  7799       */
  7800  
  7801      Object.defineProperty(Vue.prototype, '$data', {
  7802        get: function get() {
  7803          return this._data;
  7804        },
  7805        set: function set(newData) {
  7806          if (newData !== this._data) {
  7807            this._setData(newData);
  7808          }
  7809        }
  7810      });
  7811  
  7812      /**
  7813       * Setup the scope of an instance, which contains:
  7814       * - observed data
  7815       * - computed properties
  7816       * - user methods
  7817       * - meta properties
  7818       */
  7819  
  7820      Vue.prototype._initState = function () {
  7821        this._initProps();
  7822        this._initMeta();
  7823        this._initMethods();
  7824        this._initData();
  7825        this._initComputed();
  7826      };
  7827  
  7828      /**
  7829       * Initialize props.
  7830       */
  7831  
  7832      Vue.prototype._initProps = function () {
  7833        var options = this.$options;
  7834        var el = options.el;
  7835        var props = options.props;
  7836        if (props && !el) {
  7837          'development' !== 'production' && warn('Props will not be compiled if no `el` option is ' + 'provided at instantiation.', this);
  7838        }
  7839        // make sure to convert string selectors into element now
  7840        el = options.el = query(el);
  7841        this._propsUnlinkFn = el && el.nodeType === 1 && props
  7842        // props must be linked in proper scope if inside v-for
  7843        ? compileAndLinkProps(this, el, props, this._scope) : null;
  7844      };
  7845  
  7846      /**
  7847       * Initialize the data.
  7848       */
  7849  
  7850      Vue.prototype._initData = function () {
  7851        var dataFn = this.$options.data;
  7852        var data = this._data = dataFn ? dataFn() : {};
  7853        if (!isPlainObject(data)) {
  7854          data = {};
  7855          'development' !== 'production' && warn('data functions should return an object.', this);
  7856        }
  7857        var props = this._props;
  7858        // proxy data on instance
  7859        var keys = Object.keys(data);
  7860        var i, key;
  7861        i = keys.length;
  7862        while (i--) {
  7863          key = keys[i];
  7864          // there are two scenarios where we can proxy a data key:
  7865          // 1. it's not already defined as a prop
  7866          // 2. it's provided via a instantiation option AND there are no
  7867          //    template prop present
  7868          if (!props || !hasOwn(props, key)) {
  7869            this._proxy(key);
  7870          } else if ('development' !== 'production') {
  7871            warn('Data field "' + key + '" is already defined ' + 'as a prop. To provide default value for a prop, use the "default" ' + 'prop option; if you want to pass prop values to an instantiation ' + 'call, use the "propsData" option.', this);
  7872          }
  7873        }
  7874        // observe data
  7875        observe(data, this);
  7876      };
  7877  
  7878      /**
  7879       * Swap the instance's $data. Called in $data's setter.
  7880       *
  7881       * @param {Object} newData
  7882       */
  7883  
  7884      Vue.prototype._setData = function (newData) {
  7885        newData = newData || {};
  7886        var oldData = this._data;
  7887        this._data = newData;
  7888        var keys, key, i;
  7889        // unproxy keys not present in new data
  7890        keys = Object.keys(oldData);
  7891        i = keys.length;
  7892        while (i--) {
  7893          key = keys[i];
  7894          if (!(key in newData)) {
  7895            this._unproxy(key);
  7896          }
  7897        }
  7898        // proxy keys not already proxied,
  7899        // and trigger change for changed values
  7900        keys = Object.keys(newData);
  7901        i = keys.length;
  7902        while (i--) {
  7903          key = keys[i];
  7904          if (!hasOwn(this, key)) {
  7905            // new property
  7906            this._proxy(key);
  7907          }
  7908        }
  7909        oldData.__ob__.removeVm(this);
  7910        observe(newData, this);
  7911        this._digest();
  7912      };
  7913  
  7914      /**
  7915       * Proxy a property, so that
  7916       * vm.prop === vm._data.prop
  7917       *
  7918       * @param {String} key
  7919       */
  7920  
  7921      Vue.prototype._proxy = function (key) {
  7922        if (!isReserved(key)) {
  7923          // need to store ref to self here
  7924          // because these getter/setters might
  7925          // be called by child scopes via
  7926          // prototype inheritance.
  7927          var self = this;
  7928          Object.defineProperty(self, key, {
  7929            configurable: true,
  7930            enumerable: true,
  7931            get: function proxyGetter() {
  7932              return self._data[key];
  7933            },
  7934            set: function proxySetter(val) {
  7935              self._data[key] = val;
  7936            }
  7937          });
  7938        }
  7939      };
  7940  
  7941      /**
  7942       * Unproxy a property.
  7943       *
  7944       * @param {String} key
  7945       */
  7946  
  7947      Vue.prototype._unproxy = function (key) {
  7948        if (!isReserved(key)) {
  7949          delete this[key];
  7950        }
  7951      };
  7952  
  7953      /**
  7954       * Force update on every watcher in scope.
  7955       */
  7956  
  7957      Vue.prototype._digest = function () {
  7958        for (var i = 0, l = this._watchers.length; i < l; i++) {
  7959          this._watchers[i].update(true); // shallow updates
  7960        }
  7961      };
  7962  
  7963      /**
  7964       * Setup computed properties. They are essentially
  7965       * special getter/setters
  7966       */
  7967  
  7968      function noop() {}
  7969      Vue.prototype._initComputed = function () {
  7970        var computed = this.$options.computed;
  7971        if (computed) {
  7972          for (var key in computed) {
  7973            var userDef = computed[key];
  7974            var def = {
  7975              enumerable: true,
  7976              configurable: true
  7977            };
  7978            if (typeof userDef === 'function') {
  7979              def.get = makeComputedGetter(userDef, this);
  7980              def.set = noop;
  7981            } else {
  7982              def.get = userDef.get ? userDef.cache !== false ? makeComputedGetter(userDef.get, this) : bind(userDef.get, this) : noop;
  7983              def.set = userDef.set ? bind(userDef.set, this) : noop;
  7984            }
  7985            Object.defineProperty(this, key, def);
  7986          }
  7987        }
  7988      };
  7989  
  7990      function makeComputedGetter(getter, owner) {
  7991        var watcher = new Watcher(owner, getter, null, {
  7992          lazy: true
  7993        });
  7994        return function computedGetter() {
  7995          if (watcher.dirty) {
  7996            watcher.evaluate();
  7997          }
  7998          if (Dep.target) {
  7999            watcher.depend();
  8000          }
  8001          return watcher.value;
  8002        };
  8003      }
  8004  
  8005      /**
  8006       * Setup instance methods. Methods must be bound to the
  8007       * instance since they might be passed down as a prop to
  8008       * child components.
  8009       */
  8010  
  8011      Vue.prototype._initMethods = function () {
  8012        var methods = this.$options.methods;
  8013        if (methods) {
  8014          for (var key in methods) {
  8015            this[key] = bind(methods[key], this);
  8016          }
  8017        }
  8018      };
  8019  
  8020      /**
  8021       * Initialize meta information like $index, $key & $value.
  8022       */
  8023  
  8024      Vue.prototype._initMeta = function () {
  8025        var metas = this.$options._meta;
  8026        if (metas) {
  8027          for (var key in metas) {
  8028            defineReactive(this, key, metas[key]);
  8029          }
  8030        }
  8031      };
  8032    }
  8033  
  8034    var eventRE = /^v-on:|^@/;
  8035  
  8036    function eventsMixin (Vue) {
  8037      /**
  8038       * Setup the instance's option events & watchers.
  8039       * If the value is a string, we pull it from the
  8040       * instance's methods by name.
  8041       */
  8042  
  8043      Vue.prototype._initEvents = function () {
  8044        var options = this.$options;
  8045        if (options._asComponent) {
  8046          registerComponentEvents(this, options.el);
  8047        }
  8048        registerCallbacks(this, '$on', options.events);
  8049        registerCallbacks(this, '$watch', options.watch);
  8050      };
  8051  
  8052      /**
  8053       * Register v-on events on a child component
  8054       *
  8055       * @param {Vue} vm
  8056       * @param {Element} el
  8057       */
  8058  
  8059      function registerComponentEvents(vm, el) {
  8060        var attrs = el.attributes;
  8061        var name, value, handler;
  8062        for (var i = 0, l = attrs.length; i < l; i++) {
  8063          name = attrs[i].name;
  8064          if (eventRE.test(name)) {
  8065            name = name.replace(eventRE, '');
  8066            // force the expression into a statement so that
  8067            // it always dynamically resolves the method to call (#2670)
  8068            // kinda ugly hack, but does the job.
  8069            value = attrs[i].value;
  8070            if (isSimplePath(value)) {
  8071              value += '.apply(this, $arguments)';
  8072            }
  8073            handler = (vm._scope || vm._context).$eval(value, true);
  8074            handler._fromParent = true;
  8075            vm.$on(name.replace(eventRE), handler);
  8076          }
  8077        }
  8078      }
  8079  
  8080      /**
  8081       * Register callbacks for option events and watchers.
  8082       *
  8083       * @param {Vue} vm
  8084       * @param {String} action
  8085       * @param {Object} hash
  8086       */
  8087  
  8088      function registerCallbacks(vm, action, hash) {
  8089        if (!hash) return;
  8090        var handlers, key, i, j;
  8091        for (key in hash) {
  8092          handlers = hash[key];
  8093          if (isArray(handlers)) {
  8094            for (i = 0, j = handlers.length; i < j; i++) {
  8095              register(vm, action, key, handlers[i]);
  8096            }
  8097          } else {
  8098            register(vm, action, key, handlers);
  8099          }
  8100        }
  8101      }
  8102  
  8103      /**
  8104       * Helper to register an event/watch callback.
  8105       *
  8106       * @param {Vue} vm
  8107       * @param {String} action
  8108       * @param {String} key
  8109       * @param {Function|String|Object} handler
  8110       * @param {Object} [options]
  8111       */
  8112  
  8113      function register(vm, action, key, handler, options) {
  8114        var type = typeof handler;
  8115        if (type === 'function') {
  8116          vm[action](key, handler, options);
  8117        } else if (type === 'string') {
  8118          var methods = vm.$options.methods;
  8119          var method = methods && methods[handler];
  8120          if (method) {
  8121            vm[action](key, method, options);
  8122          } else {
  8123            'development' !== 'production' && warn('Unknown method: "' + handler + '" when ' + 'registering callback for ' + action + ': "' + key + '".', vm);
  8124          }
  8125        } else if (handler && type === 'object') {
  8126          register(vm, action, key, handler.handler, handler);
  8127        }
  8128      }
  8129  
  8130      /**
  8131       * Setup recursive attached/detached calls
  8132       */
  8133  
  8134      Vue.prototype._initDOMHooks = function () {
  8135        this.$on('hook:attached', onAttached);
  8136        this.$on('hook:detached', onDetached);
  8137      };
  8138  
  8139      /**
  8140       * Callback to recursively call attached hook on children
  8141       */
  8142  
  8143      function onAttached() {
  8144        if (!this._isAttached) {
  8145          this._isAttached = true;
  8146          this.$children.forEach(callAttach);
  8147        }
  8148      }
  8149  
  8150      /**
  8151       * Iterator to call attached hook
  8152       *
  8153       * @param {Vue} child
  8154       */
  8155  
  8156      function callAttach(child) {
  8157        if (!child._isAttached && inDoc(child.$el)) {
  8158          child._callHook('attached');
  8159        }
  8160      }
  8161  
  8162      /**
  8163       * Callback to recursively call detached hook on children
  8164       */
  8165  
  8166      function onDetached() {
  8167        if (this._isAttached) {
  8168          this._isAttached = false;
  8169          this.$children.forEach(callDetach);
  8170        }
  8171      }
  8172  
  8173      /**
  8174       * Iterator to call detached hook
  8175       *
  8176       * @param {Vue} child
  8177       */
  8178  
  8179      function callDetach(child) {
  8180        if (child._isAttached && !inDoc(child.$el)) {
  8181          child._callHook('detached');
  8182        }
  8183      }
  8184  
  8185      /**
  8186       * Trigger all handlers for a hook
  8187       *
  8188       * @param {String} hook
  8189       */
  8190  
  8191      Vue.prototype._callHook = function (hook) {
  8192        this.$emit('pre-hook:' + hook);
  8193        var handlers = this.$options[hook];
  8194        if (handlers) {
  8195          for (var i = 0, j = handlers.length; i < j; i++) {
  8196            handlers[i].call(this);
  8197          }
  8198        }
  8199        this.$emit('hook:' + hook);
  8200      };
  8201    }
  8202  
  8203    function noop() {}
  8204  
  8205    /**
  8206     * A directive links a DOM element with a piece of data,
  8207     * which is the result of evaluating an expression.
  8208     * It registers a watcher with the expression and calls
  8209     * the DOM update function when a change is triggered.
  8210     *
  8211     * @param {Object} descriptor
  8212     *                 - {String} name
  8213     *                 - {Object} def
  8214     *                 - {String} expression
  8215     *                 - {Array<Object>} [filters]
  8216     *                 - {Object} [modifiers]
  8217     *                 - {Boolean} literal
  8218     *                 - {String} attr
  8219     *                 - {String} arg
  8220     *                 - {String} raw
  8221     *                 - {String} [ref]
  8222     *                 - {Array<Object>} [interp]
  8223     *                 - {Boolean} [hasOneTime]
  8224     * @param {Vue} vm
  8225     * @param {Node} el
  8226     * @param {Vue} [host] - transclusion host component
  8227     * @param {Object} [scope] - v-for scope
  8228     * @param {Fragment} [frag] - owner fragment
  8229     * @constructor
  8230     */
  8231    function Directive(descriptor, vm, el, host, scope, frag) {
  8232      this.vm = vm;
  8233      this.el = el;
  8234      // copy descriptor properties
  8235      this.descriptor = descriptor;
  8236      this.name = descriptor.name;
  8237      this.expression = descriptor.expression;
  8238      this.arg = descriptor.arg;
  8239      this.modifiers = descriptor.modifiers;
  8240      this.filters = descriptor.filters;
  8241      this.literal = this.modifiers && this.modifiers.literal;
  8242      // private
  8243      this._locked = false;
  8244      this._bound = false;
  8245      this._listeners = null;
  8246      // link context
  8247      this._host = host;
  8248      this._scope = scope;
  8249      this._frag = frag;
  8250      // store directives on node in dev mode
  8251      if ('development' !== 'production' && this.el) {
  8252        this.el._vue_directives = this.el._vue_directives || [];
  8253        this.el._vue_directives.push(this);
  8254      }
  8255    }
  8256  
  8257    /**
  8258     * Initialize the directive, mixin definition properties,
  8259     * setup the watcher, call definition bind() and update()
  8260     * if present.
  8261     */
  8262  
  8263    Directive.prototype._bind = function () {
  8264      var name = this.name;
  8265      var descriptor = this.descriptor;
  8266  
  8267      // remove attribute
  8268      if ((name !== 'cloak' || this.vm._isCompiled) && this.el && this.el.removeAttribute) {
  8269        var attr = descriptor.attr || 'v-' + name;
  8270        this.el.removeAttribute(attr);
  8271      }
  8272  
  8273      // copy def properties
  8274      var def = descriptor.def;
  8275      if (typeof def === 'function') {
  8276        this.update = def;
  8277      } else {
  8278        extend(this, def);
  8279      }
  8280  
  8281      // setup directive params
  8282      this._setupParams();
  8283  
  8284      // initial bind
  8285      if (this.bind) {
  8286        this.bind();
  8287      }
  8288      this._bound = true;
  8289  
  8290      if (this.literal) {
  8291        this.update && this.update(descriptor.raw);
  8292      } else if ((this.expression || this.modifiers) && (this.update || this.twoWay) && !this._checkStatement()) {
  8293        // wrapped updater for context
  8294        var dir = this;
  8295        if (this.update) {
  8296          this._update = function (val, oldVal) {
  8297            if (!dir._locked) {
  8298              dir.update(val, oldVal);
  8299            }
  8300          };
  8301        } else {
  8302          this._update = noop;
  8303        }
  8304        var preProcess = this._preProcess ? bind(this._preProcess, this) : null;
  8305        var postProcess = this._postProcess ? bind(this._postProcess, this) : null;
  8306        var watcher = this._watcher = new Watcher(this.vm, this.expression, this._update, // callback
  8307        {
  8308          filters: this.filters,
  8309          twoWay: this.twoWay,
  8310          deep: this.deep,
  8311          preProcess: preProcess,
  8312          postProcess: postProcess,
  8313          scope: this._scope
  8314        });
  8315        // v-model with inital inline value need to sync back to
  8316        // model instead of update to DOM on init. They would
  8317        // set the afterBind hook to indicate that.
  8318        if (this.afterBind) {
  8319          this.afterBind();
  8320        } else if (this.update) {
  8321          this.update(watcher.value);
  8322        }
  8323      }
  8324    };
  8325  
  8326    /**
  8327     * Setup all param attributes, e.g. track-by,
  8328     * transition-mode, etc...
  8329     */
  8330  
  8331    Directive.prototype._setupParams = function () {
  8332      if (!this.params) {
  8333        return;
  8334      }
  8335      var params = this.params;
  8336      // swap the params array with a fresh object.
  8337      this.params = Object.create(null);
  8338      var i = params.length;
  8339      var key, val, mappedKey;
  8340      while (i--) {
  8341        key = hyphenate(params[i]);
  8342        mappedKey = camelize(key);
  8343        val = getBindAttr(this.el, key);
  8344        if (val != null) {
  8345          // dynamic
  8346          this._setupParamWatcher(mappedKey, val);
  8347        } else {
  8348          // static
  8349          val = getAttr(this.el, key);
  8350          if (val != null) {
  8351            this.params[mappedKey] = val === '' ? true : val;
  8352          }
  8353        }
  8354      }
  8355    };
  8356  
  8357    /**
  8358     * Setup a watcher for a dynamic param.
  8359     *
  8360     * @param {String} key
  8361     * @param {String} expression
  8362     */
  8363  
  8364    Directive.prototype._setupParamWatcher = function (key, expression) {
  8365      var self = this;
  8366      var called = false;
  8367      var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
  8368        self.params[key] = val;
  8369        // since we are in immediate mode,
  8370        // only call the param change callbacks if this is not the first update.
  8371        if (called) {
  8372          var cb = self.paramWatchers && self.paramWatchers[key];
  8373          if (cb) {
  8374            cb.call(self, val, oldVal);
  8375          }
  8376        } else {
  8377          called = true;
  8378        }
  8379      }, {
  8380        immediate: true,
  8381        user: false
  8382      });(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
  8383    };
  8384  
  8385    /**
  8386     * Check if the directive is a function caller
  8387     * and if the expression is a callable one. If both true,
  8388     * we wrap up the expression and use it as the event
  8389     * handler.
  8390     *
  8391     * e.g. on-click="a++"
  8392     *
  8393     * @return {Boolean}
  8394     */
  8395  
  8396    Directive.prototype._checkStatement = function () {
  8397      var expression = this.expression;
  8398      if (expression && this.acceptStatement && !isSimplePath(expression)) {
  8399        var fn = parseExpression(expression).get;
  8400        var scope = this._scope || this.vm;
  8401        var handler = function handler(e) {
  8402          scope.$event = e;
  8403          fn.call(scope, scope);
  8404          scope.$event = null;
  8405        };
  8406        if (this.filters) {
  8407          handler = scope._applyFilters(handler, null, this.filters);
  8408        }
  8409        this.update(handler);
  8410        return true;
  8411      }
  8412    };
  8413  
  8414    /**
  8415     * Set the corresponding value with the setter.
  8416     * This should only be used in two-way directives
  8417     * e.g. v-model.
  8418     *
  8419     * @param {*} value
  8420     * @public
  8421     */
  8422  
  8423    Directive.prototype.set = function (value) {
  8424      /* istanbul ignore else */
  8425      if (this.twoWay) {
  8426        this._withLock(function () {
  8427          this._watcher.set(value);
  8428        });
  8429      } else if ('development' !== 'production') {
  8430        warn('Directive.set() can only be used inside twoWay' + 'directives.');
  8431      }
  8432    };
  8433  
  8434    /**
  8435     * Execute a function while preventing that function from
  8436     * triggering updates on this directive instance.
  8437     *
  8438     * @param {Function} fn
  8439     */
  8440  
  8441    Directive.prototype._withLock = function (fn) {
  8442      var self = this;
  8443      self._locked = true;
  8444      fn.call(self);
  8445      nextTick(function () {
  8446        self._locked = false;
  8447      });
  8448    };
  8449  
  8450    /**
  8451     * Convenience method that attaches a DOM event listener
  8452     * to the directive element and autometically tears it down
  8453     * during unbind.
  8454     *
  8455     * @param {String} event
  8456     * @param {Function} handler
  8457     * @param {Boolean} [useCapture]
  8458     */
  8459  
  8460    Directive.prototype.on = function (event, handler, useCapture) {
  8461      on(this.el, event, handler, useCapture);(this._listeners || (this._listeners = [])).push([event, handler]);
  8462    };
  8463  
  8464    /**
  8465     * Teardown the watcher and call unbind.
  8466     */
  8467  
  8468    Directive.prototype._teardown = function () {
  8469      if (this._bound) {
  8470        this._bound = false;
  8471        if (this.unbind) {
  8472          this.unbind();
  8473        }
  8474        if (this._watcher) {
  8475          this._watcher.teardown();
  8476        }
  8477        var listeners = this._listeners;
  8478        var i;
  8479        if (listeners) {
  8480          i = listeners.length;
  8481          while (i--) {
  8482            off(this.el, listeners[i][0], listeners[i][1]);
  8483          }
  8484        }
  8485        var unwatchFns = this._paramUnwatchFns;
  8486        if (unwatchFns) {
  8487          i = unwatchFns.length;
  8488          while (i--) {
  8489            unwatchFns[i]();
  8490          }
  8491        }
  8492        if ('development' !== 'production' && this.el) {
  8493          this.el._vue_directives.$remove(this);
  8494        }
  8495        this.vm = this.el = this._watcher = this._listeners = null;
  8496      }
  8497    };
  8498  
  8499    function lifecycleMixin (Vue) {
  8500      /**
  8501       * Update v-ref for component.
  8502       *
  8503       * @param {Boolean} remove
  8504       */
  8505  
  8506      Vue.prototype._updateRef = function (remove) {
  8507        var ref = this.$options._ref;
  8508        if (ref) {
  8509          var refs = (this._scope || this._context).$refs;
  8510          if (remove) {
  8511            if (refs[ref] === this) {
  8512              refs[ref] = null;
  8513            }
  8514          } else {
  8515            refs[ref] = this;
  8516          }
  8517        }
  8518      };
  8519  
  8520      /**
  8521       * Transclude, compile and link element.
  8522       *
  8523       * If a pre-compiled linker is available, that means the
  8524       * passed in element will be pre-transcluded and compiled
  8525       * as well - all we need to do is to call the linker.
  8526       *
  8527       * Otherwise we need to call transclude/compile/link here.
  8528       *
  8529       * @param {Element} el
  8530       */
  8531  
  8532      Vue.prototype._compile = function (el) {
  8533        var options = this.$options;
  8534  
  8535        // transclude and init element
  8536        // transclude can potentially replace original
  8537        // so we need to keep reference; this step also injects
  8538        // the template and caches the original attributes
  8539        // on the container node and replacer node.
  8540        var original = el;
  8541        el = transclude(el, options);
  8542        this._initElement(el);
  8543  
  8544        // handle v-pre on root node (#2026)
  8545        if (el.nodeType === 1 && getAttr(el, 'v-pre') !== null) {
  8546          return;
  8547        }
  8548  
  8549        // root is always compiled per-instance, because
  8550        // container attrs and props can be different every time.
  8551        var contextOptions = this._context && this._context.$options;
  8552        var rootLinker = compileRoot(el, options, contextOptions);
  8553  
  8554        // resolve slot distribution
  8555        resolveSlots(this, options._content);
  8556  
  8557        // compile and link the rest
  8558        var contentLinkFn;
  8559        var ctor = this.constructor;
  8560        // component compilation can be cached
  8561        // as long as it's not using inline-template
  8562        if (options._linkerCachable) {
  8563          contentLinkFn = ctor.linker;
  8564          if (!contentLinkFn) {
  8565            contentLinkFn = ctor.linker = compile(el, options);
  8566          }
  8567        }
  8568  
  8569        // link phase
  8570        // make sure to link root with prop scope!
  8571        var rootUnlinkFn = rootLinker(this, el, this._scope);
  8572        var contentUnlinkFn = contentLinkFn ? contentLinkFn(this, el) : compile(el, options)(this, el);
  8573  
  8574        // register composite unlink function
  8575        // to be called during instance destruction
  8576        this._unlinkFn = function () {
  8577          rootUnlinkFn();
  8578          // passing destroying: true to avoid searching and
  8579          // splicing the directives
  8580          contentUnlinkFn(true);
  8581        };
  8582  
  8583        // finally replace original
  8584        if (options.replace) {
  8585          replace(original, el);
  8586        }
  8587  
  8588        this._isCompiled = true;
  8589        this._callHook('compiled');
  8590      };
  8591  
  8592      /**
  8593       * Initialize instance element. Called in the public
  8594       * $mount() method.
  8595       *
  8596       * @param {Element} el
  8597       */
  8598  
  8599      Vue.prototype._initElement = function (el) {
  8600        if (isFragment(el)) {
  8601          this._isFragment = true;
  8602          this.$el = this._fragmentStart = el.firstChild;
  8603          this._fragmentEnd = el.lastChild;
  8604          // set persisted text anchors to empty
  8605          if (this._fragmentStart.nodeType === 3) {
  8606            this._fragmentStart.data = this._fragmentEnd.data = '';
  8607          }
  8608          this._fragment = el;
  8609        } else {
  8610          this.$el = el;
  8611        }
  8612        this.$el.__vue__ = this;
  8613        this._callHook('beforeCompile');
  8614      };
  8615  
  8616      /**
  8617       * Create and bind a directive to an element.
  8618       *
  8619       * @param {Object} descriptor - parsed directive descriptor
  8620       * @param {Node} node   - target node
  8621       * @param {Vue} [host] - transclusion host component
  8622       * @param {Object} [scope] - v-for scope
  8623       * @param {Fragment} [frag] - owner fragment
  8624       */
  8625  
  8626      Vue.prototype._bindDir = function (descriptor, node, host, scope, frag) {
  8627        this._directives.push(new Directive(descriptor, this, node, host, scope, frag));
  8628      };
  8629  
  8630      /**
  8631       * Teardown an instance, unobserves the data, unbind all the
  8632       * directives, turn off all the event listeners, etc.
  8633       *
  8634       * @param {Boolean} remove - whether to remove the DOM node.
  8635       * @param {Boolean} deferCleanup - if true, defer cleanup to
  8636       *                                 be called later
  8637       */
  8638  
  8639      Vue.prototype._destroy = function (remove, deferCleanup) {
  8640        if (this._isBeingDestroyed) {
  8641          if (!deferCleanup) {
  8642            this._cleanup();
  8643          }
  8644          return;
  8645        }
  8646  
  8647        var destroyReady;
  8648        var pendingRemoval;
  8649  
  8650        var self = this;
  8651        // Cleanup should be called either synchronously or asynchronoysly as
  8652        // callback of this.$remove(), or if remove and deferCleanup are false.
  8653        // In any case it should be called after all other removing, unbinding and
  8654        // turning of is done
  8655        var cleanupIfPossible = function cleanupIfPossible() {
  8656          if (destroyReady && !pendingRemoval && !deferCleanup) {
  8657            self._cleanup();
  8658          }
  8659        };
  8660  
  8661        // remove DOM element
  8662        if (remove && this.$el) {
  8663          pendingRemoval = true;
  8664          this.$remove(function () {
  8665            pendingRemoval = false;
  8666            cleanupIfPossible();
  8667          });
  8668        }
  8669  
  8670        this._callHook('beforeDestroy');
  8671        this._isBeingDestroyed = true;
  8672        var i;
  8673        // remove self from parent. only necessary
  8674        // if parent is not being destroyed as well.
  8675        var parent = this.$parent;
  8676        if (parent && !parent._isBeingDestroyed) {
  8677          parent.$children.$remove(this);
  8678          // unregister ref (remove: true)
  8679          this._updateRef(true);
  8680        }
  8681        // destroy all children.
  8682        i = this.$children.length;
  8683        while (i--) {
  8684          this.$children[i].$destroy();
  8685        }
  8686        // teardown props
  8687        if (this._propsUnlinkFn) {
  8688          this._propsUnlinkFn();
  8689        }
  8690        // teardown all directives. this also tearsdown all
  8691        // directive-owned watchers.
  8692        if (this._unlinkFn) {
  8693          this._unlinkFn();
  8694        }
  8695        i = this._watchers.length;
  8696        while (i--) {
  8697          this._watchers[i].teardown();
  8698        }
  8699        // remove reference to self on $el
  8700        if (this.$el) {
  8701          this.$el.__vue__ = null;
  8702        }
  8703  
  8704        destroyReady = true;
  8705        cleanupIfPossible();
  8706      };
  8707  
  8708      /**
  8709       * Clean up to ensure garbage collection.
  8710       * This is called after the leave transition if there
  8711       * is any.
  8712       */
  8713  
  8714      Vue.prototype._cleanup = function () {
  8715        if (this._isDestroyed) {
  8716          return;
  8717        }
  8718        // remove self from owner fragment
  8719        // do it in cleanup so that we can call $destroy with
  8720        // defer right when a fragment is about to be removed.
  8721        if (this._frag) {
  8722          this._frag.children.$remove(this);
  8723        }
  8724        // remove reference from data ob
  8725        // frozen object may not have observer.
  8726        if (this._data && this._data.__ob__) {
  8727          this._data.__ob__.removeVm(this);
  8728        }
  8729        // Clean up references to private properties and other
  8730        // instances. preserve reference to _data so that proxy
  8731        // accessors still work. The only potential side effect
  8732        // here is that mutating the instance after it's destroyed
  8733        // may affect the state of other components that are still
  8734        // observing the same object, but that seems to be a
  8735        // reasonable responsibility for the user rather than
  8736        // always throwing an error on them.
  8737        this.$el = this.$parent = this.$root = this.$children = this._watchers = this._context = this._scope = this._directives = null;
  8738        // call the last hook...
  8739        this._isDestroyed = true;
  8740        this._callHook('destroyed');
  8741        // turn off all instance listeners.
  8742        this.$off();
  8743      };
  8744    }
  8745  
  8746    function miscMixin (Vue) {
  8747      /**
  8748       * Apply a list of filter (descriptors) to a value.
  8749       * Using plain for loops here because this will be called in
  8750       * the getter of any watcher with filters so it is very
  8751       * performance sensitive.
  8752       *
  8753       * @param {*} value
  8754       * @param {*} [oldValue]
  8755       * @param {Array} filters
  8756       * @param {Boolean} write
  8757       * @return {*}
  8758       */
  8759  
  8760      Vue.prototype._applyFilters = function (value, oldValue, filters, write) {
  8761        var filter, fn, args, arg, offset, i, l, j, k;
  8762        for (i = 0, l = filters.length; i < l; i++) {
  8763          filter = filters[write ? l - i - 1 : i];
  8764          fn = resolveAsset(this.$options, 'filters', filter.name, true);
  8765          if (!fn) continue;
  8766          fn = write ? fn.write : fn.read || fn;
  8767          if (typeof fn !== 'function') continue;
  8768          args = write ? [value, oldValue] : [value];
  8769          offset = write ? 2 : 1;
  8770          if (filter.args) {
  8771            for (j = 0, k = filter.args.length; j < k; j++) {
  8772              arg = filter.args[j];
  8773              args[j + offset] = arg.dynamic ? this.$get(arg.value) : arg.value;
  8774            }
  8775          }
  8776          value = fn.apply(this, args);
  8777        }
  8778        return value;
  8779      };
  8780  
  8781      /**
  8782       * Resolve a component, depending on whether the component
  8783       * is defined normally or using an async factory function.
  8784       * Resolves synchronously if already resolved, otherwise
  8785       * resolves asynchronously and caches the resolved
  8786       * constructor on the factory.
  8787       *
  8788       * @param {String|Function} value
  8789       * @param {Function} cb
  8790       */
  8791  
  8792      Vue.prototype._resolveComponent = function (value, cb) {
  8793        var factory;
  8794        if (typeof value === 'function') {
  8795          factory = value;
  8796        } else {
  8797          factory = resolveAsset(this.$options, 'components', value, true);
  8798        }
  8799        /* istanbul ignore if */
  8800        if (!factory) {
  8801          return;
  8802        }
  8803        // async component factory
  8804        if (!factory.options) {
  8805          if (factory.resolved) {
  8806            // cached
  8807            cb(factory.resolved);
  8808          } else if (factory.requested) {
  8809            // pool callbacks
  8810            factory.pendingCallbacks.push(cb);
  8811          } else {
  8812            factory.requested = true;
  8813            var cbs = factory.pendingCallbacks = [cb];
  8814            factory.call(this, function resolve(res) {
  8815              if (isPlainObject(res)) {
  8816                res = Vue.extend(res);
  8817              }
  8818              // cache resolved
  8819              factory.resolved = res;
  8820              // invoke callbacks
  8821              for (var i = 0, l = cbs.length; i < l; i++) {
  8822                cbs[i](res);
  8823              }
  8824            }, function reject(reason) {
  8825              'development' !== 'production' && warn('Failed to resolve async component' + (typeof value === 'string' ? ': ' + value : '') + '. ' + (reason ? '\nReason: ' + reason : ''));
  8826            });
  8827          }
  8828        } else {
  8829          // normal component
  8830          cb(factory);
  8831        }
  8832      };
  8833    }
  8834  
  8835    var filterRE$1 = /[^|]\|[^|]/;
  8836  
  8837    function dataAPI (Vue) {
  8838      /**
  8839       * Get the value from an expression on this vm.
  8840       *
  8841       * @param {String} exp
  8842       * @param {Boolean} [asStatement]
  8843       * @return {*}
  8844       */
  8845  
  8846      Vue.prototype.$get = function (exp, asStatement) {
  8847        var res = parseExpression(exp);
  8848        if (res) {
  8849          if (asStatement) {
  8850            var self = this;
  8851            return function statementHandler() {
  8852              self.$arguments = toArray(arguments);
  8853              var result = res.get.call(self, self);
  8854              self.$arguments = null;
  8855              return result;
  8856            };
  8857          } else {
  8858            try {
  8859              return res.get.call(this, this);
  8860            } catch (e) {}
  8861          }
  8862        }
  8863      };
  8864  
  8865      /**
  8866       * Set the value from an expression on this vm.
  8867       * The expression must be a valid left-hand
  8868       * expression in an assignment.
  8869       *
  8870       * @param {String} exp
  8871       * @param {*} val
  8872       */
  8873  
  8874      Vue.prototype.$set = function (exp, val) {
  8875        var res = parseExpression(exp, true);
  8876        if (res && res.set) {
  8877          res.set.call(this, this, val);
  8878        }
  8879      };
  8880  
  8881      /**
  8882       * Delete a property on the VM
  8883       *
  8884       * @param {String} key
  8885       */
  8886  
  8887      Vue.prototype.$delete = function (key) {
  8888        del(this._data, key);
  8889      };
  8890  
  8891      /**
  8892       * Watch an expression, trigger callback when its
  8893       * value changes.
  8894       *
  8895       * @param {String|Function} expOrFn
  8896       * @param {Function} cb
  8897       * @param {Object} [options]
  8898       *                 - {Boolean} deep
  8899       *                 - {Boolean} immediate
  8900       * @return {Function} - unwatchFn
  8901       */
  8902  
  8903      Vue.prototype.$watch = function (expOrFn, cb, options) {
  8904        var vm = this;
  8905        var parsed;
  8906        if (typeof expOrFn === 'string') {
  8907          parsed = parseDirective(expOrFn);
  8908          expOrFn = parsed.expression;
  8909        }
  8910        var watcher = new Watcher(vm, expOrFn, cb, {
  8911          deep: options && options.deep,
  8912          sync: options && options.sync,
  8913          filters: parsed && parsed.filters,
  8914          user: !options || options.user !== false
  8915        });
  8916        if (options && options.immediate) {
  8917          cb.call(vm, watcher.value);
  8918        }
  8919        return function unwatchFn() {
  8920          watcher.teardown();
  8921        };
  8922      };
  8923  
  8924      /**
  8925       * Evaluate a text directive, including filters.
  8926       *
  8927       * @param {String} text
  8928       * @param {Boolean} [asStatement]
  8929       * @return {String}
  8930       */
  8931  
  8932      Vue.prototype.$eval = function (text, asStatement) {
  8933        // check for filters.
  8934        if (filterRE$1.test(text)) {
  8935          var dir = parseDirective(text);
  8936          // the filter regex check might give false positive
  8937          // for pipes inside strings, so it's possible that
  8938          // we don't get any filters here
  8939          var val = this.$get(dir.expression, asStatement);
  8940          return dir.filters ? this._applyFilters(val, null, dir.filters) : val;
  8941        } else {
  8942          // no filter
  8943          return this.$get(text, asStatement);
  8944        }
  8945      };
  8946  
  8947      /**
  8948       * Interpolate a piece of template text.
  8949       *
  8950       * @param {String} text
  8951       * @return {String}
  8952       */
  8953  
  8954      Vue.prototype.$interpolate = function (text) {
  8955        var tokens = parseText(text);
  8956        var vm = this;
  8957        if (tokens) {
  8958          if (tokens.length === 1) {
  8959            return vm.$eval(tokens[0].value) + '';
  8960          } else {
  8961            return tokens.map(function (token) {
  8962              return token.tag ? vm.$eval(token.value) : token.value;
  8963            }).join('');
  8964          }
  8965        } else {
  8966          return text;
  8967        }
  8968      };
  8969  
  8970      /**
  8971       * Log instance data as a plain JS object
  8972       * so that it is easier to inspect in console.
  8973       * This method assumes console is available.
  8974       *
  8975       * @param {String} [path]
  8976       */
  8977  
  8978      Vue.prototype.$log = function (path) {
  8979        var data = path ? getPath(this._data, path) : this._data;
  8980        if (data) {
  8981          data = clean(data);
  8982        }
  8983        // include computed fields
  8984        if (!path) {
  8985          var key;
  8986          for (key in this.$options.computed) {
  8987            data[key] = clean(this[key]);
  8988          }
  8989          if (this._props) {
  8990            for (key in this._props) {
  8991              data[key] = clean(this[key]);
  8992            }
  8993          }
  8994        }
  8995        console.log(data);
  8996      };
  8997  
  8998      /**
  8999       * "clean" a getter/setter converted object into a plain
  9000       * object copy.
  9001       *
  9002       * @param {Object} - obj
  9003       * @return {Object}
  9004       */
  9005  
  9006      function clean(obj) {
  9007        return JSON.parse(JSON.stringify(obj));
  9008      }
  9009    }
  9010  
  9011    function domAPI (Vue) {
  9012      /**
  9013       * Convenience on-instance nextTick. The callback is
  9014       * auto-bound to the instance, and this avoids component
  9015       * modules having to rely on the global Vue.
  9016       *
  9017       * @param {Function} fn
  9018       */
  9019  
  9020      Vue.prototype.$nextTick = function (fn) {
  9021        nextTick(fn, this);
  9022      };
  9023  
  9024      /**
  9025       * Append instance to target
  9026       *
  9027       * @param {Node} target
  9028       * @param {Function} [cb]
  9029       * @param {Boolean} [withTransition] - defaults to true
  9030       */
  9031  
  9032      Vue.prototype.$appendTo = function (target, cb, withTransition) {
  9033        return insert(this, target, cb, withTransition, append, appendWithTransition);
  9034      };
  9035  
  9036      /**
  9037       * Prepend instance to target
  9038       *
  9039       * @param {Node} target
  9040       * @param {Function} [cb]
  9041       * @param {Boolean} [withTransition] - defaults to true
  9042       */
  9043  
  9044      Vue.prototype.$prependTo = function (target, cb, withTransition) {
  9045        target = query(target);
  9046        if (target.hasChildNodes()) {
  9047          this.$before(target.firstChild, cb, withTransition);
  9048        } else {
  9049          this.$appendTo(target, cb, withTransition);
  9050        }
  9051        return this;
  9052      };
  9053  
  9054      /**
  9055       * Insert instance before target
  9056       *
  9057       * @param {Node} target
  9058       * @param {Function} [cb]
  9059       * @param {Boolean} [withTransition] - defaults to true
  9060       */
  9061  
  9062      Vue.prototype.$before = function (target, cb, withTransition) {
  9063        return insert(this, target, cb, withTransition, beforeWithCb, beforeWithTransition);
  9064      };
  9065  
  9066      /**
  9067       * Insert instance after target
  9068       *
  9069       * @param {Node} target
  9070       * @param {Function} [cb]
  9071       * @param {Boolean} [withTransition] - defaults to true
  9072       */
  9073  
  9074      Vue.prototype.$after = function (target, cb, withTransition) {
  9075        target = query(target);
  9076        if (target.nextSibling) {
  9077          this.$before(target.nextSibling, cb, withTransition);
  9078        } else {
  9079          this.$appendTo(target.parentNode, cb, withTransition);
  9080        }
  9081        return this;
  9082      };
  9083  
  9084      /**
  9085       * Remove instance from DOM
  9086       *
  9087       * @param {Function} [cb]
  9088       * @param {Boolean} [withTransition] - defaults to true
  9089       */
  9090  
  9091      Vue.prototype.$remove = function (cb, withTransition) {
  9092        if (!this.$el.parentNode) {
  9093          return cb && cb();
  9094        }
  9095        var inDocument = this._isAttached && inDoc(this.$el);
  9096        // if we are not in document, no need to check
  9097        // for transitions
  9098        if (!inDocument) withTransition = false;
  9099        var self = this;
  9100        var realCb = function realCb() {
  9101          if (inDocument) self._callHook('detached');
  9102          if (cb) cb();
  9103        };
  9104        if (this._isFragment) {
  9105          removeNodeRange(this._fragmentStart, this._fragmentEnd, this, this._fragment, realCb);
  9106        } else {
  9107          var op = withTransition === false ? removeWithCb : removeWithTransition;
  9108          op(this.$el, this, realCb);
  9109        }
  9110        return this;
  9111      };
  9112  
  9113      /**
  9114       * Shared DOM insertion function.
  9115       *
  9116       * @param {Vue} vm
  9117       * @param {Element} target
  9118       * @param {Function} [cb]
  9119       * @param {Boolean} [withTransition]
  9120       * @param {Function} op1 - op for non-transition insert
  9121       * @param {Function} op2 - op for transition insert
  9122       * @return vm
  9123       */
  9124  
  9125      function insert(vm, target, cb, withTransition, op1, op2) {
  9126        target = query(target);
  9127        var targetIsDetached = !inDoc(target);
  9128        var op = withTransition === false || targetIsDetached ? op1 : op2;
  9129        var shouldCallHook = !targetIsDetached && !vm._isAttached && !inDoc(vm.$el);
  9130        if (vm._isFragment) {
  9131          mapNodeRange(vm._fragmentStart, vm._fragmentEnd, function (node) {
  9132            op(node, target, vm);
  9133          });
  9134          cb && cb();
  9135        } else {
  9136          op(vm.$el, target, vm, cb);
  9137        }
  9138        if (shouldCallHook) {
  9139          vm._callHook('attached');
  9140        }
  9141        return vm;
  9142      }
  9143  
  9144      /**
  9145       * Check for selectors
  9146       *
  9147       * @param {String|Element} el
  9148       */
  9149  
  9150      function query(el) {
  9151        return typeof el === 'string' ? document.querySelector(el) : el;
  9152      }
  9153  
  9154      /**
  9155       * Append operation that takes a callback.
  9156       *
  9157       * @param {Node} el
  9158       * @param {Node} target
  9159       * @param {Vue} vm - unused
  9160       * @param {Function} [cb]
  9161       */
  9162  
  9163      function append(el, target, vm, cb) {
  9164        target.appendChild(el);
  9165        if (cb) cb();
  9166      }
  9167  
  9168      /**
  9169       * InsertBefore operation that takes a callback.
  9170       *
  9171       * @param {Node} el
  9172       * @param {Node} target
  9173       * @param {Vue} vm - unused
  9174       * @param {Function} [cb]
  9175       */
  9176  
  9177      function beforeWithCb(el, target, vm, cb) {
  9178        before(el, target);
  9179        if (cb) cb();
  9180      }
  9181  
  9182      /**
  9183       * Remove operation that takes a callback.
  9184       *
  9185       * @param {Node} el
  9186       * @param {Vue} vm - unused
  9187       * @param {Function} [cb]
  9188       */
  9189  
  9190      function removeWithCb(el, vm, cb) {
  9191        remove(el);
  9192        if (cb) cb();
  9193      }
  9194    }
  9195  
  9196    function eventsAPI (Vue) {
  9197      /**
  9198       * Listen on the given `event` with `fn`.
  9199       *
  9200       * @param {String} event
  9201       * @param {Function} fn
  9202       */
  9203  
  9204      Vue.prototype.$on = function (event, fn) {
  9205        (this._events[event] || (this._events[event] = [])).push(fn);
  9206        modifyListenerCount(this, event, 1);
  9207        return this;
  9208      };
  9209  
  9210      /**
  9211       * Adds an `event` listener that will be invoked a single
  9212       * time then automatically removed.
  9213       *
  9214       * @param {String} event
  9215       * @param {Function} fn
  9216       */
  9217  
  9218      Vue.prototype.$once = function (event, fn) {
  9219        var self = this;
  9220        function on() {
  9221          self.$off(event, on);
  9222          fn.apply(this, arguments);
  9223        }
  9224        on.fn = fn;
  9225        this.$on(event, on);
  9226        return this;
  9227      };
  9228  
  9229      /**
  9230       * Remove the given callback for `event` or all
  9231       * registered callbacks.
  9232       *
  9233       * @param {String} event
  9234       * @param {Function} fn
  9235       */
  9236  
  9237      Vue.prototype.$off = function (event, fn) {
  9238        var cbs;
  9239        // all
  9240        if (!arguments.length) {
  9241          if (this.$parent) {
  9242            for (event in this._events) {
  9243              cbs = this._events[event];
  9244              if (cbs) {
  9245                modifyListenerCount(this, event, -cbs.length);
  9246              }
  9247            }
  9248          }
  9249          this._events = {};
  9250          return this;
  9251        }
  9252        // specific event
  9253        cbs = this._events[event];
  9254        if (!cbs) {
  9255          return this;
  9256        }
  9257        if (arguments.length === 1) {
  9258          modifyListenerCount(this, event, -cbs.length);
  9259          this._events[event] = null;
  9260          return this;
  9261        }
  9262        // specific handler
  9263        var cb;
  9264        var i = cbs.length;
  9265        while (i--) {
  9266          cb = cbs[i];
  9267          if (cb === fn || cb.fn === fn) {
  9268            modifyListenerCount(this, event, -1);
  9269            cbs.splice(i, 1);
  9270            break;
  9271          }
  9272        }
  9273        return this;
  9274      };
  9275  
  9276      /**
  9277       * Trigger an event on self.
  9278       *
  9279       * @param {String|Object} event
  9280       * @return {Boolean} shouldPropagate
  9281       */
  9282  
  9283      Vue.prototype.$emit = function (event) {
  9284        var isSource = typeof event === 'string';
  9285        event = isSource ? event : event.name;
  9286        var cbs = this._events[event];
  9287        var shouldPropagate = isSource || !cbs;
  9288        if (cbs) {
  9289          cbs = cbs.length > 1 ? toArray(cbs) : cbs;
  9290          // this is a somewhat hacky solution to the question raised
  9291          // in #2102: for an inline component listener like <comp @test="doThis">,
  9292          // the propagation handling is somewhat broken. Therefore we
  9293          // need to treat these inline callbacks differently.
  9294          var hasParentCbs = isSource && cbs.some(function (cb) {
  9295            return cb._fromParent;
  9296          });
  9297          if (hasParentCbs) {
  9298            shouldPropagate = false;
  9299          }
  9300          var args = toArray(arguments, 1);
  9301          for (var i = 0, l = cbs.length; i < l; i++) {
  9302            var cb = cbs[i];
  9303            var res = cb.apply(this, args);
  9304            if (res === true && (!hasParentCbs || cb._fromParent)) {
  9305              shouldPropagate = true;
  9306            }
  9307          }
  9308        }
  9309        return shouldPropagate;
  9310      };
  9311  
  9312      /**
  9313       * Recursively broadcast an event to all children instances.
  9314       *
  9315       * @param {String|Object} event
  9316       * @param {...*} additional arguments
  9317       */
  9318  
  9319      Vue.prototype.$broadcast = function (event) {
  9320        var isSource = typeof event === 'string';
  9321        event = isSource ? event : event.name;
  9322        // if no child has registered for this event,
  9323        // then there's no need to broadcast.
  9324        if (!this._eventsCount[event]) return;
  9325        var children = this.$children;
  9326        var args = toArray(arguments);
  9327        if (isSource) {
  9328          // use object event to indicate non-source emit
  9329          // on children
  9330          args[0] = { name: event, source: this };
  9331        }
  9332        for (var i = 0, l = children.length; i < l; i++) {
  9333          var child = children[i];
  9334          var shouldPropagate = child.$emit.apply(child, args);
  9335          if (shouldPropagate) {
  9336            child.$broadcast.apply(child, args);
  9337          }
  9338        }
  9339        return this;
  9340      };
  9341  
  9342      /**
  9343       * Recursively propagate an event up the parent chain.
  9344       *
  9345       * @param {String} event
  9346       * @param {...*} additional arguments
  9347       */
  9348  
  9349      Vue.prototype.$dispatch = function (event) {
  9350        var shouldPropagate = this.$emit.apply(this, arguments);
  9351        if (!shouldPropagate) return;
  9352        var parent = this.$parent;
  9353        var args = toArray(arguments);
  9354        // use object event to indicate non-source emit
  9355        // on parents
  9356        args[0] = { name: event, source: this };
  9357        while (parent) {
  9358          shouldPropagate = parent.$emit.apply(parent, args);
  9359          parent = shouldPropagate ? parent.$parent : null;
  9360        }
  9361        return this;
  9362      };
  9363  
  9364      /**
  9365       * Modify the listener counts on all parents.
  9366       * This bookkeeping allows $broadcast to return early when
  9367       * no child has listened to a certain event.
  9368       *
  9369       * @param {Vue} vm
  9370       * @param {String} event
  9371       * @param {Number} count
  9372       */
  9373  
  9374      var hookRE = /^hook:/;
  9375      function modifyListenerCount(vm, event, count) {
  9376        var parent = vm.$parent;
  9377        // hooks do not get broadcasted so no need
  9378        // to do bookkeeping for them
  9379        if (!parent || !count || hookRE.test(event)) return;
  9380        while (parent) {
  9381          parent._eventsCount[event] = (parent._eventsCount[event] || 0) + count;
  9382          parent = parent.$parent;
  9383        }
  9384      }
  9385    }
  9386  
  9387    function lifecycleAPI (Vue) {
  9388      /**
  9389       * Set instance target element and kick off the compilation
  9390       * process. The passed in `el` can be a selector string, an
  9391       * existing Element, or a DocumentFragment (for block
  9392       * instances).
  9393       *
  9394       * @param {Element|DocumentFragment|string} el
  9395       * @public
  9396       */
  9397  
  9398      Vue.prototype.$mount = function (el) {
  9399        if (this._isCompiled) {
  9400          'development' !== 'production' && warn('$mount() should be called only once.', this);
  9401          return;
  9402        }
  9403        el = query(el);
  9404        if (!el) {
  9405          el = document.createElement('div');
  9406        }
  9407        this._compile(el);
  9408        this._initDOMHooks();
  9409        if (inDoc(this.$el)) {
  9410          this._callHook('attached');
  9411          ready.call(this);
  9412        } else {
  9413          this.$once('hook:attached', ready);
  9414        }
  9415        return this;
  9416      };
  9417  
  9418      /**
  9419       * Mark an instance as ready.
  9420       */
  9421  
  9422      function ready() {
  9423        this._isAttached = true;
  9424        this._isReady = true;
  9425        this._callHook('ready');
  9426      }
  9427  
  9428      /**
  9429       * Teardown the instance, simply delegate to the internal
  9430       * _destroy.
  9431       *
  9432       * @param {Boolean} remove
  9433       * @param {Boolean} deferCleanup
  9434       */
  9435  
  9436      Vue.prototype.$destroy = function (remove, deferCleanup) {
  9437        this._destroy(remove, deferCleanup);
  9438      };
  9439  
  9440      /**
  9441       * Partially compile a piece of DOM and return a
  9442       * decompile function.
  9443       *
  9444       * @param {Element|DocumentFragment} el
  9445       * @param {Vue} [host]
  9446       * @param {Object} [scope]
  9447       * @param {Fragment} [frag]
  9448       * @return {Function}
  9449       */
  9450  
  9451      Vue.prototype.$compile = function (el, host, scope, frag) {
  9452        return compile(el, this.$options, true)(this, el, host, scope, frag);
  9453      };
  9454    }
  9455  
  9456    /**
  9457     * The exposed Vue constructor.
  9458     *
  9459     * API conventions:
  9460     * - public API methods/properties are prefixed with `$`
  9461     * - internal methods/properties are prefixed with `_`
  9462     * - non-prefixed properties are assumed to be proxied user
  9463     *   data.
  9464     *
  9465     * @constructor
  9466     * @param {Object} [options]
  9467     * @public
  9468     */
  9469  
  9470    function Vue(options) {
  9471      this._init(options);
  9472    }
  9473  
  9474    // install internals
  9475    initMixin(Vue);
  9476    stateMixin(Vue);
  9477    eventsMixin(Vue);
  9478    lifecycleMixin(Vue);
  9479    miscMixin(Vue);
  9480  
  9481    // install instance APIs
  9482    dataAPI(Vue);
  9483    domAPI(Vue);
  9484    eventsAPI(Vue);
  9485    lifecycleAPI(Vue);
  9486  
  9487    var slot = {
  9488  
  9489      priority: SLOT,
  9490      params: ['name'],
  9491  
  9492      bind: function bind() {
  9493        // this was resolved during component transclusion
  9494        var name = this.params.name || 'default';
  9495        var content = this.vm._slotContents && this.vm._slotContents[name];
  9496        if (!content || !content.hasChildNodes()) {
  9497          this.fallback();
  9498        } else {
  9499          this.compile(content.cloneNode(true), this.vm._context, this.vm);
  9500        }
  9501      },
  9502  
  9503      compile: function compile(content, context, host) {
  9504        if (content && context) {
  9505          if (this.el.hasChildNodes() && content.childNodes.length === 1 && content.childNodes[0].nodeType === 1 && content.childNodes[0].hasAttribute('v-if')) {
  9506            // if the inserted slot has v-if
  9507            // inject fallback content as the v-else
  9508            var elseBlock = document.createElement('template');
  9509            elseBlock.setAttribute('v-else', '');
  9510            elseBlock.innerHTML = this.el.innerHTML;
  9511            // the else block should be compiled in child scope
  9512            elseBlock._context = this.vm;
  9513            content.appendChild(elseBlock);
  9514          }
  9515          var scope = host ? host._scope : this._scope;
  9516          this.unlink = context.$compile(content, host, scope, this._frag);
  9517        }
  9518        if (content) {
  9519          replace(this.el, content);
  9520        } else {
  9521          remove(this.el);
  9522        }
  9523      },
  9524  
  9525      fallback: function fallback() {
  9526        this.compile(extractContent(this.el, true), this.vm);
  9527      },
  9528  
  9529      unbind: function unbind() {
  9530        if (this.unlink) {
  9531          this.unlink();
  9532        }
  9533      }
  9534    };
  9535  
  9536    var partial = {
  9537  
  9538      priority: PARTIAL,
  9539  
  9540      params: ['name'],
  9541  
  9542      // watch changes to name for dynamic partials
  9543      paramWatchers: {
  9544        name: function name(value) {
  9545          vIf.remove.call(this);
  9546          if (value) {
  9547            this.insert(value);
  9548          }
  9549        }
  9550      },
  9551  
  9552      bind: function bind() {
  9553        this.anchor = createAnchor('v-partial');
  9554        replace(this.el, this.anchor);
  9555        this.insert(this.params.name);
  9556      },
  9557  
  9558      insert: function insert(id) {
  9559        var partial = resolveAsset(this.vm.$options, 'partials', id, true);
  9560        if (partial) {
  9561          this.factory = new FragmentFactory(this.vm, partial);
  9562          vIf.insert.call(this);
  9563        }
  9564      },
  9565  
  9566      unbind: function unbind() {
  9567        if (this.frag) {
  9568          this.frag.destroy();
  9569        }
  9570      }
  9571    };
  9572  
  9573    var elementDirectives = {
  9574      slot: slot,
  9575      partial: partial
  9576    };
  9577  
  9578    var convertArray = vFor._postProcess;
  9579  
  9580    /**
  9581     * Limit filter for arrays
  9582     *
  9583     * @param {Number} n
  9584     * @param {Number} offset (Decimal expected)
  9585     */
  9586  
  9587    function limitBy(arr, n, offset) {
  9588      offset = offset ? parseInt(offset, 10) : 0;
  9589      n = toNumber(n);
  9590      return typeof n === 'number' ? arr.slice(offset, offset + n) : arr;
  9591    }
  9592  
  9593    /**
  9594     * Filter filter for arrays
  9595     *
  9596     * @param {String} search
  9597     * @param {String} [delimiter]
  9598     * @param {String} ...dataKeys
  9599     */
  9600  
  9601    function filterBy(arr, search, delimiter) {
  9602      arr = convertArray(arr);
  9603      if (search == null) {
  9604        return arr;
  9605      }
  9606      if (typeof search === 'function') {
  9607        return arr.filter(search);
  9608      }
  9609      // cast to lowercase string
  9610      search = ('' + search).toLowerCase();
  9611      // allow optional `in` delimiter
  9612      // because why not
  9613      var n = delimiter === 'in' ? 3 : 2;
  9614      // extract and flatten keys
  9615      var keys = Array.prototype.concat.apply([], toArray(arguments, n));
  9616      var res = [];
  9617      var item, key, val, j;
  9618      for (var i = 0, l = arr.length; i < l; i++) {
  9619        item = arr[i];
  9620        val = item && item.$value || item;
  9621        j = keys.length;
  9622        if (j) {
  9623          while (j--) {
  9624            key = keys[j];
  9625            if (key === '$key' && contains(item.$key, search) || contains(getPath(val, key), search)) {
  9626              res.push(item);
  9627              break;
  9628            }
  9629          }
  9630        } else if (contains(item, search)) {
  9631          res.push(item);
  9632        }
  9633      }
  9634      return res;
  9635    }
  9636  
  9637    /**
  9638     * Filter filter for arrays
  9639     *
  9640     * @param {String|Array<String>|Function} ...sortKeys
  9641     * @param {Number} [order]
  9642     */
  9643  
  9644    function orderBy(arr) {
  9645      var comparator = null;
  9646      var sortKeys = undefined;
  9647      arr = convertArray(arr);
  9648  
  9649      // determine order (last argument)
  9650      var args = toArray(arguments, 1);
  9651      var order = args[args.length - 1];
  9652      if (typeof order === 'number') {
  9653        order = order < 0 ? -1 : 1;
  9654        args = args.length > 1 ? args.slice(0, -1) : args;
  9655      } else {
  9656        order = 1;
  9657      }
  9658  
  9659      // determine sortKeys & comparator
  9660      var firstArg = args[0];
  9661      if (!firstArg) {
  9662        return arr;
  9663      } else if (typeof firstArg === 'function') {
  9664        // custom comparator
  9665        comparator = function (a, b) {
  9666          return firstArg(a, b) * order;
  9667        };
  9668      } else {
  9669        // string keys. flatten first
  9670        sortKeys = Array.prototype.concat.apply([], args);
  9671        comparator = function (a, b, i) {
  9672          i = i || 0;
  9673          return i >= sortKeys.length - 1 ? baseCompare(a, b, i) : baseCompare(a, b, i) || comparator(a, b, i + 1);
  9674        };
  9675      }
  9676  
  9677      function baseCompare(a, b, sortKeyIndex) {
  9678        var sortKey = sortKeys[sortKeyIndex];
  9679        if (sortKey) {
  9680          if (sortKey !== '$key') {
  9681            if (isObject(a) && '$value' in a) a = a.$value;
  9682            if (isObject(b) && '$value' in b) b = b.$value;
  9683          }
  9684          a = isObject(a) ? getPath(a, sortKey) : a;
  9685          b = isObject(b) ? getPath(b, sortKey) : b;
  9686        }
  9687        return a === b ? 0 : a > b ? order : -order;
  9688      }
  9689  
  9690      // sort on a copy to avoid mutating original array
  9691      return arr.slice().sort(comparator);
  9692    }
  9693  
  9694    /**
  9695     * String contain helper
  9696     *
  9697     * @param {*} val
  9698     * @param {String} search
  9699     */
  9700  
  9701    function contains(val, search) {
  9702      var i;
  9703      if (isPlainObject(val)) {
  9704        var keys = Object.keys(val);
  9705        i = keys.length;
  9706        while (i--) {
  9707          if (contains(val[keys[i]], search)) {
  9708            return true;
  9709          }
  9710        }
  9711      } else if (isArray(val)) {
  9712        i = val.length;
  9713        while (i--) {
  9714          if (contains(val[i], search)) {
  9715            return true;
  9716          }
  9717        }
  9718      } else if (val != null) {
  9719        return val.toString().toLowerCase().indexOf(search) > -1;
  9720      }
  9721    }
  9722  
  9723    var digitsRE = /(\d{3})(?=\d)/g;
  9724  
  9725    // asset collections must be a plain object.
  9726    var filters = {
  9727  
  9728      orderBy: orderBy,
  9729      filterBy: filterBy,
  9730      limitBy: limitBy,
  9731  
  9732      /**
  9733       * Stringify value.
  9734       *
  9735       * @param {Number} indent
  9736       */
  9737  
  9738      json: {
  9739        read: function read(value, indent) {
  9740          return typeof value === 'string' ? value : JSON.stringify(value, null, Number(indent) || 2);
  9741        },
  9742        write: function write(value) {
  9743          try {
  9744            return JSON.parse(value);
  9745          } catch (e) {
  9746            return value;
  9747          }
  9748        }
  9749      },
  9750  
  9751      /**
  9752       * 'abc' => 'Abc'
  9753       */
  9754  
  9755      capitalize: function capitalize(value) {
  9756        if (!value && value !== 0) return '';
  9757        value = value.toString();
  9758        return value.charAt(0).toUpperCase() + value.slice(1);
  9759      },
  9760  
  9761      /**
  9762       * 'abc' => 'ABC'
  9763       */
  9764  
  9765      uppercase: function uppercase(value) {
  9766        return value || value === 0 ? value.toString().toUpperCase() : '';
  9767      },
  9768  
  9769      /**
  9770       * 'AbC' => 'abc'
  9771       */
  9772  
  9773      lowercase: function lowercase(value) {
  9774        return value || value === 0 ? value.toString().toLowerCase() : '';
  9775      },
  9776  
  9777      /**
  9778       * 12345 => $12,345.00
  9779       *
  9780       * @param {String} sign
  9781       * @param {Number} decimals Decimal places
  9782       */
  9783  
  9784      currency: function currency(value, _currency, decimals) {
  9785        value = parseFloat(value);
  9786        if (!isFinite(value) || !value && value !== 0) return '';
  9787        _currency = _currency != null ? _currency : '$';
  9788        decimals = decimals != null ? decimals : 2;
  9789        var stringified = Math.abs(value).toFixed(decimals);
  9790        var _int = decimals ? stringified.slice(0, -1 - decimals) : stringified;
  9791        var i = _int.length % 3;
  9792        var head = i > 0 ? _int.slice(0, i) + (_int.length > 3 ? ',' : '') : '';
  9793        var _float = decimals ? stringified.slice(-1 - decimals) : '';
  9794        var sign = value < 0 ? '-' : '';
  9795        return sign + _currency + head + _int.slice(i).replace(digitsRE, '$1,') + _float;
  9796      },
  9797  
  9798      /**
  9799       * 'item' => 'items'
  9800       *
  9801       * @params
  9802       *  an array of strings corresponding to
  9803       *  the single, double, triple ... forms of the word to
  9804       *  be pluralized. When the number to be pluralized
  9805       *  exceeds the length of the args, it will use the last
  9806       *  entry in the array.
  9807       *
  9808       *  e.g. ['single', 'double', 'triple', 'multiple']
  9809       */
  9810  
  9811      pluralize: function pluralize(value) {
  9812        var args = toArray(arguments, 1);
  9813        return args.length > 1 ? args[value % 10 - 1] || args[args.length - 1] : args[0] + (value === 1 ? '' : 's');
  9814      },
  9815  
  9816      /**
  9817       * Debounce a handler function.
  9818       *
  9819       * @param {Function} handler
  9820       * @param {Number} delay = 300
  9821       * @return {Function}
  9822       */
  9823  
  9824      debounce: function debounce(handler, delay) {
  9825        if (!handler) return;
  9826        if (!delay) {
  9827          delay = 300;
  9828        }
  9829        return _debounce(handler, delay);
  9830      }
  9831    };
  9832  
  9833    function installGlobalAPI (Vue) {
  9834      /**
  9835       * Vue and every constructor that extends Vue has an
  9836       * associated options object, which can be accessed during
  9837       * compilation steps as `this.constructor.options`.
  9838       *
  9839       * These can be seen as the default options of every
  9840       * Vue instance.
  9841       */
  9842  
  9843      Vue.options = {
  9844        directives: directives,
  9845        elementDirectives: elementDirectives,
  9846        filters: filters,
  9847        transitions: {},
  9848        components: {},
  9849        partials: {},
  9850        replace: true
  9851      };
  9852  
  9853      /**
  9854       * Expose useful internals
  9855       */
  9856  
  9857      Vue.util = util;
  9858      Vue.config = config;
  9859      Vue.set = set;
  9860      Vue['delete'] = del;
  9861      Vue.nextTick = nextTick;
  9862  
  9863      /**
  9864       * The following are exposed for advanced usage / plugins
  9865       */
  9866  
  9867      Vue.compiler = compiler;
  9868      Vue.FragmentFactory = FragmentFactory;
  9869      Vue.internalDirectives = internalDirectives;
  9870      Vue.parsers = {
  9871        path: path,
  9872        text: text,
  9873        template: template,
  9874        directive: directive,
  9875        expression: expression
  9876      };
  9877  
  9878      /**
  9879       * Each instance constructor, including Vue, has a unique
  9880       * cid. This enables us to create wrapped "child
  9881       * constructors" for prototypal inheritance and cache them.
  9882       */
  9883  
  9884      Vue.cid = 0;
  9885      var cid = 1;
  9886  
  9887      /**
  9888       * Class inheritance
  9889       *
  9890       * @param {Object} extendOptions
  9891       */
  9892  
  9893      Vue.extend = function (extendOptions) {
  9894        extendOptions = extendOptions || {};
  9895        var Super = this;
  9896        var isFirstExtend = Super.cid === 0;
  9897        if (isFirstExtend && extendOptions._Ctor) {
  9898          return extendOptions._Ctor;
  9899        }
  9900        var name = extendOptions.name || Super.options.name;
  9901        if ('development' !== 'production') {
  9902          if (!/^[a-zA-Z][\w-]*$/.test(name)) {
  9903            warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
  9904            name = null;
  9905          }
  9906        }
  9907        var Sub = createClass(name || 'VueComponent');
  9908        Sub.prototype = Object.create(Super.prototype);
  9909        Sub.prototype.constructor = Sub;
  9910        Sub.cid = cid++;
  9911        Sub.options = mergeOptions(Super.options, extendOptions);
  9912        Sub['super'] = Super;
  9913        // allow further extension
  9914        Sub.extend = Super.extend;
  9915        // create asset registers, so extended classes
  9916        // can have their private assets too.
  9917        config._assetTypes.forEach(function (type) {
  9918          Sub[type] = Super[type];
  9919        });
  9920        // enable recursive self-lookup
  9921        if (name) {
  9922          Sub.options.components[name] = Sub;
  9923        }
  9924        // cache constructor
  9925        if (isFirstExtend) {
  9926          extendOptions._Ctor = Sub;
  9927        }
  9928        return Sub;
  9929      };
  9930  
  9931      /**
  9932       * A function that returns a sub-class constructor with the
  9933       * given name. This gives us much nicer output when
  9934       * logging instances in the console.
  9935       *
  9936       * @param {String} name
  9937       * @return {Function}
  9938       */
  9939  
  9940      function createClass(name) {
  9941        /* eslint-disable no-new-func */
  9942        return new Function('return function ' + classify(name) + ' (options) { this._init(options) }')();
  9943        /* eslint-enable no-new-func */
  9944      }
  9945  
  9946      /**
  9947       * Plugin system
  9948       *
  9949       * @param {Object} plugin
  9950       */
  9951  
  9952      Vue.use = function (plugin) {
  9953        /* istanbul ignore if */
  9954        if (plugin.installed) {
  9955          return;
  9956        }
  9957        // additional parameters
  9958        var args = toArray(arguments, 1);
  9959        args.unshift(this);
  9960        if (typeof plugin.install === 'function') {
  9961          plugin.install.apply(plugin, args);
  9962        } else {
  9963          plugin.apply(null, args);
  9964        }
  9965        plugin.installed = true;
  9966        return this;
  9967      };
  9968  
  9969      /**
  9970       * Apply a global mixin by merging it into the default
  9971       * options.
  9972       */
  9973  
  9974      Vue.mixin = function (mixin) {
  9975        Vue.options = mergeOptions(Vue.options, mixin);
  9976      };
  9977  
  9978      /**
  9979       * Create asset registration methods with the following
  9980       * signature:
  9981       *
  9982       * @param {String} id
  9983       * @param {*} definition
  9984       */
  9985  
  9986      config._assetTypes.forEach(function (type) {
  9987        Vue[type] = function (id, definition) {
  9988          if (!definition) {
  9989            return this.options[type + 's'][id];
  9990          } else {
  9991            /* istanbul ignore if */
  9992            if ('development' !== 'production') {
  9993              if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {
  9994                warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
  9995              }
  9996            }
  9997            if (type === 'component' && isPlainObject(definition)) {
  9998              definition.name = id;
  9999              definition = Vue.extend(definition);
 10000            }
 10001            this.options[type + 's'][id] = definition;
 10002            return definition;
 10003          }
 10004        };
 10005      });
 10006  
 10007      // expose internal transition API
 10008      extend(Vue.transition, transition);
 10009    }
 10010  
 10011    installGlobalAPI(Vue);
 10012  
 10013    Vue.version = '1.0.24';
 10014  
 10015    // devtools global hook
 10016    /* istanbul ignore next */
 10017    setTimeout(function () {
 10018      if (config.devtools) {
 10019        if (devtools) {
 10020          devtools.emit('init', Vue);
 10021        } else if ('development' !== 'production' && inBrowser && /Chrome\/\d+/.test(window.navigator.userAgent)) {
 10022          console.log('Download the Vue Devtools for a better development experience:\n' + 'https://github.com/vuejs/vue-devtools');
 10023        }
 10024      }
 10025    }, 0);
 10026  
 10027    return Vue;
 10028  
 10029  }));