vue-datatable
Version:
Datatable for Vuejs
853 lines (819 loc) • 476 kB
JavaScript
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _vue = __webpack_require__(1);
var _vue2 = _interopRequireDefault(_vue);
var _vueDatatable = __webpack_require__(52);
var _vueDatatable2 = _interopRequireDefault(_vueDatatable);
var _chance = __webpack_require__(47);
var _chance2 = _interopRequireDefault(_chance);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
(function () {
new _vue2.default({
el: 'body',
data: {
tableData: {
options: {
sortable: true,
editable: true,
pageCount: 10
},
columns: [{
value: 'id',
text: 'ID',
sortable: true,
editable: false
}, {
value: 'name',
text: 'Name',
sortable: true,
editable: true
}, {
value: 'age',
text: 'Age',
sortable: true,
editable: true
}, {
value: 'sex',
text: 'Sex',
sortable: true,
editable: true
}],
rows: [],
onPageChanged: function onPageChanged(page) {
console.log('Current page is ' + page);
}
}
},
ready: function ready() {
var chance = new _chance2.default();
var length = chance.integer({ min: 0, max: 1000 });
for (var i = 0; i < length; i++) {
var obj = {
id: {
value: i + 1
},
name: {
value: chance.name(),
editable: chance.bool()
},
age: {
value: chance.age(),
editable: chance.bool()
},
sex: {
value: chance.gender(),
editable: chance.bool
}
};
this.tableData.rows.push(obj);
}
},
components: {
DataTable: _vueDatatable2.default
}
});
})();
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global, process) {/*!
* Vue.js v1.0.26
* (c) 2016 Evan You
* Released under the MIT License.
*/'use strict';var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj;}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol?"symbol":typeof obj;};function set(obj,key,val){if(hasOwn(obj,key)){obj[key]=val;return;}if(obj._isVue){set(obj._data,key,val);return;}var ob=obj.__ob__;if(!ob){obj[key]=val;return;}ob.convert(key,val);ob.dep.notify();if(ob.vms){var i=ob.vms.length;while(i--){var vm=ob.vms[i];vm._proxy(key);vm._digest();}}return val;}/**
* Delete a property and trigger change if necessary.
*
* @param {Object} obj
* @param {String} key
*/function del(obj,key){if(!hasOwn(obj,key)){return;}delete obj[key];var ob=obj.__ob__;if(!ob){if(obj._isVue){delete obj._data[key];obj._digest();}return;}ob.dep.notify();if(ob.vms){var i=ob.vms.length;while(i--){var vm=ob.vms[i];vm._unproxy(key);vm._digest();}}}var hasOwnProperty=Object.prototype.hasOwnProperty;/**
* Check whether the object has the property.
*
* @param {Object} obj
* @param {String} key
* @return {Boolean}
*/function hasOwn(obj,key){return hasOwnProperty.call(obj,key);}/**
* Check if an expression is a literal value.
*
* @param {String} exp
* @return {Boolean}
*/var literalValueRE=/^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;function isLiteral(exp){return literalValueRE.test(exp);}/**
* Check if a string starts with $ or _
*
* @param {String} str
* @return {Boolean}
*/function isReserved(str){var c=(str+'').charCodeAt(0);return c===0x24||c===0x5F;}/**
* Guard text output, make sure undefined outputs
* empty string
*
* @param {*} value
* @return {String}
*/function _toString(value){return value==null?'':value.toString();}/**
* Check and convert possible numeric strings to numbers
* before setting back to data
*
* @param {*} value
* @return {*|Number}
*/function toNumber(value){if(typeof value!=='string'){return value;}else{var parsed=Number(value);return isNaN(parsed)?value:parsed;}}/**
* Convert string boolean literals into real booleans.
*
* @param {*} value
* @return {*|Boolean}
*/function toBoolean(value){return value==='true'?true:value==='false'?false:value;}/**
* Strip quotes from a string
*
* @param {String} str
* @return {String | false}
*/function stripQuotes(str){var a=str.charCodeAt(0);var b=str.charCodeAt(str.length-1);return a===b&&(a===0x22||a===0x27)?str.slice(1,-1):str;}/**
* Camelize a hyphen-delmited string.
*
* @param {String} str
* @return {String}
*/var camelizeRE=/-(\w)/g;function camelize(str){return str.replace(camelizeRE,toUpper);}function toUpper(_,c){return c?c.toUpperCase():'';}/**
* Hyphenate a camelCase string.
*
* @param {String} str
* @return {String}
*/var hyphenateRE=/([a-z\d])([A-Z])/g;function hyphenate(str){return str.replace(hyphenateRE,'$1-$2').toLowerCase();}/**
* Converts hyphen/underscore/slash delimitered names into
* camelized classNames.
*
* e.g. my-component => MyComponent
* some_else => SomeElse
* some/comp => SomeComp
*
* @param {String} str
* @return {String}
*/var classifyRE=/(?:^|[-_\/])(\w)/g;function classify(str){return str.replace(classifyRE,toUpper);}/**
* Simple bind, faster than native
*
* @param {Function} fn
* @param {Object} ctx
* @return {Function}
*/function bind(fn,ctx){return function(a){var l=arguments.length;return l?l>1?fn.apply(ctx,arguments):fn.call(ctx,a):fn.call(ctx);};}/**
* Convert an Array-like object to a real Array.
*
* @param {Array-like} list
* @param {Number} [start] - start index
* @return {Array}
*/function toArray(list,start){start=start||0;var i=list.length-start;var ret=new Array(i);while(i--){ret[i]=list[i+start];}return ret;}/**
* Mix properties into target object.
*
* @param {Object} to
* @param {Object} from
*/function extend(to,from){var keys=Object.keys(from);var i=keys.length;while(i--){to[keys[i]]=from[keys[i]];}return to;}/**
* Quick object check - this is primarily used to tell
* Objects from primitive values when we know the value
* is a JSON-compliant type.
*
* @param {*} obj
* @return {Boolean}
*/function isObject(obj){return obj!==null&&(typeof obj==='undefined'?'undefined':_typeof(obj))==='object';}/**
* Strict object type check. Only returns true
* for plain JavaScript objects.
*
* @param {*} obj
* @return {Boolean}
*/var toString=Object.prototype.toString;var OBJECT_STRING='[object Object]';function isPlainObject(obj){return toString.call(obj)===OBJECT_STRING;}/**
* Array type check.
*
* @param {*} obj
* @return {Boolean}
*/var isArray=Array.isArray;/**
* Define a property.
*
* @param {Object} obj
* @param {String} key
* @param {*} val
* @param {Boolean} [enumerable]
*/function def(obj,key,val,enumerable){Object.defineProperty(obj,key,{value:val,enumerable:!!enumerable,writable:true,configurable:true});}/**
* Debounce a function so it only gets called after the
* input stops arriving after the given wait period.
*
* @param {Function} func
* @param {Number} wait
* @return {Function} - the debounced function
*/function _debounce(func,wait){var timeout,args,context,timestamp,result;var later=function later(){var last=Date.now()-timestamp;if(last<wait&&last>=0){timeout=setTimeout(later,wait-last);}else{timeout=null;result=func.apply(context,args);if(!timeout)context=args=null;}};return function(){context=this;args=arguments;timestamp=Date.now();if(!timeout){timeout=setTimeout(later,wait);}return result;};}/**
* Manual indexOf because it's slightly faster than
* native.
*
* @param {Array} arr
* @param {*} obj
*/function indexOf(arr,obj){var i=arr.length;while(i--){if(arr[i]===obj)return i;}return-1;}/**
* Make a cancellable version of an async callback.
*
* @param {Function} fn
* @return {Function}
*/function cancellable(fn){var cb=function cb(){if(!cb.cancelled){return fn.apply(this,arguments);}};cb.cancel=function(){cb.cancelled=true;};return cb;}/**
* Check if two values are loosely equal - that is,
* if they are plain objects, do they have the same shape?
*
* @param {*} a
* @param {*} b
* @return {Boolean}
*/function looseEqual(a,b){/* eslint-disable eqeqeq */return a==b||(isObject(a)&&isObject(b)?JSON.stringify(a)===JSON.stringify(b):false);/* eslint-enable eqeqeq */}var hasProto='__proto__'in{};// Browser environment sniffing
var inBrowser=typeof window!=='undefined'&&Object.prototype.toString.call(window)!=='[object Object]';// detect devtools
var devtools=inBrowser&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;// UA sniffing for working around browser-specific quirks
var UA=inBrowser&&window.navigator.userAgent.toLowerCase();var isIE=UA&&UA.indexOf('trident')>0;var isIE9=UA&&UA.indexOf('msie 9.0')>0;var isAndroid=UA&&UA.indexOf('android')>0;var isIos=UA&&/(iphone|ipad|ipod|ios)/i.test(UA);var iosVersionMatch=isIos&&UA.match(/os ([\d_]+)/);var iosVersion=iosVersionMatch&&iosVersionMatch[1].split('_');// detecting iOS UIWebView by indexedDB
var hasMutationObserverBug=iosVersion&&Number(iosVersion[0])>=9&&Number(iosVersion[1])>=3&&!window.indexedDB;var transitionProp=undefined;var transitionEndEvent=undefined;var animationProp=undefined;var animationEndEvent=undefined;// Transition property/event sniffing
if(inBrowser&&!isIE9){var isWebkitTrans=window.ontransitionend===undefined&&window.onwebkittransitionend!==undefined;var isWebkitAnim=window.onanimationend===undefined&&window.onwebkitanimationend!==undefined;transitionProp=isWebkitTrans?'WebkitTransition':'transition';transitionEndEvent=isWebkitTrans?'webkitTransitionEnd':'transitionend';animationProp=isWebkitAnim?'WebkitAnimation':'animation';animationEndEvent=isWebkitAnim?'webkitAnimationEnd':'animationend';}/**
* Defer a task to execute it asynchronously. Ideally this
* should be executed as a microtask, so we leverage
* MutationObserver if it's available, and fallback to
* setTimeout(0).
*
* @param {Function} cb
* @param {Object} ctx
*/var nextTick=function(){var callbacks=[];var pending=false;var timerFunc;function nextTickHandler(){pending=false;var copies=callbacks.slice(0);callbacks=[];for(var i=0;i<copies.length;i++){copies[i]();}}/* istanbul ignore if */if(typeof MutationObserver!=='undefined'&&!hasMutationObserverBug){var counter=1;var observer=new MutationObserver(nextTickHandler);var textNode=document.createTextNode(counter);observer.observe(textNode,{characterData:true});timerFunc=function timerFunc(){counter=(counter+1)%2;textNode.data=counter;};}else{// webpack attempts to inject a shim for setImmediate
// if it is used as a global, so we have to work around that to
// avoid bundling unnecessary code.
var context=inBrowser?window:typeof global!=='undefined'?global:{};timerFunc=context.setImmediate||setTimeout;}return function(cb,ctx){var func=ctx?function(){cb.call(ctx);}:cb;callbacks.push(func);if(pending)return;pending=true;timerFunc(nextTickHandler,0);};}();var _Set=undefined;/* istanbul ignore if */if(typeof Set!=='undefined'&&Set.toString().match(/native code/)){// use native Set when available.
_Set=Set;}else{// a non-standard Set polyfill that only works with primitive keys.
_Set=function _Set(){this.set=Object.create(null);};_Set.prototype.has=function(key){return this.set[key]!==undefined;};_Set.prototype.add=function(key){this.set[key]=1;};_Set.prototype.clear=function(){this.set=Object.create(null);};}function Cache(limit){this.size=0;this.limit=limit;this.head=this.tail=undefined;this._keymap=Object.create(null);}var p=Cache.prototype;/**
* Put <value> into the cache associated with <key>.
* Returns the entry which was removed to make room for
* the new entry. Otherwise undefined is returned.
* (i.e. if there was enough room already).
*
* @param {String} key
* @param {*} value
* @return {Entry|undefined}
*/p.put=function(key,value){var removed;var entry=this.get(key,true);if(!entry){if(this.size===this.limit){removed=this.shift();}entry={key:key};this._keymap[key]=entry;if(this.tail){this.tail.newer=entry;entry.older=this.tail;}else{this.head=entry;}this.tail=entry;this.size++;}entry.value=value;return removed;};/**
* Purge the least recently used (oldest) entry from the
* cache. Returns the removed entry or undefined if the
* cache was empty.
*/p.shift=function(){var entry=this.head;if(entry){this.head=this.head.newer;this.head.older=undefined;entry.newer=entry.older=undefined;this._keymap[entry.key]=undefined;this.size--;}return entry;};/**
* Get and register recent use of <key>. Returns the value
* associated with <key> or undefined if not in cache.
*
* @param {String} key
* @param {Boolean} returnEntry
* @return {Entry|*}
*/p.get=function(key,returnEntry){var entry=this._keymap[key];if(entry===undefined)return;if(entry===this.tail){return returnEntry?entry:entry.value;}// HEAD--------------TAIL
// <.older .newer>
// <--- add direction --
// A B C <D> E
if(entry.newer){if(entry===this.head){this.head=entry.newer;}entry.newer.older=entry.older;// C <-- E.
}if(entry.older){entry.older.newer=entry.newer;// C. --> E
}entry.newer=undefined;// D --x
entry.older=this.tail;// D. --> E
if(this.tail){this.tail.newer=entry;// E. <-- D
}this.tail=entry;return returnEntry?entry:entry.value;};var cache$1=new Cache(1000);var filterTokenRE=/[^\s'"]+|'[^']*'|"[^"]*"/g;var reservedArgRE=/^in$|^-?\d+/;/**
* Parser state
*/var str;var dir;var c;var prev;var i;var l;var lastFilterIndex;var inSingle;var inDouble;var curly;var square;var paren;/**
* Push a filter to the current directive object
*/function pushFilter(){var exp=str.slice(lastFilterIndex,i).trim();var filter;if(exp){filter={};var tokens=exp.match(filterTokenRE);filter.name=tokens[0];if(tokens.length>1){filter.args=tokens.slice(1).map(processFilterArg);}}if(filter){(dir.filters=dir.filters||[]).push(filter);}lastFilterIndex=i+1;}/**
* Check if an argument is dynamic and strip quotes.
*
* @param {String} arg
* @return {Object}
*/function processFilterArg(arg){if(reservedArgRE.test(arg)){return{value:toNumber(arg),dynamic:false};}else{var stripped=stripQuotes(arg);var dynamic=stripped===arg;return{value:dynamic?arg:stripped,dynamic:dynamic};}}/**
* Parse a directive value and extract the expression
* and its filters into a descriptor.
*
* Example:
*
* "a + 1 | uppercase" will yield:
* {
* expression: 'a + 1',
* filters: [
* { name: 'uppercase', args: null }
* ]
* }
*
* @param {String} s
* @return {Object}
*/function parseDirective(s){var hit=cache$1.get(s);if(hit){return hit;}// reset parser state
str=s;inSingle=inDouble=false;curly=square=paren=0;lastFilterIndex=0;dir={};for(i=0,l=str.length;i<l;i++){prev=c;c=str.charCodeAt(i);if(inSingle){// check single quote
if(c===0x27&&prev!==0x5C)inSingle=!inSingle;}else if(inDouble){// check double quote
if(c===0x22&&prev!==0x5C)inDouble=!inDouble;}else if(c===0x7C&&// pipe
str.charCodeAt(i+1)!==0x7C&&str.charCodeAt(i-1)!==0x7C){if(dir.expression==null){// first filter, end of expression
lastFilterIndex=i+1;dir.expression=str.slice(0,i).trim();}else{// already has filter
pushFilter();}}else{switch(c){case 0x22:inDouble=true;break;// "
case 0x27:inSingle=true;break;// '
case 0x28:paren++;break;// (
case 0x29:paren--;break;// )
case 0x5B:square++;break;// [
case 0x5D:square--;break;// ]
case 0x7B:curly++;break;// {
case 0x7D:curly--;break;// }
}}}if(dir.expression==null){dir.expression=str.slice(0,i).trim();}else if(lastFilterIndex!==0){pushFilter();}cache$1.put(s,dir);return dir;}var directive=Object.freeze({parseDirective:parseDirective});var regexEscapeRE=/[-.*+?^${}()|[\]\/\\]/g;var cache=undefined;var tagRE=undefined;var htmlRE=undefined;/**
* Escape a string so it can be used in a RegExp
* constructor.
*
* @param {String} str
*/function escapeRegex(str){return str.replace(regexEscapeRE,'\\$&');}function compileRegex(){var open=escapeRegex(config.delimiters[0]);var close=escapeRegex(config.delimiters[1]);var unsafeOpen=escapeRegex(config.unsafeDelimiters[0]);var unsafeClose=escapeRegex(config.unsafeDelimiters[1]);tagRE=new RegExp(unsafeOpen+'((?:.|\\n)+?)'+unsafeClose+'|'+open+'((?:.|\\n)+?)'+close,'g');htmlRE=new RegExp('^'+unsafeOpen+'((?:.|\\n)+?)'+unsafeClose+'$');// reset cache
cache=new Cache(1000);}/**
* Parse a template text string into an array of tokens.
*
* @param {String} text
* @return {Array<Object> | null}
* - {String} type
* - {String} value
* - {Boolean} [html]
* - {Boolean} [oneTime]
*/function parseText(text){if(!cache){compileRegex();}var hit=cache.get(text);if(hit){return hit;}if(!tagRE.test(text)){return null;}var tokens=[];var lastIndex=tagRE.lastIndex=0;var match,index,html,value,first,oneTime;/* eslint-disable no-cond-assign */while(match=tagRE.exec(text)){/* eslint-enable no-cond-assign */index=match.index;// push text token
if(index>lastIndex){tokens.push({value:text.slice(lastIndex,index)});}// tag token
html=htmlRE.test(match[0]);value=html?match[1]:match[2];first=value.charCodeAt(0);oneTime=first===42;// *
value=oneTime?value.slice(1):value;tokens.push({tag:true,value:value.trim(),html:html,oneTime:oneTime});lastIndex=index+match[0].length;}if(lastIndex<text.length){tokens.push({value:text.slice(lastIndex)});}cache.put(text,tokens);return tokens;}/**
* Format a list of tokens into an expression.
* e.g. tokens parsed from 'a {{b}} c' can be serialized
* into one single expression as '"a " + b + " c"'.
*
* @param {Array} tokens
* @param {Vue} [vm]
* @return {String}
*/function tokensToExp(tokens,vm){if(tokens.length>1){return tokens.map(function(token){return formatToken(token,vm);}).join('+');}else{return formatToken(tokens[0],vm,true);}}/**
* Format a single token.
*
* @param {Object} token
* @param {Vue} [vm]
* @param {Boolean} [single]
* @return {String}
*/function formatToken(token,vm,single){return token.tag?token.oneTime&&vm?'"'+vm.$eval(token.value)+'"':inlineFilters(token.value,single):'"'+token.value+'"';}/**
* For an attribute with multiple interpolation tags,
* e.g. attr="some-{{thing | filter}}", in order to combine
* the whole thing into a single watchable expression, we
* have to inline those filters. This function does exactly
* that. This is a bit hacky but it avoids heavy changes
* to directive parser and watcher mechanism.
*
* @param {String} exp
* @param {Boolean} single
* @return {String}
*/var filterRE=/[^|]\|[^|]/;function inlineFilters(exp,single){if(!filterRE.test(exp)){return single?exp:'('+exp+')';}else{var dir=parseDirective(exp);if(!dir.filters){return'('+exp+')';}else{return'this._applyFilters('+dir.expression+// value
',null,'+// oldValue (null for read)
JSON.stringify(dir.filters)+// filter descriptors
',false)';// write?
}}}var text=Object.freeze({compileRegex:compileRegex,parseText:parseText,tokensToExp:tokensToExp});var delimiters=['{{','}}'];var unsafeDelimiters=['{{{','}}}'];var config=Object.defineProperties({/**
* Whether to print debug messages.
* Also enables stack trace for warnings.
*
* @type {Boolean}
*/debug:false,/**
* Whether to suppress warnings.
*
* @type {Boolean}
*/silent:false,/**
* Whether to use async rendering.
*/async:true,/**
* Whether to warn against errors caught when evaluating
* expressions.
*/warnExpressionErrors:true,/**
* Whether to allow devtools inspection.
* Disabled by default in production builds.
*/devtools:process.env.NODE_ENV!=='production',/**
* Internal flag to indicate the delimiters have been
* changed.
*
* @type {Boolean}
*/_delimitersChanged:true,/**
* List of asset types that a component can own.
*
* @type {Array}
*/_assetTypes:['component','directive','elementDirective','filter','transition','partial'],/**
* prop binding modes
*/_propBindingModes:{ONE_WAY:0,TWO_WAY:1,ONE_TIME:2},/**
* Max circular updates allowed in a batcher flush cycle.
*/_maxUpdateCount:100},{delimiters:{/**
* Interpolation delimiters. Changing these would trigger
* the text parser to re-compile the regular expressions.
*
* @type {Array<String>}
*/get:function get(){return delimiters;},set:function set(val){delimiters=val;compileRegex();},configurable:true,enumerable:true},unsafeDelimiters:{get:function get(){return unsafeDelimiters;},set:function set(val){unsafeDelimiters=val;compileRegex();},configurable:true,enumerable:true}});var warn=undefined;var formatComponentName=undefined;if(process.env.NODE_ENV!=='production'){(function(){var hasConsole=typeof console!=='undefined';warn=function warn(msg,vm){if(hasConsole&&!config.silent){console.error('[Vue warn]: '+msg+(vm?formatComponentName(vm):''));}};formatComponentName=function formatComponentName(vm){var name=vm._isVue?vm.$options.name:vm.name;return name?' (found in component: <'+hyphenate(name)+'>)':'';};})();}/**
* Append with transition.
*
* @param {Element} el
* @param {Element} target
* @param {Vue} vm
* @param {Function} [cb]
*/function appendWithTransition(el,target,vm,cb){applyTransition(el,1,function(){target.appendChild(el);},vm,cb);}/**
* InsertBefore with transition.
*
* @param {Element} el
* @param {Element} target
* @param {Vue} vm
* @param {Function} [cb]
*/function beforeWithTransition(el,target,vm,cb){applyTransition(el,1,function(){before(el,target);},vm,cb);}/**
* Remove with transition.
*
* @param {Element} el
* @param {Vue} vm
* @param {Function} [cb]
*/function removeWithTransition(el,vm,cb){applyTransition(el,-1,function(){remove(el);},vm,cb);}/**
* Apply transitions with an operation callback.
*
* @param {Element} el
* @param {Number} direction
* 1: enter
* -1: leave
* @param {Function} op - the actual DOM operation
* @param {Vue} vm
* @param {Function} [cb]
*/function applyTransition(el,direction,op,vm,cb){var transition=el.__v_trans;if(!transition||// skip if there are no js hooks and CSS transition is
// not supported
!transition.hooks&&!transitionEndEvent||// skip transitions for initial compile
!vm._isCompiled||// if the vm is being manipulated by a parent directive
// during the parent's compilation phase, skip the
// animation.
vm.$parent&&!vm.$parent._isCompiled){op();if(cb)cb();return;}var action=direction>0?'enter':'leave';transition[action](op,cb);}var transition=Object.freeze({appendWithTransition:appendWithTransition,beforeWithTransition:beforeWithTransition,removeWithTransition:removeWithTransition,applyTransition:applyTransition});/**
* Query an element selector if it's not an element already.
*
* @param {String|Element} el
* @return {Element}
*/function query(el){if(typeof el==='string'){var selector=el;el=document.querySelector(el);if(!el){process.env.NODE_ENV!=='production'&&warn('Cannot find element: '+selector);}}return el;}/**
* Check if a node is in the document.
* Note: document.documentElement.contains should work here
* but always returns false for comment nodes in phantomjs,
* making unit tests difficult. This is fixed by doing the
* contains() check on the node's parentNode instead of
* the node itself.
*
* @param {Node} node
* @return {Boolean}
*/function inDoc(node){if(!node)return false;var doc=node.ownerDocument.documentElement;var parent=node.parentNode;return doc===node||doc===parent||!!(parent&&parent.nodeType===1&&doc.contains(parent));}/**
* Get and remove an attribute from a node.
*
* @param {Node} node
* @param {String} _attr
*/function getAttr(node,_attr){var val=node.getAttribute(_attr);if(val!==null){node.removeAttribute(_attr);}return val;}/**
* Get an attribute with colon or v-bind: prefix.
*
* @param {Node} node
* @param {String} name
* @return {String|null}
*/function getBindAttr(node,name){var val=getAttr(node,':'+name);if(val===null){val=getAttr(node,'v-bind:'+name);}return val;}/**
* Check the presence of a bind attribute.
*
* @param {Node} node
* @param {String} name
* @return {Boolean}
*/function hasBindAttr(node,name){return node.hasAttribute(name)||node.hasAttribute(':'+name)||node.hasAttribute('v-bind:'+name);}/**
* Insert el before target
*
* @param {Element} el
* @param {Element} target
*/function before(el,target){target.parentNode.insertBefore(el,target);}/**
* Insert el after target
*
* @param {Element} el
* @param {Element} target
*/function after(el,target){if(target.nextSibling){before(el,target.nextSibling);}else{target.parentNode.appendChild(el);}}/**
* Remove el from DOM
*
* @param {Element} el
*/function remove(el){el.parentNode.removeChild(el);}/**
* Prepend el to target
*
* @param {Element} el
* @param {Element} target
*/function prepend(el,target){if(target.firstChild){before(el,target.firstChild);}else{target.appendChild(el);}}/**
* Replace target with el
*
* @param {Element} target
* @param {Element} el
*/function replace(target,el){var parent=target.parentNode;if(parent){parent.replaceChild(el,target);}}/**
* Add event listener shorthand.
*
* @param {Element} el
* @param {String} event
* @param {Function} cb
* @param {Boolean} [useCapture]
*/function on(el,event,cb,useCapture){el.addEventListener(event,cb,useCapture);}/**
* Remove event listener shorthand.
*
* @param {Element} el
* @param {String} event
* @param {Function} cb
*/function off(el,event,cb){el.removeEventListener(event,cb);}/**
* For IE9 compat: when both class and :class are present
* getAttribute('class') returns wrong value...
*
* @param {Element} el
* @return {String}
*/function getClass(el){var classname=el.className;if((typeof classname==='undefined'?'undefined':_typeof(classname))==='object'){classname=classname.baseVal||'';}return classname;}/**
* In IE9, setAttribute('class') will result in empty class
* if the element also has the :class attribute; However in
* PhantomJS, setting `className` does not work on SVG elements...
* So we have to do a conditional check here.
*
* @param {Element} el
* @param {String} cls
*/function setClass(el,cls){/* istanbul ignore if */if(isIE9&&!/svg$/.test(el.namespaceURI)){el.className=cls;}else{el.setAttribute('class',cls);}}/**
* Add class with compatibility for IE & SVG
*
* @param {Element} el
* @param {String} cls
*/function addClass(el,cls){if(el.classList){el.classList.add(cls);}else{var cur=' '+getClass(el)+' ';if(cur.indexOf(' '+cls+' ')<0){setClass(el,(cur+cls).trim());}}}/**
* Remove class with compatibility for IE & SVG
*
* @param {Element} el
* @param {String} cls
*/function removeClass(el,cls){if(el.classList){el.classList.remove(cls);}else{var cur=' '+getClass(el)+' ';var tar=' '+cls+' ';while(cur.indexOf(tar)>=0){cur=cur.replace(tar,' ');}setClass(el,cur.trim());}if(!el.className){el.removeAttribute('class');}}/**
* Extract raw content inside an element into a temporary
* container div
*
* @param {Element} el
* @param {Boolean} asFragment
* @return {Element|DocumentFragment}
*/function extractContent(el,asFragment){var child;var rawContent;/* istanbul ignore if */if(isTemplate(el)&&isFragment(el.content)){el=el.content;}if(el.hasChildNodes()){trimNode(el);rawContent=asFragment?document.createDocumentFragment():document.createElement('div');/* eslint-disable no-cond-assign */while(child=el.firstChild){/* eslint-enable no-cond-assign */rawContent.appendChild(child);}}return rawContent;}/**
* Trim possible empty head/tail text and comment
* nodes inside a parent.
*
* @param {Node} node
*/function trimNode(node){var child;/* eslint-disable no-sequences */while(child=node.firstChild,isTrimmable(child)){node.removeChild(child);}while(child=node.lastChild,isTrimmable(child)){node.removeChild(child);}/* eslint-enable no-sequences */}function isTrimmable(node){return node&&(node.nodeType===3&&!node.data.trim()||node.nodeType===8);}/**
* Check if an element is a template tag.
* Note if the template appears inside an SVG its tagName
* will be in lowercase.
*
* @param {Element} el
*/function isTemplate(el){return el.tagName&&el.tagName.toLowerCase()==='template';}/**
* Create an "anchor" for performing dom insertion/removals.
* This is used in a number of scenarios:
* - fragment instance
* - v-html
* - v-if
* - v-for
* - component
*
* @param {String} content
* @param {Boolean} persist - IE trashes empty textNodes on
* cloneNode(true), so in certain
* cases the anchor needs to be
* non-empty to be persisted in
* templates.
* @return {Comment|Text}
*/function createAnchor(content,persist){var anchor=config.debug?document.createComment(content):document.createTextNode(persist?' ':'');anchor.__v_anchor=true;return anchor;}/**
* Find a component ref attribute that starts with $.
*
* @param {Element} node
* @return {String|undefined}
*/var refRE=/^v-ref:/;function findRef(node){if(node.hasAttributes()){var attrs=node.attributes;for(var i=0,l=attrs.length;i<l;i++){var name=attrs[i].name;if(refRE.test(name)){return camelize(name.replace(refRE,''));}}}}/**
* Map a function to a range of nodes .
*
* @param {Node} node
* @param {Node} end
* @param {Function} op
*/function mapNodeRange(node,end,op){var next;while(node!==end){next=node.nextSibling;op(node);node=next;}op(end);}/**
* Remove a range of nodes with transition, store
* the nodes in a fragment with correct ordering,
* and call callback when done.
*
* @param {Node} start
* @param {Node} end
* @param {Vue} vm
* @param {DocumentFragment} frag
* @param {Function} cb
*/function removeNodeRange(start,end,vm,frag,cb){var done=false;var removed=0;var nodes=[];mapNodeRange(start,end,function(node){if(node===end)done=true;nodes.push(node);removeWithTransition(node,vm,onRemoved);});function onRemoved(){removed++;if(done&&removed>=nodes.length){for(var i=0;i<nodes.length;i++){frag.appendChild(nodes[i]);}cb&&cb();}}}/**
* Check if a node is a DocumentFragment.
*
* @param {Node} node
* @return {Boolean}
*/function isFragment(node){return node&&node.nodeType===11;}/**
* Get outerHTML of elements, taking care
* of SVG elements in IE as well.
*
* @param {Element} el
* @return {String}
*/function getOuterHTML(el){if(el.outerHTML){return el.outerHTML;}else{var container=document.createElement('div');container.appendChild(el.cloneNode(true));return container.innerHTML;}}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;var reservedTagRE=/^(slot|partial|component)$/i;var isUnknownElement=undefined;if(process.env.NODE_ENV!=='production'){isUnknownElement=function isUnknownElement(el,tag){if(tag.indexOf('-')>-1){// http://stackoverflow.com/a/28210364/1070244
return el.constructor===window.HTMLUnknownElement||el.constructor===window.HTMLElement;}else{return /HTMLUnknownElement/.test(el.toString())&&// Chrome returns unknown for several HTML5 elements.
// https://code.google.com/p/chromium/issues/detail?id=540526
// Firefox returns unknown for some "Interactive elements."
!/^(data|time|rtc|rb|details|dialog|summary)$/.test(tag);}};}/**
* Check if an element is a component, if yes return its
* component id.
*
* @param {Element} el
* @param {Object} options
* @return {Object|undefined}
*/function checkComponentAttr(el,options){var tag=el.tagName.toLowerCase();var hasAttrs=el.hasAttributes();if(!commonTagRE.test(tag)&&!reservedTagRE.test(tag)){if(resolveAsset(options,'components',tag)){return{id:tag};}else{var is=hasAttrs&&getIsBinding(el,options);if(is){return is;}else if(process.env.NODE_ENV!=='production'){var expectedTag=options._componentNameMap&&options._componentNameMap[tag];if(expectedTag){warn('Unknown custom element: <'+tag+'> - '+'did you mean <'+expectedTag+'>? '+'HTML is case-insensitive, remember to use kebab-case in templates.');}else if(isUnknownElement(el,tag)){warn('Unknown custom element: <'+tag+'> - did you '+'register the component correctly? For recursive components, '+'make sure to provide the "name" option.');}}}}else if(hasAttrs){return getIsBinding(el,options);}}/**
* Get "is" binding from an element.
*
* @param {Element} el
* @param {Object} options
* @return {Object|undefined}
*/function getIsBinding(el,options){// dynamic syntax
var exp=el.getAttribute('is');if(exp!=null){if(resolveAsset(options,'components',exp)){el.removeAttribute('is');return{id:exp};}}else{exp=getBindAttr(el,'is');if(exp!=null){return{id:exp,dynamic:true};}}}/**
* Option overwriting strategies are functions that handle
* how to merge a parent option value and a child option
* value into the final value.
*
* All strategy functions follow the same signature:
*
* @param {*} parentVal
* @param {*} childVal
* @param {Vue} [vm]
*/var strats=config.optionMergeStrategies=Object.create(null);/**
* Helper that recursively merges two data objects together.
*/function mergeData(to,from){var key,toVal,fromVal;for(key in from){toVal=to[key];fromVal=from[key];if(!hasOwn(to,key)){set(to,key,fromVal);}else if(isObject(toVal)&&isObject(fromVal)){mergeData(toVal,fromVal);}}return to;}/**
* Data
*/strats.data=function(parentVal,childVal,vm){if(!vm){// in a Vue.extend merge, both should be functions
if(!childVal){return parentVal;}if(typeof childVal!=='function'){process.env.NODE_ENV!=='production'&&warn('The "data" option should be a function '+'that returns a per-instance value in component '+'definitions.',vm);return parentVal;}if(!parentVal){return childVal;}// when parentVal & childVal are both present,
// we need to return a function that returns the
// merged result of both functions... no need to
// check if parentVal is a function here because
// it has to be a function to pass previous merges.
return function mergedDataFn(){return mergeData(childVal.call(this),parentVal.call(this));};}else if(parentVal||childVal){return function mergedInstanceDataFn(){// instance merge
var instanceData=typeof childVal==='function'?childVal.call(vm):childVal;var defaultData=typeof parentVal==='function'?parentVal.call(vm):undefined;if(instanceData){return mergeData(instanceData,defaultData);}else{return defaultData;}};}};/**
* El
*/strats.el=function(parentVal,childVal,vm){if(!vm&&childVal&&typeof childVal!=='function'){process.env.NODE_ENV!=='production'&&warn('The "el" option should be a function '+'that returns a per-instance value in component '+'definitions.',vm);return;}var ret=childVal||parentVal;// invoke the element factory if this is instance merge
return vm&&typeof ret==='function'?ret.call(vm):ret;};/**
* Hooks and param attributes are merged as arrays.
*/strats.init=strats.created=strats.ready=strats.attached=strats.detached=strats.beforeCompile=strats.compiled=strats.beforeDestroy=strats.destroyed=strats.activate=function(parentVal,childVal){return childVal?parentVal?parentVal.concat(childVal):isArray(childVal)?childVal:[childVal]:parentVal;};/**
* Assets
*
* When a vm is present (instance creation), we need to do
* a three-way merge between constructor options, instance
* options and parent options.
*/function mergeAssets(parentVal,childVal){var res=Object.create(parentVal||null);return childVal?extend(res,guardArrayAssets(childVal)):res;}config._assetTypes.forEach(function(type){strats[type+'s']=mergeAssets;});/**
* Events & Watchers.
*
* Events & watchers hashes should not overwrite one
* another, so we merge them as arrays.
*/strats.watch=strats.events=function(parentVal,childVal){if(!childVal)return parentVal;if(!parentVal)return childVal;var ret={};extend(ret,parentVal);for(var key in childVal){var parent=ret[key];var child=childVal[key];if(parent&&!isArray(parent)){parent=[parent];}ret[key]=parent?parent.concat(child):[child];}return ret;};/**
* Other object hashes.
*/strats.props=strats.methods=strats.computed=function(parentVal,childVal){if(!childVal)return parentVal;if(!parentVal)return childVal;var ret=Object.create(null);extend(ret,parentVal);extend(ret,childVal);return ret;};/**
* Default strategy.
*/var defaultStrat=function defaultStrat(parentVal,childVal){return childVal===undefined?parentVal:childVal;};/**
* Make sure component options get converted to actual
* constructors.
*
* @param {Object} options
*/function guardComponents(options){if(options.components){var components=options.components=guardArrayAssets(options.components);var ids=Object.keys(components);var def;if(process.env.NODE_ENV!=='production'){var map=options._componentNameMap={};}for(var i=0,l=ids.length;i<l;i++){var key=ids[i];if(commonTagRE.test(key)||reservedTagRE.test(key)){process.env.NODE_ENV!=='production'&&warn('Do not use built-in or reserved HTML elements as component '+'id: '+key);continue;}// record a all lowercase <-> kebab-case mapping for
// possible custom element case error warning
if(process.env.NODE_ENV!=='production'){map[key.replace(/-/g,'').toLowerCase()]=hyphenate(key);}def=components[key];if(isPlainObject(def)){components[key]=Vue.extend(def);}}}}/**
* Ensure all props option syntax are normalized into the
* Object-based format.
*
* @param {Object} options
*/function guardProps(options){var props=options.props;var i,val;if(isArray(props)){options.props={};i=props.length;while(i--){val=props[i];if(typeof val==='string'){options.props[val]=null;}else if(val.name){options.props[val.name]=val;}}}else if(isPlainObject(props)){var keys=Object.keys(props);i=keys.length;while(i--){val=props[keys[i]];if(typeof val==='function'){props[keys[i]]={type:val};}}}}/**
* Guard an Array-format assets option and converted it
* into the key-value Object format.
*
* @param {Object|Array} assets
* @return {Object}
*/function guardArrayAssets(assets){if(isArray(assets)){var res={};var i=assets.length;var asset;while(i--){asset=assets[i];var id=typeof asset==='function'?asset.options&&asset.options.name||asset.id:asset.name||asset.id;if(!id){process.env.NODE_ENV!=='production'&&warn('Array-syntax assets must provide a "name" or "id" field.');}else{res[id]=asset;}}return res;}return assets;}/**
* Merge two option objects into a new one.
* Core utility used in both instantiation and inheritance.
*
* @param {Object} parent
* @param {Object} child
* @param {Vue} [vm] - if vm is present, indicates this is
* an instantiation merge.
*/function mergeOptions(parent,child,vm){guardComponents(child);guardProps(child);if(process.env.NODE_ENV!=='production'){if(child.propsData&&!vm){warn('propsData can only be used as an instantiation option.');}}var options={};var key;if(child['extends']){parent=typeof child['extends']==='function'?mergeOptions(parent,child['extends'].options,vm):mergeOptions(parent,child['extends'],vm);}if(child.mixins){for(var i=0,l=child.mixins.length;i<l;i++){var mixin=child.mixins[i];var mixinOptions=mixin.prototype instanceof Vue?mixin.options:mixin;parent=mergeOptions(parent,mixinOptions,vm);}}for(key in parent){mergeField(key);}for(key in child){if(!hasOwn(parent,key)){mergeField(key);}}function mergeField(key){var strat=strats[key]||defaultStrat;options[key]=strat(parent[key],child[key],vm,key);}return options;}/**
* Resolve an asset.
* This function is used because child instances need access
* to assets defined in its ancestor chain.
*
* @param {Object} options
* @param {String} type
* @param {String} id
* @param {Boolean} warnMissing
* @return {Object|Function}
*/function resolveAsset(options,type,id,warnMissing){/* istanbul ignore if */if(typeof id!=='string'){return;}var assets=options[type];var camelizedId;var res=assets[id]||// camelCase ID
assets[camelizedId=camelize(id)]||// Pascal Case ID
assets[camelizedId.charAt(0).toUpperCase()+camelizedId.slice(1)];if(process.env.NODE_ENV!=='production'&&warnMissing&&!res){warn('Failed to resolve '+type.slice(0,-1)+': '+id,options);}return res;}var uid$1=0;/**
* A dep is an observable that can have multiple
* directives subscribing to it.
*
* @constructor
*/function Dep(){this.id=uid$1++;this.subs=[];}// the current target watcher being evaluated.
// this is globally unique because there could be only one
// watcher being evaluated at any time.
Dep.target=null;/**
* Add a directive subscriber.
*
* @param {Directive} sub
*/Dep.prototype.addSub=function(sub){this.subs.push(sub);};/**
* Remove a directive subscriber.
*
* @param {Directive} sub
*/Dep.prototype.removeSub=function(sub){this.subs.$remove(sub);};/**
* Add self as a dependency to the target watcher.
*/Dep.prototype.depend=function(){Dep.target.addDep(this);};/**
* Notify all subscribers of a new value.
*/Dep.prototype.notify=function(){// stablize the subscriber list first
var subs=toArray(this.subs);for(var i=0,l=subs.length;i<l;i++){subs[i].update();}};var arrayProto=Array.prototype;var arrayMethods=Object.create(arrayProto)/**
* Intercept mutating methods and emit events
*/;['push','pop','shift','unshift','splice','sort','reverse'].forEach(function(method){// cache original method
var original=arrayProto[method];def(arrayMethods,method,function mutator(){// avoid leaking arguments:
// http://jsperf.com/closure-with-arguments
var i=arguments.length;var args=new Array(i);while(i--){args[i]=arguments[i];}var result=original.apply(this,args);var ob=this.__ob__;var inserted;switch(method){case'push':inserted=args;break;case'unshift':inserted=args;break;case'splice':inserted=args.slice(2);break;}if(inserted)ob.observeArray(inserted);// notify change
ob.dep.notify();return result;});});/**
* Swap the element at the given index with a new value
* and emits corresponding event.
*
* @param {Number} index
* @param {*} val
* @return {*} - replaced element
*/def(arrayProto,'$set',function $set(index,val){if(index>=this.length){this.length=Number(index)+1;}return this.splice(index,1,val)[0];});/**
* Convenience method to remove the element at given index or target element reference.
*
* @param {*} item
*/def(arrayProto,'$remove',function $remove(item){/* istanbul ignore if */if(!this.length)return;var index=indexOf(this,item);if(index>-1){return this.splice(index,1);}});var arrayKeys=Object.getOwnPropertyNames(arrayMethods);/**
* By default, when a reactive property is set, the new value is
* also converted to become reactive. However in certain cases, e.g.
* v-for scope alias and props, we don't want to force conversion
* because the value may be a nested value under a frozen data structure.
*
* So whenever we want to set a reactive property without forcing
* conversion on the new value, we wrap that call inside this function.
*/var shouldConvert=true;function withoutConversion(fn){shouldConvert=false;fn();shouldConvert=true;}/**
* Observer class that are attached to each observed
* object. Once attached, the observer converts target
* object's property keys into getter/setters that
* collect dependencies and dispatches updates.
*
* @param {Array|Object} value
* @constructor
*/function Observer(value){this.value=value;this.dep=new Dep();def(value,'__ob__',this);if(isArray(value)){var augment=hasProto?protoAugment:copyAugment;augment(value,arrayMethods,arrayKeys);this.observeArray(value);}else{this.walk(value);}}// Instance methods
/**
* Walk through each property and convert them into
* getter/setters. This method should only be called when
* value type is Object.
*
* @param {Object} obj
*/Observer.prototype.walk=function(obj){var keys=Object.keys(obj);for(var i=0,l=keys.length;i<l;i++){this.convert(keys[i],obj[keys[i]]);}};/**
* Observe a list of Array items.
*
* @param {Array} items
*/Observer.prototype.observeArray=function(items){for(var i=0,l=items.length;i<l;i++){observe(items[i]);}};/**
* Convert a property into getter/setter so we can emit
* the events when the property is accessed/changed.
*
* @param {String} key
* @param {*} val
*/Observer.prototype.convert=function(key,val){defineReactive(this.value,key,val);};/**
* Add an owner vm, so that when $set/$delete mutations
* happen we can notify owner vms to proxy the keys and
* digest the watchers. This is only called when the object
* is observed as an instance's root $data.
*
* @param {Vue} vm
*/Observer.prototype.addVm=function(vm){(this.vms||(this.vms=[])).push(vm);};/**
* Remove an owner vm. This is called when the object is
* swapped out as an instance's $data object.
*
* @param {Vue} vm
*/Observer.prototype.removeVm=function(vm){this.vms.$remove(vm);};// helpers
/**
* Augment an target Object or Array by intercepting
* the prototype chain using __proto__
*
* @param {Object|Array} target
* @param {Object} src
*/function protoAugment(target,src){/* eslint-disable no-proto */target.__proto__=src;/* eslint-enable no-proto */}/**
* Augment an target Object or Array by defining
* hidden properties.
*
* @param {Object|Array} target
* @param {Object} proto
*/function copyAugment(target,src,keys){for(var i=0,l=keys.length;i<l;i++){var key=keys[i];def(target,key,src[key]);}}/**
* Attempt to create an observer instance for a value,
* returns the new observer if successfully observed,
* or the existing observer if the value already has one.
*
* @param {*} value
* @param {Vue} [vm]
* @return {Observer|undefined}
* @static
*/function observe(value,vm){if(!value||(typeof value==='undefined'?'undefined':_typeof(value))!=='object'){return;}var ob;if(hasOwn(value,'__ob__')&&value.__ob__ instanceof Observer){ob=value.__ob__;}else if(shouldConvert&&(isArray(value)||isPlainObject(value))&&Object.isExtensible(value)&&!value._isVue){ob=new Observer(value);}if(ob&&vm){ob.addVm(vm);}return ob;}/**
* Define a reactive property on an Object.
*
* @param {Object} obj
* @param {String} key
* @param {*} val
*/function defineReactive(obj,key,val){var dep=new Dep();var property=Object.getOwnPropertyDescriptor(obj,key);if(property&&property.configurable===false){return;}// cater for pre-defined getter/setters
var getter=property&&property.get;var setter=property&&property.set;var childOb=observe(val);Object.defineProperty(obj,key,{enumerable:true,configurable:true,get:function reactiveGetter(){var value=getter?getter.call(obj):val;if(Dep.target){dep.depend();if(childOb){childOb.dep.depend();}if(isArray(value)){for(var e,i=0,l=value.length;i<l;i++){e=value[i];e&&e.__ob__&&e.__ob__.dep.depend();}}}return value;},set:function reactiveSetter(newVal){var value=getter?getter.call(obj):val;if(newVal===value){return;}if(setter){setter.call(obj,newVal);}else{val=newVal;}childOb=observe(newVal);dep.notify();}});}var util=Object.freeze({defineReactive:defineReactive,set:set,del:del,hasOwn:hasOwn,isLiteral:isLiteral,isReserved:isReserved,_toString:_toString,toNumber:toNumber,toBoolean:toBoolean,stripQuotes:stripQuotes,camelize:camelize,hyphenate:hyphenate,classify:classify,bind:bind,toArray:toArray,extend:extend,isObject:isObject,isPlainObject:isPlainObject,def:def,debounce:_debounce,indexOf:indexOf,cancellable:cancellable,looseEqual:looseEqual,isArray:isArray,hasProto:hasProto,inBrowser:inBrowser,devtools:devtools,isIE:isIE,isIE9:isIE9,isAndroid:isAndroid,isIos:isIos,iosVersionMatch:iosVersionMatch,iosVersion:iosVersion,hasMutationObserverBug:hasMutationObserverBug,get