diff --git a/.gitignore b/.gitignore index 396cd18..214d09b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ node_modules .DS_Store example/example.build.js +example/vendor.build.js +example/*.map +npm-debug.log diff --git a/README.md b/README.md index 965de25..43102c5 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,20 @@ > Touch events plugin for Vue.js -This is a directive wrapper for Hammer.js 2.0. +This is a component wrapper for Hammer.js 2.0. ## Install -#### CommonJS +> This plugin requires Vue >= 2.0. For the Vue 1.\*-compatible version, see the `1.0` branch + - Available through npm as `vue-touch`. - ``` js - var VueTouch = require('vue-touch') - Vue.use(VueTouch) - ``` +```Javascript +var VueTouch = require('vue-touch') +Vue.use(VueTouch, {name: 'v-touch'}) +``` +You can pass an options object as the second argument, which at the moment accepts one property, `name`. It's used to define the name of the component that is registered with Vue and defaults to `'v-touch'`. #### Direct include @@ -21,17 +23,99 @@ This is a directive wrapper for Hammer.js 2.0. ## Usage -#### Using the `v-touch` directive +#### Using the `` component ``` html -Tap me! + +Swipe me! + + +Tap me! +``` + +## API + +### Component Events + +vue-touch supports all Hammer Events ot of the box, just bind a listener to the component with `v-on` and vue-touch will setup the Hammer Manager & Recognizer for you. + +|Recognizer|Events|Example| +|---|----|----|----| +|**Pan**|`pan`, `panstart`, `panmove`, `panend`, `pancancel`, `panleft`, `panright`, `panup`, `pandown` |`v-on:panstart="callback"`| +|**Pinch**|`pinch`, `pinchstart`, `pinchmove`,`pinchend`, `pinchcancel`, `pinchin`, `pinchout`| `v-on:pinchout="callback"`| +|**Press**|`press`, `pressup`|`v-on:pressup="callback"`| +|**Rotate**|`rotate`, `rotatestart`, `rotatemove`, `rotateend`, `rotatecancel`, |`v-on:rotateend="callback"`| +|**Swipe**|`swipe`, `swipeleft`, `swiperight`, `swipeup`, `swipedown`|`v-on:swipeleft="callback"`| +|**Tap**|`tap`|`v-on:tap="callback"`| + +### Component Props -
Swipe me!
+You can use the matching `*-options` props to pass Hammer options such as `direction` and `threshold`: + +``` html + + + ``` +There's one prop per `Recognizer` available. + +|Recognizer|Prop| +|----------|----| +|**Pan**|`v-bind:pan-options`| +|**Pinch**|`v-bind:pinch-options`| +|**Rotate**|`v-bind:rotate-options`| +|**Swipe**|`v-bind:swipe-options`| +|**Tap**|`v-bind:tap-options`| + +See [Hammer.js documentation](http://hammerjs.github.io/getting-started/) for all available options for events. -#### Configuring Recognizer Options +#### Directions -There are two ways to customize recognizer options such as `direction` and `threshold`. The first one is setting global options: +In the above example, not that we used `direction: 'horizontal'`. Hammer's directions interface is a little ugly (Hammer['DIRECTION_HORIZONTAL']). + +VueTouch keeps that from you and accepts simple strings as directions: + +```javascript +const directions = ['up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all'] +``` + +## Public Component Methods + +The component exposes a few convenience methods to enable and disable Recognizers: + +|Method|Explanation| +|------|-----------| +|`disable(event)`|disable the Recognizer for `event`| +|`enable(event)`|disable the Recognizer for `event`| +|`disableAll`|disable all Recognizers| +|`enableAll`|enable all Recognizers| +|`isEnabled(event)`|returns `true` if Recognizer for `event` is currently enabled| + +```html + + +``` + +### Plugin Methods + +#### Global Event Options + +You can define global defaults for the builtin recognizers ``` js // change the threshold for all swipe recognizers @@ -40,18 +124,10 @@ VueTouch.config.swipe = { } ``` -Or, you can use the `v-touch-options` directive to configure the behavior on a specific element: - -``` html - - - -``` - #### Registering Custom Events +You can register custom events with vue-touch. + ``` js // example registering a custom doubletap event. // the `type` indicates the base recognizer to use from Hammer @@ -61,14 +137,28 @@ VueTouch.registerCustomEvent('doubletap', { taps: 2 }) ``` +> **Warning**: You have to register your custom events *before* installing the plugin with `Vue.use(VueTouch)`. +VueTouch will log a warning to the console (in dev mode) if you try to do that afterwards, and the event will not work. + +This will make it possible to listen for this event on ``. Additionally, just like for "normal" events, you can pass further options as the corresponding prop. + ``` html - + + + ``` -See [Hammer.js documentation](http://hammerjs.github.io/getting-started/) for all available events. - See `/example` for a multi-event demo. To build it, run `npm install && npm run build`. +## Known Limitations & Bugs + +* Curently, changing `-options` props will not change recogizer settings. The initial values will stay in place until the component is re-created. + +## TODO + +* [ ] Support updating recognizer options when props change. +* [ ] Find out if e2e tests are possible(contribution welcome) + ## License [MIT](http://opensource.org/licenses/MIT) diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..3d9aed3 --- /dev/null +++ b/TODO.md @@ -0,0 +1,13 @@ +* [x] refactor HammerJS out of this so it can be an external dependency passed into the plugin via options +* [x] Improve Test cases in /examples/index.html +* [x] Test prod build process with rollup +* [x] Add test run with prod build +* [x] clean up package.json +* [x] add unit tests +* [x] Write README docs +* [ ] Write Release notes +* [ ] create 1.0 Branch for old version +* [x] include assign polyfill +* [x] create function to define props to reduce size. +* [ ] use DefinePlugin / ReplacePlugin to get rid of warnings in production. +* [x] add public Methods `isEnabled(event)` diff --git a/build/devserver.js b/build/devserver.js new file mode 100644 index 0000000..2da9cef --- /dev/null +++ b/build/devserver.js @@ -0,0 +1,14 @@ +var webpack = require('webpack') +var DevServer = require('webpack-dev-server') +var config = require('./webpack.config.dev.js') +config.entry.example.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server"); +var compiler = webpack(config) +var server = new DevServer(compiler, { + contentBase: './example/', + clientLogLevel: 'warning', + hot: true, +}) + +server.listen(8080) + +module.exports = server diff --git a/build/rollup.config.prod.js b/build/rollup.config.prod.js new file mode 100644 index 0000000..ee938d9 --- /dev/null +++ b/build/rollup.config.prod.js @@ -0,0 +1,23 @@ +import buble from 'rollup-plugin-buble' +import commonjs from 'rollup-plugin-commonjs' +import nodeResolve from 'rollup-plugin-node-resolve' +import cleanup from 'rollup-plugin-cleanup' + +export default { + entry: './src/index.js', + dest: './dist/vue-touch.js', + // Module settings + format: 'umd', + external: ['hammerjs'], + globals: { + hammerjs: 'Hammer' + }, + moduleName: 'VueTouch', + + plugins: [ + buble(), + nodeResolve({ jsnext: true, main: true }), + commonjs(), + cleanup() + ] +} diff --git a/build/webpack.config.dev.js b/build/webpack.config.dev.js new file mode 100644 index 0000000..45c601e --- /dev/null +++ b/build/webpack.config.dev.js @@ -0,0 +1,55 @@ +var path = require('path') +var webpack = require('webpack') + +const config = { + entry: { + example: ['./example/example.js'], + vendor: ['vue', 'hammerjs'], + }, + output: { + path: path.resolve(__dirname, "../example"), + publicPath: '/', + library: 'VueTouch', + libraryTarget: 'umd', + filename: '[name].build.js' + }, + resolve: { + alias: { + 'vue$': 'vue/dist/vue.common' + } + }, + module: { + rules: [ + { + test: /\.js$/, + loader: 'buble-loader', + exclude: path.resolve(__dirname, "../node_modules") + }, + { + test: /\.css$/, + loader: 'style-loader!css-loader', + exclude: path.resolve(__dirname, "../node_modules") + } + ] + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: process.env.NODE_ENV ? JSON.stringify(process.env.NODE_ENV) : "'development'" + } + }), + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor' + }) + ], + devtool: 'source-map', + performance: { + hints: false + }, + /*devServer: { + contentBase: '/example/' + }*/ +} + +module.exports = config diff --git a/dist/vue-touch.js b/dist/vue-touch.js new file mode 100644 index 0000000..ae2348b --- /dev/null +++ b/dist/vue-touch.js @@ -0,0 +1,202 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('hammerjs')) : + typeof define === 'function' && define.amd ? define(['hammerjs'], factory) : + (factory(global.Hammer)); +}(this, (function (Hammer) { 'use strict'; + +Hammer = 'default' in Hammer ? Hammer['default'] : Hammer; + +function assign(target) { + var sources = [], len = arguments.length - 1; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; + for (var i = 0; i < sources.length; i++) { + var source = sources[i]; + var keys = Object.keys(source); + for (var i$1 = 0; i$1 < keys.length; i$1++) { + var key = keys[i$1]; + target[key] = source[key]; + } + } + return target +} +function createProp() { + return { + type: Object, + default: function() { return {} } + } +} +function capitalize (str) { + return str.charAt(0).toUpperCase() + str.slice(1) +} +var directions = ['up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all']; +function guardDirections (options) { + var dir = options.direction; + if (typeof dir === 'string') { + var hammerDirection = 'DIRECTION_' + dir.toUpperCase(); + if (directions.indexOf(dir) > -1 && Hammer.hasOwnProperty(hammerDirection)) { + options.direction = Hammer[hammerDirection]; + } else { + console.warn('[vue-touch] invalid direction: ' + dir); + } + } + return options +} +var config = { +}; +var customEvents = { +}; +var gestures = [ + 'pan','panstart','panmove','panend','pancancel','panleft','panright','panup','pandown', + 'pinch','pinchstart','pinchmove','pinchend','pinchcancel','pinchin','pinchout', + 'press','pressup', + 'rotate','rotatestart','rotatemove','rotateend','rotatecancel', + 'swipe','swipeleft','swiperight','swipeup','swipedown', + 'tap' +]; +var gestureMap = { + pan: 'pan', + panstart: 'pan', + panmove: 'pan', + panend: 'pan', + pancancel: 'pan', + panleft: 'pan', + panright: 'pan', + panup: 'pan', + pandown: 'pan', + pinch: 'pinch', + pinchstart: 'pinch', + pinchmove: 'pinch', + pinchend: 'pinch', + pinchcancel: 'pinch', + pinchin: 'pinch', + pinchout: 'pinch', + press: 'press', + pressup: 'press', + rotate: 'rotate', + rotatestart: 'rotate', + rotatemove: 'rotate', + rotateend: 'rotate', + rotatecancel: 'rotate', + swipe: 'swipe', + swipeleft: 'swipe', + swiperight: 'swipe', + swipeup: 'swipe', + swipedown: 'swipe', + tap: 'tap' +}; + +var Component = { + props: { + tapOptions: createProp(), + panOptions: createProp(), + pinchOptions: createProp(), + pressOptions: createProp(), + rotateOptions: createProp(), + swipeOptions: createProp(), + tag: { type: String, default: 'div' }, + }, + mounted: function mounted() { + this.hammer = new Hammer.Manager(this.$el); + this.recognizers = {}; + this.setupBuiltinRecognizers(); + this.setupCustomRecognizers(); + }, + destroyed: function destroyed() { + this.hammer.destroy(); + }, + methods: { + setupBuiltinRecognizers: function setupBuiltinRecognizers() { + var this$1 = this; + for (var i = 0; i < gestures.length; i++) { + var gesture = gestures[i]; + if (this$1._events[gesture]) { + var mainGesture = gestureMap[gesture]; + var options = assign({}, (config[mainGesture] || {}), this$1[(mainGesture + "Options")]); + this$1.addRecognizer(mainGesture, options); + this$1.addEvent(gesture); + } + } + }, + setupCustomRecognizers: function setupCustomRecognizers() { + var this$1 = this; + var gestures$$1 = Object.keys(customEvents); + for (var i = 0; i < gestures$$1.length; i++) { + var gesture = gestures$$1[i]; + if (this$1._events[gesture]) { + var opts = customEvents[gesture]; + var localCustomOpts = this$1[(gesture + "Options")] || {}; + var options = assign({}, opts, localCustomOpts); + this$1.addRecognizer(gesture, options, {mainGesture: options.type}); + this$1.addEvent(gesture); + } + } + }, + addRecognizer: function addRecognizer(gesture, options, ref) { + if ( ref === void 0 ) ref = {}; + var mainGesture = ref.mainGesture; + if (!this.recognizers[gesture]) { + var recognizer = new Hammer[capitalize(mainGesture || gesture)](guardDirections(options)); + this.recognizers[gesture] = recognizer; + this.hammer.add(recognizer); + recognizer.recognizeWith(this.hammer.recognizers); + } + }, + addEvent: function addEvent(gesture) { + var this$1 = this; + this.hammer.on(gesture, function (e) { return this$1.$emit(gesture, e); }); + }, + enable: function enable(r) { this.recognizers[r].set({ enable: true }); }, + disable: function disable(r) { this.recognizers[r].set({ enable: false }); }, + enableAll: function enableAll(r) { this.toggleAll({ enable: true }); }, + disableAll: function disableAll(r) { this.toggleAll({ enable: false }); }, + toggleAll: function toggleAll(ref) { + var this$1 = this; + var enable = ref.enable; + var keys = Object.keys(this.recognizers); + for (var i = 0; i < keys.length; i++) { + var r = this$1.recognizers[keys[i]]; + r.set({ enable: enable }); + } + }, + isEnabled: function isEnabled(r) { + return this.recognizers[r] && this.recognizers[r].options.enable + } + }, + render: function render(h) { + return h(this.tag, {}, this.$slots.default) + } +}; + +var installed = false; +var vueTouch = { config: config, customEvents: customEvents }; +vueTouch.component = Component; +vueTouch.install = function install(Vue, opts) { + if ( opts === void 0 ) opts = {}; + var name = opts.name || 'v-touch'; + Vue.component(name, assign(this.component, { name: name })); + installed = true; +}.bind(vueTouch); +vueTouch.registerCustomEvent = function registerCustomEvent(event, options) { + if ( options === void 0 ) options = {}; + if (installed) { + console.warn(("\n [vue-touch]: Custom Event '" + event + "' couldn't be added to vue-touch.\n Custom Events have to be registered before installing the plugin.\n ")); + return + } + options.event = event; + customEvents[event] = options; + this.component.props[(event + "Options")] = { + type: Object, + default: function default$1() { return {} } + }; +}.bind(vueTouch); +if (typeof exports == "object") { + module.exports = vueTouch; +} else if (typeof define == "function" && define.amd) { + define([], function(){ return vueTouch }); +} else if (window.Vue) { + window.VueTouch = vueTouch; + Vue.use(vueTouch); +} + +}))); +//# sourceMappingURL=vue-touch.js.map diff --git a/dist/vue-touch.js.map b/dist/vue-touch.js.map new file mode 100644 index 0000000..07bdc81 --- /dev/null +++ b/dist/vue-touch.js.map @@ -0,0 +1 @@ +{"version":3,"file":null,"sources":["../src/utils.js","../src/component.js","../src/index.js"],"sourcesContent":["import Hammer from 'hammerjs' // used by guardDirections\n\n/**\n * Tiny Object.assign replacement\n * @param {Object} target Any type of object\n * @param {Object} sources Any type of object\n * @return {Object} Merged Object\n */\nexport function assign(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n const source = sources[i]\n const keys = Object.keys(source)\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]\n target[key] = source[key]\n }\n }\n return target\n}\n\n/**\n * Small helper method to generate prop options for all the\n * *-options props.\n * @return {[type]} [description]\n */\nexport function createProp() {\n return {\n type: Object,\n default: function() { return {} }\n }\n}\n\nexport function capitalize (str) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\n/**\n * Directions that VueTouch understands.\n * Will be tanslated to Hammer-style directions by guardDirections()\n * @type {Array}\n */\nexport const directions = ['up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all']\n\n/**\n * Translates VueTouch direction names into Hammer Direction numbers.\n * @param {Objects} options Hammer Options\n * @return {Object} [Hammer Options]\n */\nexport function guardDirections (options) {\n var dir = options.direction\n if (typeof dir === 'string') {\n var hammerDirection = 'DIRECTION_' + dir.toUpperCase()\n if (directions.indexOf(dir) > -1 && Hammer.hasOwnProperty(hammerDirection)) {\n options.direction = Hammer[hammerDirection]\n } else {\n console.warn('[vue-touch] invalid direction: ' + dir)\n }\n }\n return options\n}\n\n/**\n * This pobject will contain global options for recognizers\n * see index.js -> vueTouch.config\n * @type {Object}\n */\nexport const config = {\n\n}\n\n/**\n * This object will contain recognizer options for custom events.\n * see index.js -> registerCustomEvent\n * @type {Object}\n */\nexport const customEvents = {\n\n}\n\n/**\n * Names of all the builtin gestures of Hammer\n * @type {Array}\n */\nexport const gestures = [\n 'pan','panstart','panmove','panend','pancancel','panleft','panright','panup','pandown',\n 'pinch','pinchstart','pinchmove','pinchend','pinchcancel','pinchin','pinchout',\n 'press','pressup',\n 'rotate','rotatestart','rotatemove','rotateend','rotatecancel',\n 'swipe','swipeleft','swiperight','swipeup','swipedown',\n 'tap'\n]\n\n/**\n * Maps the gestures to their \"main gesture\" (the name of the recognizer)\n * @type {Object}\n */\nexport const gestureMap = {\n pan: 'pan',\n panstart: 'pan',\n panmove: 'pan',\n panend: 'pan',\n pancancel: 'pan',\n panleft: 'pan',\n panright: 'pan',\n panup: 'pan',\n pandown: 'pan',\n pinch: 'pinch',\n pinchstart: 'pinch',\n pinchmove: 'pinch',\n pinchend: 'pinch',\n pinchcancel: 'pinch',\n pinchin: 'pinch',\n pinchout: 'pinch',\n press: 'press',\n pressup: 'press',\n rotate: 'rotate',\n rotatestart: 'rotate',\n rotatemove: 'rotate',\n rotateend: 'rotate',\n rotatecancel: 'rotate',\n swipe: 'swipe',\n swipeleft: 'swipe',\n swiperight: 'swipe',\n swipeup: 'swipe',\n swipedown: 'swipe',\n tap: 'tap'\n}\n","import Hammer from 'hammerjs'\n\nimport {\n createProp,\n capitalize,\n guardDirections,\n gestures,\n gestureMap,\n directions,\n assign,\n config,\n customEvents\n} from './utils'\n\nexport default {\n props: {\n tapOptions: createProp(),\n panOptions: createProp(),\n pinchOptions: createProp(),\n pressOptions: createProp(),\n rotateOptions: createProp(),\n swipeOptions: createProp(),\n tag: { type: String, default: 'div' },\n },\n\n mounted() {\n this.hammer = new Hammer.Manager(this.$el)\n this.recognizers = {} // not reactive\n this.setupBuiltinRecognizers()\n this.setupCustomRecognizers()\n },\n destroyed() {\n this.hammer.destroy()\n },\n\n methods: {\n\n setupBuiltinRecognizers() {\n // Built-in Hammer events\n // We check weither any event callbacks are registered\n // for the gesture, and if so, add a Recognizer\n for (let i = 0; i < gestures.length; i++) {\n const gesture = gestures[i]\n if (this._events[gesture]) {\n // get the main gesture (e.g. 'panstart' -> 'pan')\n const mainGesture = gestureMap[gesture]\n //merge global and local options\n const options = assign({}, (config[mainGesture] || {}), this[`${mainGesture}Options`])\n // add recognizer for this main gesture\n this.addRecognizer(mainGesture, options)\n // register Event Emit for the specific gesture\n this.addEvent(gesture)\n }\n }\n },\n\n setupCustomRecognizers() {\n // Custom events\n // We get the customGestures and options from the\n // customEvents object, then basically do the same check\n // as we did for the built-in events.\n const gestures = Object.keys(customEvents)\n\n for (let i = 0; i < gestures.length; i++) {\n\n const gesture = gestures[i]\n\n if (this._events[gesture]) {\n const opts = customEvents[gesture]\n const localCustomOpts = this[`${gesture}Options`] || {}\n const options = assign({}, opts, localCustomOpts)\n this.addRecognizer(gesture, options, {mainGesture: options.type})\n this.addEvent(gesture)\n }\n }\n },\n\n /**\n * Registers a new Recognizer with the manager and saves it on the component\n * instance\n * @param {String} gesture See utils.js -> gestures\n * @param {Object} options Hammer options\n * @param {String} mainGesture if gesture is a custom event name, mapping to utils.js -> gestures\n */\n addRecognizer: function addRecognizer(gesture, options, { mainGesture } = {}) {\n // create recognizer, e.g. new Hammer['Swipe'](options)\n if (!this.recognizers[gesture]) {\n const recognizer = new Hammer[capitalize(mainGesture || gesture)](guardDirections(options))\n this.recognizers[gesture] = recognizer\n this.hammer.add(recognizer)\n recognizer.recognizeWith(this.hammer.recognizers)\n }\n },\n\n addEvent(gesture) {\n this.hammer.on(gesture, (e) => this.$emit(gesture, e))\n },\n\n // Enabling / Disabling certain recognizers.\n //\n enable(r) { this.recognizers[r].set({ enable: true }) },\n disable(r) { this.recognizers[r].set({ enable: false }) },\n enableAll(r) { this.toggleAll({ enable: true }) },\n disableAll(r) { this.toggleAll({ enable: false }) },\n toggleAll({ enable }) {\n const keys = Object.keys(this.recognizers)\n for (let i = 0; i < keys.length; i++) {\n const r = this.recognizers[keys[i]]\n r.set({ enable: enable })\n }\n },\n isEnabled(r) {\n return this.recognizers[r] && this.recognizers[r].options.enable\n }\n },\n\n render(h) {\n return h(this.tag, {}, this.$slots.default)\n }\n}\n","import Hammer from 'hammerjs'\n\nimport Component from './component'\nimport { assign, config, customEvents } from './utils'\n\nlet installed = false\n\nconst vueTouch = { config, customEvents }\n\nvueTouch.component = Component\n\n// Plugin API\n// *********\nvueTouch.install = function install(Vue, opts = {}) {\n const name = opts.name || 'v-touch'\n Vue.component(name, assign(this.component, { name }))\n installed = true\n}.bind(vueTouch)\n\nvueTouch.registerCustomEvent = function registerCustomEvent(event, options = {}) {\n if (installed) {\n console.warn(`\n [vue-touch]: Custom Event '${event}' couldn't be added to vue-touch.\n Custom Events have to be registered before installing the plugin.\n `)\n return\n }\n options.event = event\n customEvents[event] = options\n this.component.props[`${event}Options`] = {\n type: Object,\n default() { return {} }\n }\n}.bind(vueTouch)\n\n// Utilities\n// ********\n\nif (typeof exports == \"object\") {\n module.exports = vueTouch\n} else if (typeof define == \"function\" && define.amd) {\n define([], function(){ return vueTouch })\n} else if (window.Vue) {\n window.VueTouch = vueTouch\n Vue.use(vueTouch)\n}\n"],"names":["let","const","i","this","gestures"],"mappings":"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"} \ No newline at end of file diff --git a/dist/vue-touch.min.js b/dist/vue-touch.min.js new file mode 100644 index 0000000..e730a9b --- /dev/null +++ b/dist/vue-touch.min.js @@ -0,0 +1 @@ +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("hammerjs")):"function"==typeof define&&define.amd?define(["hammerjs"],n):n(e.Hammer)}(this,function(e){"use strict";function n(e){for(var n=[],t=arguments.length-1;t-- >0;)n[t]=arguments[t+1];for(var i=0;i-1&&e.hasOwnProperty(i)?n.direction=e[i]:console.warn("[vue-touch] invalid direction: "+t)}return n}e="default"in e?e.default:e;var r=["up","down","left","right","horizontal","vertical","all"],s={},a={},p=["pan","panstart","panmove","panend","pancancel","panleft","panright","panup","pandown","pinch","pinchstart","pinchmove","pinchend","pinchcancel","pinchin","pinchout","press","pressup","rotate","rotatestart","rotatemove","rotateend","rotatecancel","swipe","swipeleft","swiperight","swipeup","swipedown","tap"],c={pan:"pan",panstart:"pan",panmove:"pan",panend:"pan",pancancel:"pan",panleft:"pan",panright:"pan",panup:"pan",pandown:"pan",pinch:"pinch",pinchstart:"pinch",pinchmove:"pinch",pinchend:"pinch",pinchcancel:"pinch",pinchin:"pinch",pinchout:"pinch",press:"press",pressup:"press",rotate:"rotate",rotatestart:"rotate",rotatemove:"rotate",rotateend:"rotate",rotatecancel:"rotate",swipe:"swipe",swipeleft:"swipe",swiperight:"swipe",swipeup:"swipe",swipedown:"swipe",tap:"tap"},u={props:{tapOptions:t(),panOptions:t(),pinchOptions:t(),pressOptions:t(),rotateOptions:t(),swipeOptions:t(),tag:{type:String,default:"div"}},mounted:function(){this.hammer=new e.Manager(this.$el),this.recognizers={},this.setupBuiltinRecognizers(),this.setupCustomRecognizers()},destroyed:function(){this.hammer.destroy()},methods:{setupBuiltinRecognizers:function(){for(var e=this,t=0;t + + + `, +}) + +Vue.component('rotator', { + template: ` + + + + {{name || 'NoEvent'}} - {{angle}}deg, {{rotation}} + + + `, + data() { + return { + angle: 0, + rotation: 0, + initialRotation: 0, + name: '' + } + }, + methods: { + cb(event) { + console.log('rotate', event) + if (event.isFirst) { this.initialRotation = event.rotation } + else { + const newRotation = Math.round(event.rotation - this.initialRotation) + + this.rotation = this.rotation = newRotation + } + this.angle = Math.round(event.angle) + this.name = event.type + } + }, + computed: { + rotated() { + return { transform: `rotate(${this.rotation}deg)` } + } + } +}) diff --git a/example/example.build.js.map b/example/example.build.js.map new file mode 100644 index 0000000..273bd4d --- /dev/null +++ b/example/example.build.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///./src/index.js","webpack:///./example/example.js"],"names":["let","const","this"],"mappings":"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","file":"example.build.js","sourcesContent":["let Hammer\n\nconst gestures = [\n 'pan','panstart','panmove','panend','pancancel','panleft','panright','panup','pandown',\n 'pinch','pinchstart','pinchmove','pinchend','pinchcancel','pinchin','pinchout',\n 'press','pressup',\n 'rotate','rotatestart','rotatemove','rotateend','rotatecancel',\n 'swipe','swipeleft','swiperight','swipeup','swipedown',\n 'tap'\n]\nconst gestureMap = {\n pan: 'pan',\n panstart: 'pan',\n panmove: 'pan',\n panend: 'pan',\n pancancel: 'pan',\n panleft: 'pan',\n panright: 'pan',\n panup: 'pan',\n pandown: 'pan',\n pinch: 'pinch',\n pinchstart: 'pinch',\n pinchmove: 'pinch',\n pinchend: 'pinch',\n pinchcancel: 'pinch',\n pinchin: 'pinch',\n pinchout: 'pinch',\n press: 'press',\n pressup: 'press',\n rotate: 'rotate',\n rotatestart: 'rotate',\n rotatemove: 'rotate',\n rotateend: 'rotate',\n rotatecancel: 'rotate',\n swipe: 'swipe',\n swipeleft: 'swipe',\n swiperight: 'swipe',\n swipeup: 'swipe',\n swipedown: 'swipe',\n tap: 'tap'\n}\nconst directions = ['up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all']\nconst customEvents = {}\nlet installed = false\n\nconst vueTouch = { config: {}, customEvents }\n\nvueTouch.component = {\n props: {\n tapOptions: {\n type: Object,\n default() { return {} }\n },\n panOptions: {\n type: Object,\n default() { return {} }\n },\n pinchOptions: {\n type: Object,\n default() { return {} }\n },\n pressOptions: {\n type: Object,\n default() { return {} }\n },\n rotateOptions: {\n type: Object,\n default() { return {} }\n },\n swipeOptions: {\n type: Object,\n default() { return {} }\n },\n tag: {\n type: String,\n default: 'div'\n }\n },\n\n mounted() {\n this.hammer = new Hammer.Manager(this.$el)\n this.recognizers = {}\n this.setupRecognizers()\n },\n destroyed() {\n this.hammer.destroy()\n },\n\n methods: {\n setupRecognizers() {\n this.setupBuiltinRecognizers()\n this.setupCustomRecognizers()\n },\n\n setupBuiltinRecognizers() {\n // Built-in events\n // We check weither any event callbacks are registered\n // for the gesture, and if so, add a Recognizer\n for (let i = 0; i < gestures.length; i++) {\n const gesture = gestures[i]\n if (this._events[gesture]) {\n // get the main gesture (e.g. 'panstart' -> 'pan')\n const mainGesture = gestureMap[gesture]\n //merge global and local options\n const options = Object.assign({}, vueTouch.config[mainGesture], this[`${mainGesture}Options`])\n // add recognizer for this main gesture\n this.addRecognizer(mainGesture, options)\n // register Event Emit for the specific gesture\n this.addEvent(gesture)\n }\n }\n },\n\n setupCustomRecognizers() {\n // Custom events\n // We get the customGestures and options from the\n // customEvents object, then basically do the same check\n // as we did for the built-in events.\n const gestures = Object.keys(customEvents)\n\n for (let i = 0; i < gestures.length; i++) {\n\n const gesture = gestures[i]\n\n if (this._events[gesture]) {\n const mainGesture = gestureMap[gesture]\n const opts = customEvents[gesture]\n const localCustomOpts = this[`${gesture}Options`] || {}\n const options = Object.assign({}, opts, localCustomOpts)\n this.addRecognizer(gesture, options, {mainGesture: options.type})\n this.addEvent(gesture)\n }\n }\n },\n\n addRecognizer(gesture, options, { mainGesture } = {}) {\n // create recognizer, e.g. new Hammer['Swipe'](options)\n if (!this.recognizers[gesture]) {\n const recognizer = new Hammer[capitalize(mainGesture || gesture)](guardDirections(options))\n this.recognizers[gesture] = recognizer\n this.hammer.add(recognizer)\n recognizer.recognizeWith(this.hammer.recognizers)\n }\n },\n\n addEvent(gesture) {\n this.hammer.on(gesture, (e) => this.$emit(gesture, e))\n },\n\n // Enabling / Disabling certain recognizers.\n //\n enable(r) { this.recognizers[r].set({ enable: true }) },\n disable(r) { this.recognizers[r].set({ enable: false }) },\n enableAll(r) { this.toggleAll({ enable: true }) },\n disableAll(r) { this.toggleAll({ enable: false }) },\n toggleAll({ enable }) {\n const keys = Object.keys(this.recognizers)\n for (let i = 0; i < keys.length; i++) {\n const r = this.recognizers[keys[i]]\n r.set({ enable: enable })\n }\n }\n },\n\n render(h) {\n return h(this.tag, {}, this.$slots.default)\n }\n}\n\n// Plugin API\n// *********\nvueTouch.install = function(Vue, opts = {}) {\n\n if (!opts.hammer && !window.Hammer) {\n console.warn(`\n [vue-touch] Hammer constructor not found. Either make it available globally,\n or pass it as an option to the plugin: Vue.use(VueTouch, {hammer: Hammer})\n notice the lowercase property key!\n `)\n return\n }\n const name = opts.name || 'v-touch'\n Hammer = opts.hammer || window.Hammer\n Vue.component(name, Object.assign(this.component, { name }))\n installed = true\n\n}\n\nvueTouch.registerCustomEvent = function registerCustomEvent(event, options = {}) {\n if (installed) {\n console.warn(`\n [vue-touch]: Custom Event '${event}' couldn't be added to vue-touch.\n Custom Events have to be registered before installing the plugin.\n `)\n return\n }\n options.event = event\n customEvents[event] = options\n vueTouch.component.props[`${event}Options`] = {\n type: Object,\n default() { return {} }\n }\n}\n\n// Utilities\n// ********\n\nfunction capitalize (str) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nfunction guardDirections (options) {\n var dir = options.direction\n if (typeof dir === 'string') {\n var hammerDirection = 'DIRECTION_' + dir.toUpperCase()\n if (directions.indexOf(dir) > -1 && Hammer.hasOwnProperty(hammerDirection)) {\n options.direction = Hammer[hammerDirection]\n } else {\n console.warn('[vue-touch] invalid direction: ' + dir)\n }\n }\n return options\n}\n\nif (typeof exports == \"object\") {\n module.exports = vueTouch\n} else if (typeof define == \"function\" && define.amd) {\n define([], function(){ return vueTouch })\n} else if (window.Vue) {\n window.VueTouch = vueTouch\n Vue.use(vueTouch)\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","var Vue = require('vue')\nvar VueTouch = require('../src')\n// import './styling.css'\n// import './components'\n// use the plugin\n\n// example registering a custom doubletap event.\n// the `type` indicates the base recognizer to use from Hammer\n// all other options are Hammer recognizer options.\nVueTouch.registerCustomEvent('doubletap', {\n type: 'tap',\n taps: 2\n})\n\nVue.use(VueTouch)\n\nnew Vue({\n el: 'div',\n data: {\n event: {}\n },\n methods: {\n test: function (e) {\n delete e.target\n this.event = e\n console.log(e)\n }\n }\n})\n\n\n\n// WEBPACK FOOTER //\n// ./example/example.js"],"sourceRoot":""} \ No newline at end of file diff --git a/example/example.js b/example/example.js index 33aeec4..32fa729 100644 --- a/example/example.js +++ b/example/example.js @@ -1,8 +1,16 @@ var Vue = require('vue') -var VueTouch = require('../') +var VueTouch + +if (process.env.NODE_ENV === 'development') { + VueTouch = require('../src') +} +else { + VueTouch = require('../dist/vue-touch.js') +} +// import './styling.css' +// import './components' // use the plugin -Vue.use(VueTouch) // example registering a custom doubletap event. // the `type` indicates the base recognizer to use from Hammer @@ -12,14 +20,18 @@ VueTouch.registerCustomEvent('doubletap', { taps: 2 }) +Vue.use(VueTouch) + new Vue({ - el: 'div', + el: '#app', data: { - event: '' + event: {} }, methods: { test: function (e) { - this.event = e.type + delete e.target + this.event = e + console.log(e) } } }) diff --git a/example/index.html b/example/index.html index bde1672..92b4b98 100644 --- a/example/index.html +++ b/example/index.html @@ -3,7 +3,7 @@ - + vue-touch Test Area -
+
+ +

{{event.type}}

+
+
{{event}}
+ +
+ diff --git a/example/styling.css b/example/styling.css new file mode 100644 index 0000000..19fcdac --- /dev/null +++ b/example/styling.css @@ -0,0 +1,6 @@ +.container > div { + color: white; + background-color: navy; + width: 300px; + height: 150px; +} diff --git a/example/vendor.build.js b/example/vendor.build.js new file mode 100644 index 0000000..1af23c0 --- /dev/null +++ b/example/vendor.build.js @@ -0,0 +1,11351 @@ +var umd = +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ var parentJsonpFunction = window["webpackJsonpumd"]; +/******/ window["webpackJsonpumd"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = [], result; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); +/******/ while(resolves.length) +/******/ resolves.shift()(); +/******/ if(executeModules) { +/******/ for(i=0; i < executeModules.length; i++) { +/******/ result = __webpack_require__(__webpack_require__.s = executeModules[i]); +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // objects to store loaded and loading chunks +/******/ var installedChunks = { +/******/ 1: 0 +/******/ }; +/******/ +/******/ // 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] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId) { +/******/ if(installedChunks[chunkId] === 0) +/******/ return Promise.resolve(); +/******/ +/******/ // an Promise means "currently loading". +/******/ if(installedChunks[chunkId]) { +/******/ return installedChunks[chunkId][2]; +/******/ } +/******/ // start chunk loading +/******/ var head = document.getElementsByTagName('head')[0]; +/******/ var script = document.createElement('script'); +/******/ script.type = 'text/javascript'; +/******/ script.charset = 'utf-8'; +/******/ script.async = true; +/******/ script.timeout = 120000; +/******/ +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.src = __webpack_require__.p + "" + chunkId + ".build.js"; +/******/ var timeout = setTimeout(onScriptComplete, 120000); +/******/ script.onerror = script.onload = onScriptComplete; +/******/ function onScriptComplete() { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var chunk = installedChunks[chunkId]; +/******/ if(chunk !== 0) { +/******/ if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); +/******/ installedChunks[chunkId] = undefined; +/******/ } +/******/ }; +/******/ head.appendChild(script); +/******/ +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ return installedChunks[chunkId][2] = promise; +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "/"; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 6); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process, global) {/*! + * Vue.js v2.1.6 + * (c) 2014-2016 Evan You + * Released under the MIT License. + */ +'use strict'; + +/* */ + +/** + * Convert a value to a string that is actually rendered. + */ +function _toString (val) { + return val == null + ? '' + : typeof val === 'object' + ? JSON.stringify(val, null, 2) + : String(val) +} + +/** + * Convert a input value to a number for persistence. + * If the conversion fails, return original string. + */ +function toNumber (val) { + var n = parseFloat(val, 10); + return (n || n === 0) ? n : val +} + +/** + * Make a map and return a function for checking if a key + * is in that map. + */ +function makeMap ( + str, + expectsLowerCase +) { + var map = Object.create(null); + var list = str.split(','); + for (var i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase + ? function (val) { return map[val.toLowerCase()]; } + : function (val) { return map[val]; } +} + +/** + * Check if a tag is a built-in tag. + */ +var isBuiltInTag = makeMap('slot,component', true); + +/** + * Remove an item from an array + */ +function remove$1 (arr, item) { + if (arr.length) { + var index = arr.indexOf(item); + if (index > -1) { + return arr.splice(index, 1) + } + } +} + +/** + * Check whether the object has the property. + */ +var hasOwnProperty = Object.prototype.hasOwnProperty; +function hasOwn (obj, key) { + return hasOwnProperty.call(obj, key) +} + +/** + * Check if value is primitive + */ +function isPrimitive (value) { + return typeof value === 'string' || typeof value === 'number' +} + +/** + * Create a cached version of a pure function. + */ +function cached (fn) { + var cache = Object.create(null); + return function cachedFn (str) { + var hit = cache[str]; + return hit || (cache[str] = fn(str)) + } +} + +/** + * Camelize a hyphen-delmited string. + */ +var camelizeRE = /-(\w)/g; +var camelize = cached(function (str) { + return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) +}); + +/** + * Capitalize a string. + */ +var capitalize = cached(function (str) { + return str.charAt(0).toUpperCase() + str.slice(1) +}); + +/** + * Hyphenate a camelCase string. + */ +var hyphenateRE = /([^-])([A-Z])/g; +var hyphenate = cached(function (str) { + return str + .replace(hyphenateRE, '$1-$2') + .replace(hyphenateRE, '$1-$2') + .toLowerCase() +}); + +/** + * Simple bind, faster than native + */ +function bind$1 (fn, ctx) { + function boundFn (a) { + var l = arguments.length; + return l + ? l > 1 + ? fn.apply(ctx, arguments) + : fn.call(ctx, a) + : fn.call(ctx) + } + // record original fn length + boundFn._length = fn.length; + return boundFn +} + +/** + * Convert an Array-like object to a real 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. + */ +function extend (to, _from) { + for (var key in _from) { + to[key] = _from[key]; + } + 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. + */ +function isObject (obj) { + return obj !== null && typeof obj === 'object' +} + +/** + * Strict object type check. Only returns true + * for plain JavaScript objects. + */ +var toString = Object.prototype.toString; +var OBJECT_STRING = '[object Object]'; +function isPlainObject (obj) { + return toString.call(obj) === OBJECT_STRING +} + +/** + * Merge an Array of Objects into a single Object. + */ +function toObject (arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res +} + +/** + * Perform no operation. + */ +function noop () {} + +/** + * Always return false. + */ +var no = function () { return false; }; + +/** + * Return same value + */ +var identity = function (_) { return _; }; + +/** + * Generate a static keys string from compiler modules. + */ +function genStaticKeys (modules) { + return modules.reduce(function (keys, m) { + return keys.concat(m.staticKeys || []) + }, []).join(',') +} + +/** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + */ +function looseEqual (a, b) { + /* eslint-disable eqeqeq */ + return a == b || ( + isObject(a) && isObject(b) + ? JSON.stringify(a) === JSON.stringify(b) + : false + ) + /* eslint-enable eqeqeq */ +} + +function looseIndexOf (arr, val) { + for (var i = 0; i < arr.length; i++) { + if (looseEqual(arr[i], val)) { return i } + } + return -1 +} + +/* */ + +var config = { + /** + * Option merge strategies (used in core/util/options) + */ + optionMergeStrategies: Object.create(null), + + /** + * Whether to suppress warnings. + */ + silent: false, + + /** + * Whether to enable devtools + */ + devtools: process.env.NODE_ENV !== 'production', + + /** + * Error handler for watcher errors + */ + errorHandler: null, + + /** + * Ignore certain custom elements + */ + ignoredElements: null, + + /** + * Custom user key aliases for v-on + */ + keyCodes: Object.create(null), + + /** + * Check if a tag is reserved so that it cannot be registered as a + * component. This is platform-dependent and may be overwritten. + */ + isReservedTag: no, + + /** + * Check if a tag is an unknown element. + * Platform-dependent. + */ + isUnknownElement: no, + + /** + * Get the namespace of an element + */ + getTagNamespace: noop, + + /** + * Parse the real tag name for the specific platform. + */ + parsePlatformTagName: identity, + + /** + * Check if an attribute must be bound using property, e.g. value + * Platform-dependent. + */ + mustUseProp: no, + + /** + * List of asset types that a component can own. + */ + _assetTypes: [ + 'component', + 'directive', + 'filter' + ], + + /** + * List of lifecycle hooks. + */ + _lifecycleHooks: [ + 'beforeCreate', + 'created', + 'beforeMount', + 'mounted', + 'beforeUpdate', + 'updated', + 'beforeDestroy', + 'destroyed', + 'activated', + 'deactivated' + ], + + /** + * Max circular updates allowed in a scheduler flush cycle. + */ + _maxUpdateCount: 100 +}; + +/* */ + +/** + * Check if a string starts with $ or _ + */ +function isReserved (str) { + var c = (str + '').charCodeAt(0); + return c === 0x24 || c === 0x5F +} + +/** + * Define a property. + */ +function def (obj, key, val, enumerable) { + Object.defineProperty(obj, key, { + value: val, + enumerable: !!enumerable, + writable: true, + configurable: true + }); +} + +/** + * Parse simple path. + */ +var bailRE = /[^\w.$]/; +function parsePath (path) { + if (bailRE.test(path)) { + return + } else { + var segments = path.split('.'); + return function (obj) { + for (var i = 0; i < segments.length; i++) { + if (!obj) { return } + obj = obj[segments[i]]; + } + return obj + } + } +} + +/* */ +/* globals MutationObserver */ + +// can we use __proto__? +var hasProto = '__proto__' in {}; + +// Browser environment sniffing +var inBrowser = typeof window !== 'undefined'; +var UA = inBrowser && window.navigator.userAgent.toLowerCase(); +var isIE = UA && /msie|trident/.test(UA); +var isIE9 = UA && UA.indexOf('msie 9.0') > 0; +var isEdge = UA && UA.indexOf('edge/') > 0; +var isAndroid = UA && UA.indexOf('android') > 0; +var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); + +// this needs to be lazy-evaled because vue may be required before +// vue-server-renderer can set VUE_ENV +var _isServer; +var isServerRendering = function () { + if (_isServer === undefined) { + /* istanbul ignore if */ + if (!inBrowser && typeof global !== 'undefined') { + // detect presence of vue-server-renderer and avoid + // Webpack shimming the process + _isServer = global['process'].env.VUE_ENV === 'server'; + } else { + _isServer = false; + } + } + return _isServer +}; + +// detect devtools +var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; + +/* istanbul ignore next */ +function isNative (Ctor) { + return /native code/.test(Ctor.toString()) +} + +/** + * Defer a task to execute it asynchronously. + */ +var nextTick = (function () { + var callbacks = []; + var pending = false; + var timerFunc; + + function nextTickHandler () { + pending = false; + var copies = callbacks.slice(0); + callbacks.length = 0; + for (var i = 0; i < copies.length; i++) { + copies[i](); + } + } + + // the nextTick behavior leverages the microtask queue, which can be accessed + // via either native Promise.then or MutationObserver. + // MutationObserver has wider support, however it is seriously bugged in + // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It + // completely stops working after triggering a few times... so, if native + // Promise is available, we will use it: + /* istanbul ignore if */ + if (typeof Promise !== 'undefined' && isNative(Promise)) { + var p = Promise.resolve(); + var logError = function (err) { console.error(err); }; + timerFunc = function () { + p.then(nextTickHandler).catch(logError); + // in problematic UIWebViews, Promise.then doesn't completely break, but + // it can get stuck in a weird state where callbacks are pushed into the + // microtask queue but the queue isn't being flushed, until the browser + // needs to do some other work, e.g. handle a timer. Therefore we can + // "force" the microtask queue to be flushed by adding an empty timer. + if (isIOS) { setTimeout(noop); } + }; + } else if (typeof MutationObserver !== 'undefined' && ( + isNative(MutationObserver) || + // PhantomJS and iOS 7.x + MutationObserver.toString() === '[object MutationObserverConstructor]' + )) { + // use MutationObserver where native Promise is not available, + // e.g. PhantomJS IE11, iOS7, Android 4.4 + var counter = 1; + var observer = new MutationObserver(nextTickHandler); + var textNode = document.createTextNode(String(counter)); + observer.observe(textNode, { + characterData: true + }); + timerFunc = function () { + counter = (counter + 1) % 2; + textNode.data = String(counter); + }; + } else { + // fallback to setTimeout + /* istanbul ignore next */ + timerFunc = function () { + setTimeout(nextTickHandler, 0); + }; + } + + return function queueNextTick (cb, ctx) { + var _resolve; + callbacks.push(function () { + if (cb) { cb.call(ctx); } + if (_resolve) { _resolve(ctx); } + }); + if (!pending) { + pending = true; + timerFunc(); + } + if (!cb && typeof Promise !== 'undefined') { + return new Promise(function (resolve) { + _resolve = resolve; + }) + } + } +})(); + +var _Set; +/* istanbul ignore if */ +if (typeof Set !== 'undefined' && isNative(Set)) { + // use native Set when available. + _Set = Set; +} else { + // a non-standard Set polyfill that only works with primitive keys. + _Set = (function () { + function Set () { + this.set = Object.create(null); + } + Set.prototype.has = function has (key) { + return this.set[key] === true + }; + Set.prototype.add = function add (key) { + this.set[key] = true; + }; + Set.prototype.clear = function clear () { + this.set = Object.create(null); + }; + + return Set; + }()); +} + +var warn = noop; +var formatComponentName; + +if (process.env.NODE_ENV !== 'production') { + var hasConsole = typeof console !== 'undefined'; + + warn = function (msg, vm) { + if (hasConsole && (!config.silent)) { + console.error("[Vue warn]: " + msg + " " + ( + vm ? formatLocation(formatComponentName(vm)) : '' + )); + } + }; + + formatComponentName = function (vm) { + if (vm.$root === vm) { + return 'root instance' + } + var name = vm._isVue + ? vm.$options.name || vm.$options._componentTag + : vm.name; + return ( + (name ? ("component <" + name + ">") : "anonymous component") + + (vm._isVue && vm.$options.__file ? (" at " + (vm.$options.__file)) : '') + ) + }; + + var formatLocation = function (str) { + if (str === 'anonymous component') { + str += " - use the \"name\" option for better debugging messages."; + } + return ("\n(found in " + str + ")") + }; +} + +/* */ + + +var uid$1 = 0; + +/** + * A dep is an observable that can have multiple + * directives subscribing to it. + */ +var Dep = function Dep () { + this.id = uid$1++; + this.subs = []; +}; + +Dep.prototype.addSub = function addSub (sub) { + this.subs.push(sub); +}; + +Dep.prototype.removeSub = function removeSub (sub) { + remove$1(this.subs, sub); +}; + +Dep.prototype.depend = function depend () { + if (Dep.target) { + Dep.target.addDep(this); + } +}; + +Dep.prototype.notify = function notify () { + // stablize the subscriber list first + var subs = this.subs.slice(); + for (var i = 0, l = subs.length; i < l; i++) { + subs[i].update(); + } +}; + +// 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; +var targetStack = []; + +function pushTarget (_target) { + if (Dep.target) { targetStack.push(Dep.target); } + Dep.target = _target; +} + +function popTarget () { + Dep.target = targetStack.pop(); +} + +/* + * not type checking this file because flow doesn't play well with + * dynamically accessing methods on Array prototype + */ + +var arrayProto = Array.prototype; +var arrayMethods = Object.create(arrayProto);[ + 'push', + 'pop', + 'shift', + 'unshift', + 'splice', + 'sort', + 'reverse' +] +.forEach(function (method) { + // cache original method + var original = arrayProto[method]; + def(arrayMethods, method, function mutator () { + var arguments$1 = arguments; + + // avoid leaking arguments: + // http://jsperf.com/closure-with-arguments + var i = arguments.length; + var args = new Array(i); + while (i--) { + args[i] = arguments$1[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 + }); +}); + +/* */ + +var arrayKeys = Object.getOwnPropertyNames(arrayMethods); + +/** + * By default, when a reactive property is set, the new value is + * also converted to become reactive. However when passing down props, + * we don't want to force conversion because the value may be a nested value + * under a frozen data structure. Converting it would defeat the optimization. + */ +var observerState = { + shouldConvert: true, + isSettingProps: false +}; + +/** + * 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. + */ +var Observer = function Observer (value) { + this.value = value; + this.dep = new Dep(); + this.vmCount = 0; + def(value, '__ob__', this); + if (Array.isArray(value)) { + var augment = hasProto + ? protoAugment + : copyAugment; + augment(value, arrayMethods, arrayKeys); + this.observeArray(value); + } else { + this.walk(value); + } +}; + +/** + * Walk through each property and convert them into + * getter/setters. This method should only be called when + * value type is Object. + */ +Observer.prototype.walk = function walk (obj) { + var keys = Object.keys(obj); + for (var i = 0; i < keys.length; i++) { + defineReactive$$1(obj, keys[i], obj[keys[i]]); + } +}; + +/** + * Observe a list of Array items. + */ +Observer.prototype.observeArray = function observeArray (items) { + for (var i = 0, l = items.length; i < l; i++) { + observe(items[i]); + } +}; + +// helpers + +/** + * Augment an target Object or Array by intercepting + * the prototype chain using __proto__ + */ +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. + */ +/* istanbul ignore next */ +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. + */ +function observe (value) { + if (!isObject(value)) { + return + } + var ob; + if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { + ob = value.__ob__; + } else if ( + observerState.shouldConvert && + !isServerRendering() && + (Array.isArray(value) || isPlainObject(value)) && + Object.isExtensible(value) && + !value._isVue + ) { + ob = new Observer(value); + } + return ob +} + +/** + * Define a reactive property on an Object. + */ +function defineReactive$$1 ( + obj, + key, + val, + customSetter +) { + 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 (Array.isArray(value)) { + dependArray(value); + } + } + return value + }, + set: function reactiveSetter (newVal) { + var value = getter ? getter.call(obj) : val; + /* eslint-disable no-self-compare */ + if (newVal === value || (newVal !== newVal && value !== value)) { + return + } + /* eslint-enable no-self-compare */ + if (process.env.NODE_ENV !== 'production' && customSetter) { + customSetter(); + } + if (setter) { + setter.call(obj, newVal); + } else { + val = newVal; + } + childOb = observe(newVal); + dep.notify(); + } + }); +} + +/** + * Set a property on an object. Adds the new property and + * triggers change notification if the property doesn't + * already exist. + */ +function set$1 (obj, key, val) { + if (Array.isArray(obj)) { + obj.length = Math.max(obj.length, key); + obj.splice(key, 1, val); + return val + } + if (hasOwn(obj, key)) { + obj[key] = val; + return + } + var ob = obj.__ob__; + if (obj._isVue || (ob && ob.vmCount)) { + process.env.NODE_ENV !== 'production' && warn( + 'Avoid adding reactive properties to a Vue instance or its root $data ' + + 'at runtime - declare it upfront in the data option.' + ); + return + } + if (!ob) { + obj[key] = val; + return + } + defineReactive$$1(ob.value, key, val); + ob.dep.notify(); + return val +} + +/** + * Delete a property and trigger change if necessary. + */ +function del (obj, key) { + var ob = obj.__ob__; + if (obj._isVue || (ob && ob.vmCount)) { + process.env.NODE_ENV !== 'production' && warn( + 'Avoid deleting properties on a Vue instance or its root $data ' + + '- just set it to null.' + ); + return + } + if (!hasOwn(obj, key)) { + return + } + delete obj[key]; + if (!ob) { + return + } + ob.dep.notify(); +} + +/** + * Collect dependencies on array elements when the array is touched, since + * we cannot intercept array element access like property getters. + */ +function dependArray (value) { + for (var e = (void 0), i = 0, l = value.length; i < l; i++) { + e = value[i]; + e && e.__ob__ && e.__ob__.dep.depend(); + if (Array.isArray(e)) { + dependArray(e); + } + } +} + +/* */ + +/** + * Option overwriting strategies are functions that handle + * how to merge a parent option value and a child option + * value into the final value. + */ +var strats = config.optionMergeStrategies; + +/** + * Options with restrictions + */ +if (process.env.NODE_ENV !== 'production') { + strats.el = strats.propsData = function (parent, child, vm, key) { + if (!vm) { + warn( + "option \"" + key + "\" can only be used during instance " + + 'creation with the `new` keyword.' + ); + } + return defaultStrat(parent, child) + }; +} + +/** + * Helper that recursively merges two data objects together. + */ +function mergeData (to, from) { + if (!from) { return to } + var key, toVal, fromVal; + var keys = Object.keys(from); + for (var i = 0; i < keys.length; i++) { + key = keys[i]; + toVal = to[key]; + fromVal = from[key]; + if (!hasOwn(to, key)) { + set$1(to, key, fromVal); + } else if (isPlainObject(toVal) && isPlainObject(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 + } + } + } +}; + +/** + * Hooks and param attributes are merged as arrays. + */ +function mergeHook ( + parentVal, + childVal +) { + return childVal + ? parentVal + ? parentVal.concat(childVal) + : Array.isArray(childVal) + ? childVal + : [childVal] + : parentVal +} + +config._lifecycleHooks.forEach(function (hook) { + strats[hook] = mergeHook; +}); + +/** + * 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, childVal) + : res +} + +config._assetTypes.forEach(function (type) { + strats[type + 's'] = mergeAssets; +}); + +/** + * Watchers. + * + * Watchers hashes should not overwrite one + * another, so we merge them as arrays. + */ +strats.watch = function (parentVal, childVal) { + /* istanbul ignore if */ + 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 && !Array.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 (parentVal, childVal) { + return childVal === undefined + ? parentVal + : childVal +}; + +/** + * Validate component names + */ +function checkComponents (options) { + for (var key in options.components) { + var lower = key.toLowerCase(); + if (isBuiltInTag(lower) || config.isReservedTag(lower)) { + warn( + 'Do not use built-in or reserved HTML elements as component ' + + 'id: ' + key + ); + } + } +} + +/** + * Ensure all props option syntax are normalized into the + * Object-based format. + */ +function normalizeProps (options) { + var props = options.props; + if (!props) { return } + var res = {}; + var i, val, name; + if (Array.isArray(props)) { + i = props.length; + while (i--) { + val = props[i]; + if (typeof val === 'string') { + name = camelize(val); + res[name] = { type: null }; + } else if (process.env.NODE_ENV !== 'production') { + warn('props must be strings when using array syntax.'); + } + } + } else if (isPlainObject(props)) { + for (var key in props) { + val = props[key]; + name = camelize(key); + res[name] = isPlainObject(val) + ? val + : { type: val }; + } + } + options.props = res; +} + +/** + * Normalize raw function directives into object format. + */ +function normalizeDirectives (options) { + var dirs = options.directives; + if (dirs) { + for (var key in dirs) { + var def = dirs[key]; + if (typeof def === 'function') { + dirs[key] = { bind: def, update: def }; + } + } + } +} + +/** + * Merge two option objects into a new one. + * Core utility used in both instantiation and inheritance. + */ +function mergeOptions ( + parent, + child, + vm +) { + if (process.env.NODE_ENV !== 'production') { + checkComponents(child); + } + normalizeProps(child); + normalizeDirectives(child); + var extendsFrom = child.extends; + if (extendsFrom) { + parent = typeof extendsFrom === 'function' + ? mergeOptions(parent, extendsFrom.options, vm) + : mergeOptions(parent, extendsFrom, vm); + } + if (child.mixins) { + for (var i = 0, l = child.mixins.length; i < l; i++) { + var mixin = child.mixins[i]; + if (mixin.prototype instanceof Vue$3) { + mixin = mixin.options; + } + parent = mergeOptions(parent, mixin, vm); + } + } + var options = {}; + var key; + 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. + */ +function resolveAsset ( + options, + type, + id, + warnMissing +) { + /* istanbul ignore if */ + if (typeof id !== 'string') { + return + } + var assets = options[type]; + // check local registration variations first + if (hasOwn(assets, id)) { return assets[id] } + var camelizedId = camelize(id); + if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } + var PascalCaseId = capitalize(camelizedId); + if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } + // fallback to prototype chain + var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; + if (process.env.NODE_ENV !== 'production' && warnMissing && !res) { + warn( + 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, + options + ); + } + return res +} + +/* */ + +function validateProp ( + key, + propOptions, + propsData, + vm +) { + var prop = propOptions[key]; + var absent = !hasOwn(propsData, key); + var value = propsData[key]; + // handle boolean props + if (isBooleanType(prop.type)) { + if (absent && !hasOwn(prop, 'default')) { + value = false; + } else if (value === '' || value === hyphenate(key)) { + value = true; + } + } + // check default value + if (value === undefined) { + value = getPropDefaultValue(vm, prop, key); + // since the default value is a fresh copy, + // make sure to observe it. + var prevShouldConvert = observerState.shouldConvert; + observerState.shouldConvert = true; + observe(value); + observerState.shouldConvert = prevShouldConvert; + } + if (process.env.NODE_ENV !== 'production') { + assertProp(prop, key, value, vm, absent); + } + return value +} + +/** + * Get the default value of a prop. + */ +function getPropDefaultValue (vm, prop, key) { + // no default, return undefined + if (!hasOwn(prop, 'default')) { + return undefined + } + var def = prop.default; + // warn against non-factory defaults for Object & Array + if (isObject(def)) { + process.env.NODE_ENV !== 'production' && warn( + 'Invalid default value for prop "' + key + '": ' + + 'Props with type Object/Array must use a factory function ' + + 'to return the default value.', + vm + ); + } + // the raw prop value was also undefined from previous render, + // return previous default value to avoid unnecessary watcher trigger + if (vm && vm.$options.propsData && + vm.$options.propsData[key] === undefined && + vm[key] !== undefined) { + return vm[key] + } + // call factory function for non-Function types + return typeof def === 'function' && prop.type !== Function + ? def.call(vm) + : def +} + +/** + * Assert whether a prop is valid. + */ +function assertProp ( + prop, + name, + value, + vm, + absent +) { + if (prop.required && absent) { + warn( + 'Missing required prop: "' + name + '"', + vm + ); + return + } + if (value == null && !prop.required) { + return + } + var type = prop.type; + var valid = !type || type === true; + var expectedTypes = []; + if (type) { + if (!Array.isArray(type)) { + type = [type]; + } + for (var i = 0; i < type.length && !valid; i++) { + var assertedType = assertType(value, type[i]); + expectedTypes.push(assertedType.expectedType); + valid = assertedType.valid; + } + } + if (!valid) { + warn( + 'Invalid prop: type check failed for prop "' + name + '".' + + ' Expected ' + expectedTypes.map(capitalize).join(', ') + + ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', + vm + ); + return + } + var validator = prop.validator; + if (validator) { + if (!validator(value)) { + warn( + 'Invalid prop: custom validator check failed for prop "' + name + '".', + vm + ); + } + } +} + +/** + * Assert the type of a value + */ +function assertType (value, type) { + var valid; + var expectedType = getType(type); + if (expectedType === 'String') { + valid = typeof value === (expectedType = 'string'); + } else if (expectedType === 'Number') { + valid = typeof value === (expectedType = 'number'); + } else if (expectedType === 'Boolean') { + valid = typeof value === (expectedType = 'boolean'); + } else if (expectedType === 'Function') { + valid = typeof value === (expectedType = 'function'); + } else if (expectedType === 'Object') { + valid = isPlainObject(value); + } else if (expectedType === 'Array') { + valid = Array.isArray(value); + } else { + valid = value instanceof type; + } + return { + valid: valid, + expectedType: expectedType + } +} + +/** + * Use function string name to check built-in types, + * because a simple equality check will fail when running + * across different vms / iframes. + */ +function getType (fn) { + var match = fn && fn.toString().match(/^\s*function (\w+)/); + return match && match[1] +} + +function isBooleanType (fn) { + if (!Array.isArray(fn)) { + return getType(fn) === 'Boolean' + } + for (var i = 0, len = fn.length; i < len; i++) { + if (getType(fn[i]) === 'Boolean') { + return true + } + } + /* istanbul ignore next */ + return false +} + + + +var util = Object.freeze({ + defineReactive: defineReactive$$1, + _toString: _toString, + toNumber: toNumber, + makeMap: makeMap, + isBuiltInTag: isBuiltInTag, + remove: remove$1, + hasOwn: hasOwn, + isPrimitive: isPrimitive, + cached: cached, + camelize: camelize, + capitalize: capitalize, + hyphenate: hyphenate, + bind: bind$1, + toArray: toArray, + extend: extend, + isObject: isObject, + isPlainObject: isPlainObject, + toObject: toObject, + noop: noop, + no: no, + identity: identity, + genStaticKeys: genStaticKeys, + looseEqual: looseEqual, + looseIndexOf: looseIndexOf, + isReserved: isReserved, + def: def, + parsePath: parsePath, + hasProto: hasProto, + inBrowser: inBrowser, + UA: UA, + isIE: isIE, + isIE9: isIE9, + isEdge: isEdge, + isAndroid: isAndroid, + isIOS: isIOS, + isServerRendering: isServerRendering, + devtools: devtools, + nextTick: nextTick, + get _Set () { return _Set; }, + mergeOptions: mergeOptions, + resolveAsset: resolveAsset, + get warn () { return warn; }, + get formatComponentName () { return formatComponentName; }, + validateProp: validateProp +}); + +/* not type checking this file because flow doesn't play well with Proxy */ + +var initProxy; + +if (process.env.NODE_ENV !== 'production') { + var allowedGlobals = makeMap( + 'Infinity,undefined,NaN,isFinite,isNaN,' + + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + + 'require' // for Webpack/Browserify + ); + + var warnNonPresent = function (target, key) { + warn( + "Property or method \"" + key + "\" is not defined on the instance but " + + "referenced during render. Make sure to declare reactive data " + + "properties in the data option.", + target + ); + }; + + var hasProxy = + typeof Proxy !== 'undefined' && + Proxy.toString().match(/native code/); + + if (hasProxy) { + var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta'); + config.keyCodes = new Proxy(config.keyCodes, { + set: function set (target, key, value) { + if (isBuiltInModifier(key)) { + warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); + return false + } else { + target[key] = value; + return true + } + } + }); + } + + var hasHandler = { + has: function has (target, key) { + var has = key in target; + var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; + if (!has && !isAllowed) { + warnNonPresent(target, key); + } + return has || !isAllowed + } + }; + + var getHandler = { + get: function get (target, key) { + if (typeof key === 'string' && !(key in target)) { + warnNonPresent(target, key); + } + return target[key] + } + }; + + initProxy = function initProxy (vm) { + if (hasProxy) { + // determine which proxy handler to use + var options = vm.$options; + var handlers = options.render && options.render._withStripped + ? getHandler + : hasHandler; + vm._renderProxy = new Proxy(vm, handlers); + } else { + vm._renderProxy = vm; + } + }; +} + +/* */ + + +var queue = []; +var has$1 = {}; +var circular = {}; +var waiting = false; +var flushing = false; +var index = 0; + +/** + * Reset the scheduler's state. + */ +function resetSchedulerState () { + queue.length = 0; + has$1 = {}; + if (process.env.NODE_ENV !== 'production') { + circular = {}; + } + waiting = flushing = false; +} + +/** + * Flush both queues and run the watchers. + */ +function flushSchedulerQueue () { + flushing = true; + + // Sort queue before flush. + // This ensures that: + // 1. Components are updated from parent to child. (because parent is always + // created before the child) + // 2. A component's user watchers are run before its render watcher (because + // user watchers are created before the render watcher) + // 3. If a component is destroyed during a parent component's watcher run, + // its watchers can be skipped. + queue.sort(function (a, b) { return a.id - b.id; }); + + // do not cache length because more watchers might be pushed + // as we run existing watchers + for (index = 0; index < queue.length; index++) { + var watcher = queue[index]; + var id = watcher.id; + has$1[id] = null; + watcher.run(); + // in dev build, check and stop circular updates. + if (process.env.NODE_ENV !== 'production' && has$1[id] != null) { + circular[id] = (circular[id] || 0) + 1; + if (circular[id] > config._maxUpdateCount) { + warn( + 'You may have an infinite update loop ' + ( + watcher.user + ? ("in watcher with expression \"" + (watcher.expression) + "\"") + : "in a component render function." + ), + watcher.vm + ); + break + } + } + } + + // devtool hook + /* istanbul ignore if */ + if (devtools && config.devtools) { + devtools.emit('flush'); + } + + resetSchedulerState(); +} + +/** + * Push a watcher into the watcher queue. + * Jobs with duplicate IDs will be skipped unless it's + * pushed when the queue is being flushed. + */ +function queueWatcher (watcher) { + var id = watcher.id; + if (has$1[id] == null) { + has$1[id] = true; + if (!flushing) { + queue.push(watcher); + } else { + // if already flushing, splice the watcher based on its id + // if already past its id, it will be run next immediately. + var i = queue.length - 1; + while (i >= 0 && queue[i].id > watcher.id) { + i--; + } + queue.splice(Math.max(i, index) + 1, 0, watcher); + } + // queue the flush + if (!waiting) { + waiting = true; + nextTick(flushSchedulerQueue); + } + } +} + +/* */ + +var uid$2 = 0; + +/** + * A watcher parses an expression, collects dependencies, + * and fires callback when the expression value changes. + * This is used for both the $watch() api and directives. + */ +var Watcher = function Watcher ( + vm, + expOrFn, + cb, + options +) { + if ( options === void 0 ) options = {}; + + this.vm = vm; + vm._watchers.push(this); + // options + this.deep = !!options.deep; + this.user = !!options.user; + this.lazy = !!options.lazy; + this.sync = !!options.sync; + this.expression = expOrFn.toString(); + this.cb = cb; + this.id = ++uid$2; // uid for batching + this.active = true; + this.dirty = this.lazy; // for lazy watchers + this.deps = []; + this.newDeps = []; + this.depIds = new _Set(); + this.newDepIds = new _Set(); + // parse expression for getter + if (typeof expOrFn === 'function') { + this.getter = expOrFn; + } else { + this.getter = parsePath(expOrFn); + if (!this.getter) { + this.getter = function () {}; + process.env.NODE_ENV !== 'production' && warn( + "Failed watching path: \"" + expOrFn + "\" " + + 'Watcher only accepts simple dot-delimited paths. ' + + 'For full control, use a function instead.', + vm + ); + } + } + this.value = this.lazy + ? undefined + : this.get(); +}; + +/** + * Evaluate the getter, and re-collect dependencies. + */ +Watcher.prototype.get = function get () { + pushTarget(this); + var value = this.getter.call(this.vm, this.vm); + // "touch" every property so they are all tracked as + // dependencies for deep watching + if (this.deep) { + traverse(value); + } + popTarget(); + this.cleanupDeps(); + return value +}; + +/** + * Add a dependency to this directive. + */ +Watcher.prototype.addDep = function addDep (dep) { + var id = dep.id; + if (!this.newDepIds.has(id)) { + this.newDepIds.add(id); + this.newDeps.push(dep); + if (!this.depIds.has(id)) { + dep.addSub(this); + } + } +}; + +/** + * Clean up for dependency collection. + */ +Watcher.prototype.cleanupDeps = function cleanupDeps () { + var this$1 = this; + + var i = this.deps.length; + while (i--) { + var dep = this$1.deps[i]; + if (!this$1.newDepIds.has(dep.id)) { + dep.removeSub(this$1); + } + } + var tmp = this.depIds; + this.depIds = this.newDepIds; + this.newDepIds = tmp; + this.newDepIds.clear(); + tmp = this.deps; + this.deps = this.newDeps; + this.newDeps = tmp; + this.newDeps.length = 0; +}; + +/** + * Subscriber interface. + * Will be called when a dependency changes. + */ +Watcher.prototype.update = function update () { + /* istanbul ignore else */ + if (this.lazy) { + this.dirty = true; + } else if (this.sync) { + this.run(); + } else { + queueWatcher(this); + } +}; + +/** + * Scheduler job interface. + * Will be called by the scheduler. + */ +Watcher.prototype.run = function run () { + if (this.active) { + var value = this.get(); + if ( + value !== this.value || + // Deep watchers and watchers on Object/Arrays should fire even + // when the value is the same, because the value may + // have mutated. + isObject(value) || + this.deep + ) { + // set new value + var oldValue = this.value; + this.value = value; + if (this.user) { + try { + this.cb.call(this.vm, value, oldValue); + } catch (e) { + /* istanbul ignore else */ + if (config.errorHandler) { + config.errorHandler.call(null, e, this.vm); + } else { + process.env.NODE_ENV !== 'production' && warn( + ("Error in watcher \"" + (this.expression) + "\""), + this.vm + ); + throw e + } + } + } else { + this.cb.call(this.vm, value, oldValue); + } + } + } +}; + +/** + * Evaluate the value of the watcher. + * This only gets called for lazy watchers. + */ +Watcher.prototype.evaluate = function evaluate () { + this.value = this.get(); + this.dirty = false; +}; + +/** + * Depend on all deps collected by this watcher. + */ +Watcher.prototype.depend = function depend () { + var this$1 = this; + + var i = this.deps.length; + while (i--) { + this$1.deps[i].depend(); + } +}; + +/** + * Remove self from all dependencies' subscriber list. + */ +Watcher.prototype.teardown = function teardown () { + var this$1 = this; + + if (this.active) { + // remove self from vm's watcher list + // this is a somewhat expensive operation so we skip it + // if the vm is being destroyed or is performing a v-for + // re-render (the watcher list is then filtered by v-for). + if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) { + remove$1(this.vm._watchers, this); + } + var i = this.deps.length; + while (i--) { + this$1.deps[i].removeSub(this$1); + } + this.active = false; + } +}; + +/** + * Recursively traverse an object to evoke all converted + * getters, so that every nested property inside the object + * is collected as a "deep" dependency. + */ +var seenObjects = new _Set(); +function traverse (val) { + seenObjects.clear(); + _traverse(val, seenObjects); +} + +function _traverse (val, seen) { + var i, keys; + var isA = Array.isArray(val); + if ((!isA && !isObject(val)) || !Object.isExtensible(val)) { + return + } + if (val.__ob__) { + var depId = val.__ob__.dep.id; + if (seen.has(depId)) { + return + } + seen.add(depId); + } + if (isA) { + i = val.length; + while (i--) { _traverse(val[i], seen); } + } else { + keys = Object.keys(val); + i = keys.length; + while (i--) { _traverse(val[keys[i]], seen); } + } +} + +/* */ + +function initState (vm) { + vm._watchers = []; + initProps(vm); + initMethods(vm); + initData(vm); + initComputed(vm); + initWatch(vm); +} + +var isReservedProp = { key: 1, ref: 1, slot: 1 }; + +function initProps (vm) { + var props = vm.$options.props; + if (props) { + var propsData = vm.$options.propsData || {}; + var keys = vm.$options._propKeys = Object.keys(props); + var isRoot = !vm.$parent; + // root instance props should be converted + observerState.shouldConvert = isRoot; + var loop = function ( i ) { + var key = keys[i]; + /* istanbul ignore else */ + if (process.env.NODE_ENV !== 'production') { + if (isReservedProp[key]) { + warn( + ("\"" + key + "\" is a reserved attribute and cannot be used as component prop."), + vm + ); + } + defineReactive$$1(vm, key, validateProp(key, props, propsData, vm), function () { + if (vm.$parent && !observerState.isSettingProps) { + warn( + "Avoid mutating a prop directly since the value will be " + + "overwritten whenever the parent component re-renders. " + + "Instead, use a data or computed property based on the prop's " + + "value. Prop being mutated: \"" + key + "\"", + vm + ); + } + }); + } else { + defineReactive$$1(vm, key, validateProp(key, props, propsData, vm)); + } + }; + + for (var i = 0; i < keys.length; i++) loop( i ); + observerState.shouldConvert = true; + } +} + +function initData (vm) { + var data = vm.$options.data; + data = vm._data = typeof data === 'function' + ? data.call(vm) + : data || {}; + if (!isPlainObject(data)) { + data = {}; + process.env.NODE_ENV !== 'production' && warn( + 'data functions should return an object:\n' + + 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', + vm + ); + } + // proxy data on instance + var keys = Object.keys(data); + var props = vm.$options.props; + var i = keys.length; + while (i--) { + if (props && hasOwn(props, keys[i])) { + process.env.NODE_ENV !== 'production' && warn( + "The data property \"" + (keys[i]) + "\" is already declared as a prop. " + + "Use prop default value instead.", + vm + ); + } else { + proxy(vm, keys[i]); + } + } + // observe data + observe(data); + data.__ob__ && data.__ob__.vmCount++; +} + +var computedSharedDefinition = { + enumerable: true, + configurable: true, + get: noop, + set: noop +}; + +function initComputed (vm) { + var computed = vm.$options.computed; + if (computed) { + for (var key in computed) { + var userDef = computed[key]; + if (typeof userDef === 'function') { + computedSharedDefinition.get = makeComputedGetter(userDef, vm); + computedSharedDefinition.set = noop; + } else { + computedSharedDefinition.get = userDef.get + ? userDef.cache !== false + ? makeComputedGetter(userDef.get, vm) + : bind$1(userDef.get, vm) + : noop; + computedSharedDefinition.set = userDef.set + ? bind$1(userDef.set, vm) + : noop; + } + Object.defineProperty(vm, key, computedSharedDefinition); + } + } +} + +function makeComputedGetter (getter, owner) { + var watcher = new Watcher(owner, getter, noop, { + lazy: true + }); + return function computedGetter () { + if (watcher.dirty) { + watcher.evaluate(); + } + if (Dep.target) { + watcher.depend(); + } + return watcher.value + } +} + +function initMethods (vm) { + var methods = vm.$options.methods; + if (methods) { + for (var key in methods) { + vm[key] = methods[key] == null ? noop : bind$1(methods[key], vm); + if (process.env.NODE_ENV !== 'production' && methods[key] == null) { + warn( + "method \"" + key + "\" has an undefined value in the component definition. " + + "Did you reference the function correctly?", + vm + ); + } + } + } +} + +function initWatch (vm) { + var watch = vm.$options.watch; + if (watch) { + for (var key in watch) { + var handler = watch[key]; + if (Array.isArray(handler)) { + for (var i = 0; i < handler.length; i++) { + createWatcher(vm, key, handler[i]); + } + } else { + createWatcher(vm, key, handler); + } + } + } +} + +function createWatcher (vm, key, handler) { + var options; + if (isPlainObject(handler)) { + options = handler; + handler = handler.handler; + } + if (typeof handler === 'string') { + handler = vm[handler]; + } + vm.$watch(key, handler, options); +} + +function stateMixin (Vue) { + // flow somehow has problems with directly declared definition object + // when using Object.defineProperty, so we have to procedurally build up + // the object here. + var dataDef = {}; + dataDef.get = function () { + return this._data + }; + if (process.env.NODE_ENV !== 'production') { + dataDef.set = function (newData) { + warn( + 'Avoid replacing instance root $data. ' + + 'Use nested data properties instead.', + this + ); + }; + } + Object.defineProperty(Vue.prototype, '$data', dataDef); + + Vue.prototype.$set = set$1; + Vue.prototype.$delete = del; + + Vue.prototype.$watch = function ( + expOrFn, + cb, + options + ) { + var vm = this; + options = options || {}; + options.user = true; + var watcher = new Watcher(vm, expOrFn, cb, options); + if (options.immediate) { + cb.call(vm, watcher.value); + } + return function unwatchFn () { + watcher.teardown(); + } + }; +} + +function proxy (vm, key) { + if (!isReserved(key)) { + Object.defineProperty(vm, key, { + configurable: true, + enumerable: true, + get: function proxyGetter () { + return vm._data[key] + }, + set: function proxySetter (val) { + vm._data[key] = val; + } + }); + } +} + +/* */ + +var VNode = function VNode ( + tag, + data, + children, + text, + elm, + context, + componentOptions +) { + this.tag = tag; + this.data = data; + this.children = children; + this.text = text; + this.elm = elm; + this.ns = undefined; + this.context = context; + this.functionalContext = undefined; + this.key = data && data.key; + this.componentOptions = componentOptions; + this.child = undefined; + this.parent = undefined; + this.raw = false; + this.isStatic = false; + this.isRootInsert = true; + this.isComment = false; + this.isCloned = false; + this.isOnce = false; +}; + +var createEmptyVNode = function () { + var node = new VNode(); + node.text = ''; + node.isComment = true; + return node +}; + +function createTextVNode (val) { + return new VNode(undefined, undefined, undefined, String(val)) +} + +// optimized shallow clone +// used for static nodes and slot nodes because they may be reused across +// multiple renders, cloning them avoids errors when DOM manipulations rely +// on their elm reference. +function cloneVNode (vnode) { + var cloned = new VNode( + vnode.tag, + vnode.data, + vnode.children, + vnode.text, + vnode.elm, + vnode.context, + vnode.componentOptions + ); + cloned.ns = vnode.ns; + cloned.isStatic = vnode.isStatic; + cloned.key = vnode.key; + cloned.isCloned = true; + return cloned +} + +function cloneVNodes (vnodes) { + var res = new Array(vnodes.length); + for (var i = 0; i < vnodes.length; i++) { + res[i] = cloneVNode(vnodes[i]); + } + return res +} + +/* */ + +var activeInstance = null; + +function initLifecycle (vm) { + var options = vm.$options; + + // locate first non-abstract parent + var parent = options.parent; + if (parent && !options.abstract) { + while (parent.$options.abstract && parent.$parent) { + parent = parent.$parent; + } + parent.$children.push(vm); + } + + vm.$parent = parent; + vm.$root = parent ? parent.$root : vm; + + vm.$children = []; + vm.$refs = {}; + + vm._watcher = null; + vm._inactive = false; + vm._isMounted = false; + vm._isDestroyed = false; + vm._isBeingDestroyed = false; +} + +function lifecycleMixin (Vue) { + Vue.prototype._mount = function ( + el, + hydrating + ) { + var vm = this; + vm.$el = el; + if (!vm.$options.render) { + vm.$options.render = createEmptyVNode; + if (process.env.NODE_ENV !== 'production') { + /* istanbul ignore if */ + if (vm.$options.template && vm.$options.template.charAt(0) !== '#') { + warn( + 'You are using the runtime-only build of Vue where the template ' + + 'option is not available. Either pre-compile the templates into ' + + 'render functions, or use the compiler-included build.', + vm + ); + } else { + warn( + 'Failed to mount component: template or render function not defined.', + vm + ); + } + } + } + callHook(vm, 'beforeMount'); + vm._watcher = new Watcher(vm, function () { + vm._update(vm._render(), hydrating); + }, noop); + hydrating = false; + // manually mounted instance, call mounted on self + // mounted is called for render-created child components in its inserted hook + if (vm.$vnode == null) { + vm._isMounted = true; + callHook(vm, 'mounted'); + } + return vm + }; + + Vue.prototype._update = function (vnode, hydrating) { + var vm = this; + if (vm._isMounted) { + callHook(vm, 'beforeUpdate'); + } + var prevEl = vm.$el; + var prevVnode = vm._vnode; + var prevActiveInstance = activeInstance; + activeInstance = vm; + vm._vnode = vnode; + // Vue.prototype.__patch__ is injected in entry points + // based on the rendering backend used. + if (!prevVnode) { + // initial render + vm.$el = vm.__patch__( + vm.$el, vnode, hydrating, false /* removeOnly */, + vm.$options._parentElm, + vm.$options._refElm + ); + } else { + // updates + vm.$el = vm.__patch__(prevVnode, vnode); + } + activeInstance = prevActiveInstance; + // update __vue__ reference + if (prevEl) { + prevEl.__vue__ = null; + } + if (vm.$el) { + vm.$el.__vue__ = vm; + } + // if parent is an HOC, update its $el as well + if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { + vm.$parent.$el = vm.$el; + } + if (vm._isMounted) { + callHook(vm, 'updated'); + } + }; + + Vue.prototype._updateFromParent = function ( + propsData, + listeners, + parentVnode, + renderChildren + ) { + var vm = this; + var hasChildren = !!(vm.$options._renderChildren || renderChildren); + vm.$options._parentVnode = parentVnode; + vm.$vnode = parentVnode; // update vm's placeholder node without re-render + if (vm._vnode) { // update child tree's parent + vm._vnode.parent = parentVnode; + } + vm.$options._renderChildren = renderChildren; + // update props + if (propsData && vm.$options.props) { + observerState.shouldConvert = false; + if (process.env.NODE_ENV !== 'production') { + observerState.isSettingProps = true; + } + var propKeys = vm.$options._propKeys || []; + for (var i = 0; i < propKeys.length; i++) { + var key = propKeys[i]; + vm[key] = validateProp(key, vm.$options.props, propsData, vm); + } + observerState.shouldConvert = true; + if (process.env.NODE_ENV !== 'production') { + observerState.isSettingProps = false; + } + vm.$options.propsData = propsData; + } + // update listeners + if (listeners) { + var oldListeners = vm.$options._parentListeners; + vm.$options._parentListeners = listeners; + vm._updateListeners(listeners, oldListeners); + } + // resolve slots + force update if has children + if (hasChildren) { + vm.$slots = resolveSlots(renderChildren, parentVnode.context); + vm.$forceUpdate(); + } + }; + + Vue.prototype.$forceUpdate = function () { + var vm = this; + if (vm._watcher) { + vm._watcher.update(); + } + }; + + Vue.prototype.$destroy = function () { + var vm = this; + if (vm._isBeingDestroyed) { + return + } + callHook(vm, 'beforeDestroy'); + vm._isBeingDestroyed = true; + // remove self from parent + var parent = vm.$parent; + if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { + remove$1(parent.$children, vm); + } + // teardown watchers + if (vm._watcher) { + vm._watcher.teardown(); + } + var i = vm._watchers.length; + while (i--) { + vm._watchers[i].teardown(); + } + // remove reference from data ob + // frozen object may not have observer. + if (vm._data.__ob__) { + vm._data.__ob__.vmCount--; + } + // call the last hook... + vm._isDestroyed = true; + callHook(vm, 'destroyed'); + // turn off all instance listeners. + vm.$off(); + // remove __vue__ reference + if (vm.$el) { + vm.$el.__vue__ = null; + } + // invoke destroy hooks on current rendered tree + vm.__patch__(vm._vnode, null); + }; +} + +function callHook (vm, hook) { + var handlers = vm.$options[hook]; + if (handlers) { + for (var i = 0, j = handlers.length; i < j; i++) { + handlers[i].call(vm); + } + } + vm.$emit('hook:' + hook); +} + +/* */ + +var hooks = { init: init, prepatch: prepatch, insert: insert, destroy: destroy$1 }; +var hooksToMerge = Object.keys(hooks); + +function createComponent ( + Ctor, + data, + context, + children, + tag +) { + if (!Ctor) { + return + } + + var baseCtor = context.$options._base; + if (isObject(Ctor)) { + Ctor = baseCtor.extend(Ctor); + } + + if (typeof Ctor !== 'function') { + if (process.env.NODE_ENV !== 'production') { + warn(("Invalid Component definition: " + (String(Ctor))), context); + } + return + } + + // async component + if (!Ctor.cid) { + if (Ctor.resolved) { + Ctor = Ctor.resolved; + } else { + Ctor = resolveAsyncComponent(Ctor, baseCtor, function () { + // it's ok to queue this on every render because + // $forceUpdate is buffered by the scheduler. + context.$forceUpdate(); + }); + if (!Ctor) { + // return nothing if this is indeed an async component + // wait for the callback to trigger parent update. + return + } + } + } + + // resolve constructor options in case global mixins are applied after + // component constructor creation + resolveConstructorOptions(Ctor); + + data = data || {}; + + // extract props + var propsData = extractProps(data, Ctor); + + // functional component + if (Ctor.options.functional) { + return createFunctionalComponent(Ctor, propsData, data, context, children) + } + + // extract listeners, since these needs to be treated as + // child component listeners instead of DOM listeners + var listeners = data.on; + // replace with listeners with .native modifier + data.on = data.nativeOn; + + if (Ctor.options.abstract) { + // abstract components do not keep anything + // other than props & listeners + data = {}; + } + + // merge component management hooks onto the placeholder node + mergeHooks(data); + + // return a placeholder vnode + var name = Ctor.options.name || tag; + var vnode = new VNode( + ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')), + data, undefined, undefined, undefined, context, + { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children } + ); + return vnode +} + +function createFunctionalComponent ( + Ctor, + propsData, + data, + context, + children +) { + var props = {}; + var propOptions = Ctor.options.props; + if (propOptions) { + for (var key in propOptions) { + props[key] = validateProp(key, propOptions, propsData); + } + } + // ensure the createElement function in functional components + // gets a unique context - this is necessary for correct named slot check + var _context = Object.create(context); + var h = function (a, b, c, d) { return createElement(_context, a, b, c, d, true); }; + var vnode = Ctor.options.render.call(null, h, { + props: props, + data: data, + parent: context, + children: children, + slots: function () { return resolveSlots(children, context); } + }); + if (vnode instanceof VNode) { + vnode.functionalContext = context; + if (data.slot) { + (vnode.data || (vnode.data = {})).slot = data.slot; + } + } + return vnode +} + +function createComponentInstanceForVnode ( + vnode, // we know it's MountedComponentVNode but flow doesn't + parent, // activeInstance in lifecycle state + parentElm, + refElm +) { + var vnodeComponentOptions = vnode.componentOptions; + var options = { + _isComponent: true, + parent: parent, + propsData: vnodeComponentOptions.propsData, + _componentTag: vnodeComponentOptions.tag, + _parentVnode: vnode, + _parentListeners: vnodeComponentOptions.listeners, + _renderChildren: vnodeComponentOptions.children, + _parentElm: parentElm || null, + _refElm: refElm || null + }; + // check inline-template render functions + var inlineTemplate = vnode.data.inlineTemplate; + if (inlineTemplate) { + options.render = inlineTemplate.render; + options.staticRenderFns = inlineTemplate.staticRenderFns; + } + return new vnodeComponentOptions.Ctor(options) +} + +function init ( + vnode, + hydrating, + parentElm, + refElm +) { + if (!vnode.child || vnode.child._isDestroyed) { + var child = vnode.child = createComponentInstanceForVnode( + vnode, + activeInstance, + parentElm, + refElm + ); + child.$mount(hydrating ? vnode.elm : undefined, hydrating); + } else if (vnode.data.keepAlive) { + // kept-alive components, treat as a patch + var mountedNode = vnode; // work around flow + prepatch(mountedNode, mountedNode); + } +} + +function prepatch ( + oldVnode, + vnode +) { + var options = vnode.componentOptions; + var child = vnode.child = oldVnode.child; + child._updateFromParent( + options.propsData, // updated props + options.listeners, // updated listeners + vnode, // new parent vnode + options.children // new children + ); +} + +function insert (vnode) { + if (!vnode.child._isMounted) { + vnode.child._isMounted = true; + callHook(vnode.child, 'mounted'); + } + if (vnode.data.keepAlive) { + vnode.child._inactive = false; + callHook(vnode.child, 'activated'); + } +} + +function destroy$1 (vnode) { + if (!vnode.child._isDestroyed) { + if (!vnode.data.keepAlive) { + vnode.child.$destroy(); + } else { + vnode.child._inactive = true; + callHook(vnode.child, 'deactivated'); + } + } +} + +function resolveAsyncComponent ( + factory, + baseCtor, + cb +) { + if (factory.requested) { + // pool callbacks + factory.pendingCallbacks.push(cb); + } else { + factory.requested = true; + var cbs = factory.pendingCallbacks = [cb]; + var sync = true; + + var resolve = function (res) { + if (isObject(res)) { + res = baseCtor.extend(res); + } + // cache resolved + factory.resolved = res; + // invoke callbacks only if this is not a synchronous resolve + // (async resolves are shimmed as synchronous during SSR) + if (!sync) { + for (var i = 0, l = cbs.length; i < l; i++) { + cbs[i](res); + } + } + }; + + var reject = function (reason) { + process.env.NODE_ENV !== 'production' && warn( + "Failed to resolve async component: " + (String(factory)) + + (reason ? ("\nReason: " + reason) : '') + ); + }; + + var res = factory(resolve, reject); + + // handle promise + if (res && typeof res.then === 'function' && !factory.resolved) { + res.then(resolve, reject); + } + + sync = false; + // return in case resolved synchronously + return factory.resolved + } +} + +function extractProps (data, Ctor) { + // we are only extracting raw values here. + // validation and default values are handled in the child + // component itself. + var propOptions = Ctor.options.props; + if (!propOptions) { + return + } + var res = {}; + var attrs = data.attrs; + var props = data.props; + var domProps = data.domProps; + if (attrs || props || domProps) { + for (var key in propOptions) { + var altKey = hyphenate(key); + checkProp(res, props, key, altKey, true) || + checkProp(res, attrs, key, altKey) || + checkProp(res, domProps, key, altKey); + } + } + return res +} + +function checkProp ( + res, + hash, + key, + altKey, + preserve +) { + if (hash) { + if (hasOwn(hash, key)) { + res[key] = hash[key]; + if (!preserve) { + delete hash[key]; + } + return true + } else if (hasOwn(hash, altKey)) { + res[key] = hash[altKey]; + if (!preserve) { + delete hash[altKey]; + } + return true + } + } + return false +} + +function mergeHooks (data) { + if (!data.hook) { + data.hook = {}; + } + for (var i = 0; i < hooksToMerge.length; i++) { + var key = hooksToMerge[i]; + var fromParent = data.hook[key]; + var ours = hooks[key]; + data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours; + } +} + +function mergeHook$1 (one, two) { + return function (a, b, c, d) { + one(a, b, c, d); + two(a, b, c, d); + } +} + +/* */ + +function mergeVNodeHook (def, hookKey, hook, key) { + key = key + hookKey; + var injectedHash = def.__injected || (def.__injected = {}); + if (!injectedHash[key]) { + injectedHash[key] = true; + var oldHook = def[hookKey]; + if (oldHook) { + def[hookKey] = function () { + oldHook.apply(this, arguments); + hook.apply(this, arguments); + }; + } else { + def[hookKey] = hook; + } + } +} + +/* */ + +function updateListeners ( + on, + oldOn, + add, + remove$$1, + vm +) { + var name, cur, old, fn, event, capture, once; + for (name in on) { + cur = on[name]; + old = oldOn[name]; + if (!cur) { + process.env.NODE_ENV !== 'production' && warn( + "Invalid handler for event \"" + name + "\": got " + String(cur), + vm + ); + } else if (!old) { + once = name.charAt(0) === '~'; // Prefixed last, checked first + event = once ? name.slice(1) : name; + capture = event.charAt(0) === '!'; + event = capture ? event.slice(1) : event; + if (Array.isArray(cur)) { + add(event, (cur.invoker = arrInvoker(cur)), once, capture); + } else { + if (!cur.invoker) { + fn = cur; + cur = on[name] = {}; + cur.fn = fn; + cur.invoker = fnInvoker(cur); + } + add(event, cur.invoker, once, capture); + } + } else if (cur !== old) { + if (Array.isArray(old)) { + old.length = cur.length; + for (var i = 0; i < old.length; i++) { old[i] = cur[i]; } + on[name] = old; + } else { + old.fn = cur; + on[name] = old; + } + } + } + for (name in oldOn) { + if (!on[name]) { + once = name.charAt(0) === '~'; // Prefixed last, checked first + event = once ? name.slice(1) : name; + capture = event.charAt(0) === '!'; + event = capture ? event.slice(1) : event; + remove$$1(event, oldOn[name].invoker, capture); + } + } +} + +function arrInvoker (arr) { + return function (ev) { + var arguments$1 = arguments; + + var single = arguments.length === 1; + for (var i = 0; i < arr.length; i++) { + single ? arr[i](ev) : arr[i].apply(null, arguments$1); + } + } +} + +function fnInvoker (o) { + return function (ev) { + var single = arguments.length === 1; + single ? o.fn(ev) : o.fn.apply(null, arguments); + } +} + +/* */ + +function normalizeChildren (children) { + return isPrimitive(children) + ? [createTextVNode(children)] + : Array.isArray(children) + ? normalizeArrayChildren(children) + : undefined +} + +function normalizeArrayChildren (children, nestedIndex) { + var res = []; + var i, c, last; + for (i = 0; i < children.length; i++) { + c = children[i]; + if (c == null || typeof c === 'boolean') { continue } + last = res[res.length - 1]; + // nested + if (Array.isArray(c)) { + res.push.apply(res, normalizeArrayChildren(c, ((nestedIndex || '') + "_" + i))); + } else if (isPrimitive(c)) { + if (last && last.text) { + last.text += String(c); + } else if (c !== '') { + // convert primitive to vnode + res.push(createTextVNode(c)); + } + } else { + if (c.text && last && last.text) { + res[res.length - 1] = createTextVNode(last.text + c.text); + } else { + // default key for nested array children (likely generated by v-for) + if (c.tag && c.key == null && nestedIndex != null) { + c.key = "__vlist" + nestedIndex + "_" + i + "__"; + } + res.push(c); + } + } + } + return res +} + +/* */ + +function getFirstComponentChild (children) { + return children && children.filter(function (c) { return c && c.componentOptions; })[0] +} + +/* */ + +// wrapper function for providing a more flexible interface +// without getting yelled at by flow +function createElement ( + context, + tag, + data, + children, + needNormalization, + alwaysNormalize +) { + if (Array.isArray(data) || isPrimitive(data)) { + needNormalization = children; + children = data; + data = undefined; + } + if (alwaysNormalize) { needNormalization = true; } + return _createElement(context, tag, data, children, needNormalization) +} + +function _createElement ( + context, + tag, + data, + children, + needNormalization +) { + if (data && data.__ob__) { + process.env.NODE_ENV !== 'production' && warn( + "Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" + + 'Always create fresh vnode data objects in each render!', + context + ); + return createEmptyVNode() + } + if (!tag) { + // in case of component :is set to falsy value + return createEmptyVNode() + } + // support single function children as default scoped slot + if (Array.isArray(children) && + typeof children[0] === 'function') { + data = data || {}; + data.scopedSlots = { default: children[0] }; + children.length = 0; + } + if (needNormalization) { + children = normalizeChildren(children); + } + var vnode, ns; + if (typeof tag === 'string') { + var Ctor; + ns = config.getTagNamespace(tag); + if (config.isReservedTag(tag)) { + // platform built-in elements + vnode = new VNode( + config.parsePlatformTagName(tag), data, children, + undefined, undefined, context + ); + } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) { + // component + vnode = createComponent(Ctor, data, context, children, tag); + } else { + // unknown or unlisted namespaced elements + // check at runtime because it may get assigned a namespace when its + // parent normalizes children + ns = tag === 'foreignObject' ? 'xhtml' : ns; + vnode = new VNode( + tag, data, children, + undefined, undefined, context + ); + } + } else { + // direct component options / constructor + vnode = createComponent(tag, data, context, children); + } + if (vnode) { + if (ns) { applyNS(vnode, ns); } + return vnode + } else { + return createEmptyVNode() + } +} + +function applyNS (vnode, ns) { + vnode.ns = ns; + if (vnode.children) { + for (var i = 0, l = vnode.children.length; i < l; i++) { + var child = vnode.children[i]; + if (child.tag && !child.ns) { + applyNS(child, ns); + } + } + } +} + +/* */ + +function initRender (vm) { + vm.$vnode = null; // the placeholder node in parent tree + vm._vnode = null; // the root of the child tree + vm._staticTrees = null; + var parentVnode = vm.$options._parentVnode; + var renderContext = parentVnode && parentVnode.context; + vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext); + vm.$scopedSlots = {}; + // bind the createElement fn to this instance + // so that we get proper render context inside it. + // args order: tag, data, children, needNormalization, alwaysNormalize + // internal version is used by render functions compiled from templates + vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); }; + // normalization is always applied for the public version, used in + // user-written render functions. + vm.$createElement = function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }; + if (vm.$options.el) { + vm.$mount(vm.$options.el); + } +} + +function renderMixin (Vue) { + Vue.prototype.$nextTick = function (fn) { + return nextTick(fn, this) + }; + + Vue.prototype._render = function () { + var vm = this; + var ref = vm.$options; + var render = ref.render; + var staticRenderFns = ref.staticRenderFns; + var _parentVnode = ref._parentVnode; + + if (vm._isMounted) { + // clone slot nodes on re-renders + for (var key in vm.$slots) { + vm.$slots[key] = cloneVNodes(vm.$slots[key]); + } + } + + if (_parentVnode && _parentVnode.data.scopedSlots) { + vm.$scopedSlots = _parentVnode.data.scopedSlots; + } + + if (staticRenderFns && !vm._staticTrees) { + vm._staticTrees = []; + } + // set parent vnode. this allows render functions to have access + // to the data on the placeholder node. + vm.$vnode = _parentVnode; + // render self + var vnode; + try { + vnode = render.call(vm._renderProxy, vm.$createElement); + } catch (e) { + /* istanbul ignore else */ + if (config.errorHandler) { + config.errorHandler.call(null, e, vm); + } else { + if (process.env.NODE_ENV !== 'production') { + warn(("Error when rendering " + (formatComponentName(vm)) + ":")); + } + throw e + } + // return previous vnode to prevent render error causing blank component + vnode = vm._vnode; + } + // return empty vnode in case the render function errored out + if (!(vnode instanceof VNode)) { + if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) { + warn( + 'Multiple root nodes returned from render function. Render function ' + + 'should return a single root node.', + vm + ); + } + vnode = createEmptyVNode(); + } + // set parent + vnode.parent = _parentVnode; + return vnode + }; + + // toString for mustaches + Vue.prototype._s = _toString; + // convert text to vnode + Vue.prototype._v = createTextVNode; + // number conversion + Vue.prototype._n = toNumber; + // empty vnode + Vue.prototype._e = createEmptyVNode; + // loose equal + Vue.prototype._q = looseEqual; + // loose indexOf + Vue.prototype._i = looseIndexOf; + + // render static tree by index + Vue.prototype._m = function renderStatic ( + index, + isInFor + ) { + var tree = this._staticTrees[index]; + // if has already-rendered static tree and not inside v-for, + // we can reuse the same tree by doing a shallow clone. + if (tree && !isInFor) { + return Array.isArray(tree) + ? cloneVNodes(tree) + : cloneVNode(tree) + } + // otherwise, render a fresh tree. + tree = this._staticTrees[index] = this.$options.staticRenderFns[index].call(this._renderProxy); + markStatic(tree, ("__static__" + index), false); + return tree + }; + + // mark node as static (v-once) + Vue.prototype._o = function markOnce ( + tree, + index, + key + ) { + markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true); + return tree + }; + + function markStatic (tree, key, isOnce) { + if (Array.isArray(tree)) { + for (var i = 0; i < tree.length; i++) { + if (tree[i] && typeof tree[i] !== 'string') { + markStaticNode(tree[i], (key + "_" + i), isOnce); + } + } + } else { + markStaticNode(tree, key, isOnce); + } + } + + function markStaticNode (node, key, isOnce) { + node.isStatic = true; + node.key = key; + node.isOnce = isOnce; + } + + // filter resolution helper + Vue.prototype._f = function resolveFilter (id) { + return resolveAsset(this.$options, 'filters', id, true) || identity + }; + + // render v-for + Vue.prototype._l = function renderList ( + val, + render + ) { + var ret, i, l, keys, key; + if (Array.isArray(val)) { + ret = new Array(val.length); + for (i = 0, l = val.length; i < l; i++) { + ret[i] = render(val[i], i); + } + } else if (typeof val === 'number') { + ret = new Array(val); + for (i = 0; i < val; i++) { + ret[i] = render(i + 1, i); + } + } else if (isObject(val)) { + keys = Object.keys(val); + ret = new Array(keys.length); + for (i = 0, l = keys.length; i < l; i++) { + key = keys[i]; + ret[i] = render(val[key], key, i); + } + } + return ret + }; + + // renderSlot + Vue.prototype._t = function ( + name, + fallback, + props + ) { + var scopedSlotFn = this.$scopedSlots[name]; + if (scopedSlotFn) { // scoped slot + return scopedSlotFn(props || {}) || fallback + } else { + var slotNodes = this.$slots[name]; + // warn duplicate slot usage + if (slotNodes && process.env.NODE_ENV !== 'production') { + slotNodes._rendered && warn( + "Duplicate presence of slot \"" + name + "\" found in the same render tree " + + "- this will likely cause render errors.", + this + ); + slotNodes._rendered = true; + } + return slotNodes || fallback + } + }; + + // apply v-bind object + Vue.prototype._b = function bindProps ( + data, + tag, + value, + asProp + ) { + if (value) { + if (!isObject(value)) { + process.env.NODE_ENV !== 'production' && warn( + 'v-bind without argument expects an Object or Array value', + this + ); + } else { + if (Array.isArray(value)) { + value = toObject(value); + } + for (var key in value) { + if (key === 'class' || key === 'style') { + data[key] = value[key]; + } else { + var hash = asProp || config.mustUseProp(tag, key) + ? data.domProps || (data.domProps = {}) + : data.attrs || (data.attrs = {}); + hash[key] = value[key]; + } + } + } + } + return data + }; + + // check v-on keyCodes + Vue.prototype._k = function checkKeyCodes ( + eventKeyCode, + key, + builtInAlias + ) { + var keyCodes = config.keyCodes[key] || builtInAlias; + if (Array.isArray(keyCodes)) { + return keyCodes.indexOf(eventKeyCode) === -1 + } else { + return keyCodes !== eventKeyCode + } + }; +} + +function resolveSlots ( + children, + context +) { + var slots = {}; + if (!children) { + return slots + } + var defaultSlot = []; + var name, child; + for (var i = 0, l = children.length; i < l; i++) { + child = children[i]; + // named slots should only be respected if the vnode was rendered in the + // same context. + if ((child.context === context || child.functionalContext === context) && + child.data && (name = child.data.slot)) { + var slot = (slots[name] || (slots[name] = [])); + if (child.tag === 'template') { + slot.push.apply(slot, child.children); + } else { + slot.push(child); + } + } else { + defaultSlot.push(child); + } + } + // ignore single whitespace + if (defaultSlot.length && !( + defaultSlot.length === 1 && + (defaultSlot[0].text === ' ' || defaultSlot[0].isComment) + )) { + slots.default = defaultSlot; + } + return slots +} + +/* */ + +function initEvents (vm) { + vm._events = Object.create(null); + // init parent attached events + var listeners = vm.$options._parentListeners; + var add = function (event, fn, once) { + once ? vm.$once(event, fn) : vm.$on(event, fn); + }; + var remove$$1 = bind$1(vm.$off, vm); + vm._updateListeners = function (listeners, oldListeners) { + updateListeners(listeners, oldListeners || {}, add, remove$$1, vm); + }; + if (listeners) { + vm._updateListeners(listeners); + } +} + +function eventsMixin (Vue) { + Vue.prototype.$on = function (event, fn) { + var vm = this;(vm._events[event] || (vm._events[event] = [])).push(fn); + return vm + }; + + Vue.prototype.$once = function (event, fn) { + var vm = this; + function on () { + vm.$off(event, on); + fn.apply(vm, arguments); + } + on.fn = fn; + vm.$on(event, on); + return vm + }; + + Vue.prototype.$off = function (event, fn) { + var vm = this; + // all + if (!arguments.length) { + vm._events = Object.create(null); + return vm + } + // specific event + var cbs = vm._events[event]; + if (!cbs) { + return vm + } + if (arguments.length === 1) { + vm._events[event] = null; + return vm + } + // specific handler + var cb; + var i = cbs.length; + while (i--) { + cb = cbs[i]; + if (cb === fn || cb.fn === fn) { + cbs.splice(i, 1); + break + } + } + return vm + }; + + Vue.prototype.$emit = function (event) { + var vm = this; + var cbs = vm._events[event]; + if (cbs) { + cbs = cbs.length > 1 ? toArray(cbs) : cbs; + var args = toArray(arguments, 1); + for (var i = 0, l = cbs.length; i < l; i++) { + cbs[i].apply(vm, args); + } + } + return vm + }; +} + +/* */ + +var uid = 0; + +function initMixin (Vue) { + Vue.prototype._init = function (options) { + var vm = this; + // a uid + vm._uid = uid++; + // a flag to avoid this being observed + vm._isVue = true; + // merge options + if (options && options._isComponent) { + // optimize internal component instantiation + // since dynamic options merging is pretty slow, and none of the + // internal component options needs special treatment. + initInternalComponent(vm, options); + } else { + vm.$options = mergeOptions( + resolveConstructorOptions(vm.constructor), + options || {}, + vm + ); + } + /* istanbul ignore else */ + if (process.env.NODE_ENV !== 'production') { + initProxy(vm); + } else { + vm._renderProxy = vm; + } + // expose real self + vm._self = vm; + initLifecycle(vm); + initEvents(vm); + callHook(vm, 'beforeCreate'); + initState(vm); + callHook(vm, 'created'); + initRender(vm); + }; +} + +function initInternalComponent (vm, options) { + var opts = vm.$options = Object.create(vm.constructor.options); + // doing this because it's faster than dynamic enumeration. + opts.parent = options.parent; + opts.propsData = options.propsData; + opts._parentVnode = options._parentVnode; + opts._parentListeners = options._parentListeners; + opts._renderChildren = options._renderChildren; + opts._componentTag = options._componentTag; + opts._parentElm = options._parentElm; + opts._refElm = options._refElm; + if (options.render) { + opts.render = options.render; + opts.staticRenderFns = options.staticRenderFns; + } +} + +function resolveConstructorOptions (Ctor) { + var options = Ctor.options; + if (Ctor.super) { + var superOptions = Ctor.super.options; + var cachedSuperOptions = Ctor.superOptions; + var extendOptions = Ctor.extendOptions; + if (superOptions !== cachedSuperOptions) { + // super option changed + Ctor.superOptions = superOptions; + extendOptions.render = options.render; + extendOptions.staticRenderFns = options.staticRenderFns; + extendOptions._scopeId = options._scopeId; + options = Ctor.options = mergeOptions(superOptions, extendOptions); + if (options.name) { + options.components[options.name] = Ctor; + } + } + } + return options +} + +function Vue$3 (options) { + if (process.env.NODE_ENV !== 'production' && + !(this instanceof Vue$3)) { + warn('Vue is a constructor and should be called with the `new` keyword'); + } + this._init(options); +} + +initMixin(Vue$3); +stateMixin(Vue$3); +eventsMixin(Vue$3); +lifecycleMixin(Vue$3); +renderMixin(Vue$3); + +/* */ + +function initUse (Vue) { + Vue.use = function (plugin) { + /* istanbul ignore if */ + if (plugin.installed) { + return + } + // additional parameters + var args = toArray(arguments, 1); + args.unshift(this); + if (typeof plugin.install === 'function') { + plugin.install.apply(plugin, args); + } else { + plugin.apply(null, args); + } + plugin.installed = true; + return this + }; +} + +/* */ + +function initMixin$1 (Vue) { + Vue.mixin = function (mixin) { + this.options = mergeOptions(this.options, mixin); + }; +} + +/* */ + +function initExtend (Vue) { + /** + * Each instance constructor, including Vue, has a unique + * cid. This enables us to create wrapped "child + * constructors" for prototypal inheritance and cache them. + */ + Vue.cid = 0; + var cid = 1; + + /** + * Class inheritance + */ + Vue.extend = function (extendOptions) { + extendOptions = extendOptions || {}; + var Super = this; + var SuperId = Super.cid; + var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); + if (cachedCtors[SuperId]) { + return cachedCtors[SuperId] + } + var name = extendOptions.name || Super.options.name; + if (process.env.NODE_ENV !== 'production') { + if (!/^[a-zA-Z][\w-]*$/.test(name)) { + warn( + 'Invalid component name: "' + name + '". Component names ' + + 'can only contain alphanumeric characters and the hyphen, ' + + 'and must start with a letter.' + ); + } + } + var Sub = function VueComponent (options) { + this._init(options); + }; + Sub.prototype = Object.create(Super.prototype); + Sub.prototype.constructor = Sub; + Sub.cid = cid++; + Sub.options = mergeOptions( + Super.options, + extendOptions + ); + Sub['super'] = Super; + // allow further extension/mixin/plugin usage + Sub.extend = Super.extend; + Sub.mixin = Super.mixin; + Sub.use = Super.use; + // create asset registers, so extended classes + // can have their private assets too. + config._assetTypes.forEach(function (type) { + Sub[type] = Super[type]; + }); + // enable recursive self-lookup + if (name) { + Sub.options.components[name] = Sub; + } + // keep a reference to the super options at extension time. + // later at instantiation we can check if Super's options have + // been updated. + Sub.superOptions = Super.options; + Sub.extendOptions = extendOptions; + // cache constructor + cachedCtors[SuperId] = Sub; + return Sub + }; +} + +/* */ + +function initAssetRegisters (Vue) { + /** + * Create asset registration methods. + */ + config._assetTypes.forEach(function (type) { + Vue[type] = function ( + id, + definition + ) { + if (!definition) { + return this.options[type + 's'][id] + } else { + /* istanbul ignore if */ + if (process.env.NODE_ENV !== 'production') { + if (type === 'component' && config.isReservedTag(id)) { + warn( + 'Do not use built-in or reserved HTML elements as component ' + + 'id: ' + id + ); + } + } + if (type === 'component' && isPlainObject(definition)) { + definition.name = definition.name || id; + definition = this.options._base.extend(definition); + } + if (type === 'directive' && typeof definition === 'function') { + definition = { bind: definition, update: definition }; + } + this.options[type + 's'][id] = definition; + return definition + } + }; + }); +} + +/* */ + +var patternTypes = [String, RegExp]; + +function matches (pattern, name) { + if (typeof pattern === 'string') { + return pattern.split(',').indexOf(name) > -1 + } else { + return pattern.test(name) + } +} + +var KeepAlive = { + name: 'keep-alive', + abstract: true, + props: { + include: patternTypes, + exclude: patternTypes + }, + created: function created () { + this.cache = Object.create(null); + }, + render: function render () { + var vnode = getFirstComponentChild(this.$slots.default); + if (vnode && vnode.componentOptions) { + var opts = vnode.componentOptions; + // check pattern + var name = opts.Ctor.options.name || opts.tag; + if (name && ( + (this.include && !matches(this.include, name)) || + (this.exclude && matches(this.exclude, name)) + )) { + return vnode + } + var key = vnode.key == null + // same constructor may get registered as different local components + // so cid alone is not enough (#3269) + ? opts.Ctor.cid + (opts.tag ? ("::" + (opts.tag)) : '') + : vnode.key; + if (this.cache[key]) { + vnode.child = this.cache[key].child; + } else { + this.cache[key] = vnode; + } + vnode.data.keepAlive = true; + } + return vnode + }, + destroyed: function destroyed () { + var this$1 = this; + + for (var key in this.cache) { + var vnode = this$1.cache[key]; + callHook(vnode.child, 'deactivated'); + vnode.child.$destroy(); + } + } +}; + +var builtInComponents = { + KeepAlive: KeepAlive +}; + +/* */ + +function initGlobalAPI (Vue) { + // config + var configDef = {}; + configDef.get = function () { return config; }; + if (process.env.NODE_ENV !== 'production') { + configDef.set = function () { + warn( + 'Do not replace the Vue.config object, set individual fields instead.' + ); + }; + } + Object.defineProperty(Vue, 'config', configDef); + Vue.util = util; + Vue.set = set$1; + Vue.delete = del; + Vue.nextTick = nextTick; + + Vue.options = Object.create(null); + config._assetTypes.forEach(function (type) { + Vue.options[type + 's'] = Object.create(null); + }); + + // this is used to identify the "base" constructor to extend all plain-object + // components with in Weex's multi-instance scenarios. + Vue.options._base = Vue; + + extend(Vue.options.components, builtInComponents); + + initUse(Vue); + initMixin$1(Vue); + initExtend(Vue); + initAssetRegisters(Vue); +} + +initGlobalAPI(Vue$3); + +Object.defineProperty(Vue$3.prototype, '$isServer', { + get: isServerRendering +}); + +Vue$3.version = '2.1.6'; + +/* */ + +// attributes that should be using props for binding +var acceptValue = makeMap('input,textarea,option,select'); +var mustUseProp = function (tag, attr) { + return ( + (attr === 'value' && acceptValue(tag)) || + (attr === 'selected' && tag === 'option') || + (attr === 'checked' && tag === 'input') || + (attr === 'muted' && tag === 'video') + ) +}; + +var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck'); + +var isBooleanAttr = makeMap( + 'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' + + 'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' + + 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' + + 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' + + 'required,reversed,scoped,seamless,selected,sortable,translate,' + + 'truespeed,typemustmatch,visible' +); + +var xlinkNS = 'http://www.w3.org/1999/xlink'; + +var isXlink = function (name) { + return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' +}; + +var getXlinkProp = function (name) { + return isXlink(name) ? name.slice(6, name.length) : '' +}; + +var isFalsyAttrValue = function (val) { + return val == null || val === false +}; + +/* */ + +function genClassForVnode (vnode) { + var data = vnode.data; + var parentNode = vnode; + var childNode = vnode; + while (childNode.child) { + childNode = childNode.child._vnode; + if (childNode.data) { + data = mergeClassData(childNode.data, data); + } + } + while ((parentNode = parentNode.parent)) { + if (parentNode.data) { + data = mergeClassData(data, parentNode.data); + } + } + return genClassFromData(data) +} + +function mergeClassData (child, parent) { + return { + staticClass: concat(child.staticClass, parent.staticClass), + class: child.class + ? [child.class, parent.class] + : parent.class + } +} + +function genClassFromData (data) { + var dynamicClass = data.class; + var staticClass = data.staticClass; + if (staticClass || dynamicClass) { + return concat(staticClass, stringifyClass(dynamicClass)) + } + /* istanbul ignore next */ + return '' +} + +function concat (a, b) { + return a ? b ? (a + ' ' + b) : a : (b || '') +} + +function stringifyClass (value) { + var res = ''; + if (!value) { + return res + } + if (typeof value === 'string') { + return value + } + if (Array.isArray(value)) { + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (value[i]) { + if ((stringified = stringifyClass(value[i]))) { + res += stringified + ' '; + } + } + } + return res.slice(0, -1) + } + if (isObject(value)) { + for (var key in value) { + if (value[key]) { res += key + ' '; } + } + return res.slice(0, -1) + } + /* istanbul ignore next */ + return res +} + +/* */ + +var namespaceMap = { + svg: 'http://www.w3.org/2000/svg', + math: 'http://www.w3.org/1998/Math/MathML', + xhtml: 'http://www.w3.org/1999/xhtml' +}; + +var isHTMLTag = makeMap( + 'html,body,base,head,link,meta,style,title,' + + 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + + 'div,dd,dl,dt,figcaption,figure,hr,img,li,main,ol,p,pre,ul,' + + 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + + 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + + 'embed,object,param,source,canvas,script,noscript,del,ins,' + + 'caption,col,colgroup,table,thead,tbody,td,th,tr,' + + 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + + 'output,progress,select,textarea,' + + 'details,dialog,menu,menuitem,summary,' + + 'content,element,shadow,template' +); + +// this map is intentionally selective, only covering SVG elements that may +// contain child elements. +var isSVG = makeMap( + 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,' + + 'font-face,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + + 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', + true +); + +var isPreTag = function (tag) { return tag === 'pre'; }; + +var isReservedTag = function (tag) { + return isHTMLTag(tag) || isSVG(tag) +}; + +function getTagNamespace (tag) { + if (isSVG(tag)) { + return 'svg' + } + // basic support for MathML + // note it doesn't support other MathML elements being component roots + if (tag === 'math') { + return 'math' + } +} + +var unknownElementCache = Object.create(null); +function isUnknownElement (tag) { + /* istanbul ignore if */ + if (!inBrowser) { + return true + } + if (isReservedTag(tag)) { + return false + } + tag = tag.toLowerCase(); + /* istanbul ignore if */ + if (unknownElementCache[tag] != null) { + return unknownElementCache[tag] + } + var el = document.createElement(tag); + if (tag.indexOf('-') > -1) { + // http://stackoverflow.com/a/28210364/1070244 + return (unknownElementCache[tag] = ( + el.constructor === window.HTMLUnknownElement || + el.constructor === window.HTMLElement + )) + } else { + return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString())) + } +} + +/* */ + +/** + * Query an element selector if it's not an element already. + */ +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 document.createElement('div') + } + } + return el +} + +/* */ + +function createElement$1 (tagName, vnode) { + var elm = document.createElement(tagName); + if (tagName !== 'select') { + return elm + } + if (vnode.data && vnode.data.attrs && 'multiple' in vnode.data.attrs) { + elm.setAttribute('multiple', 'multiple'); + } + return elm +} + +function createElementNS (namespace, tagName) { + return document.createElementNS(namespaceMap[namespace], tagName) +} + +function createTextNode (text) { + return document.createTextNode(text) +} + +function createComment (text) { + return document.createComment(text) +} + +function insertBefore (parentNode, newNode, referenceNode) { + parentNode.insertBefore(newNode, referenceNode); +} + +function removeChild (node, child) { + node.removeChild(child); +} + +function appendChild (node, child) { + node.appendChild(child); +} + +function parentNode (node) { + return node.parentNode +} + +function nextSibling (node) { + return node.nextSibling +} + +function tagName (node) { + return node.tagName +} + +function setTextContent (node, text) { + node.textContent = text; +} + +function setAttribute (node, key, val) { + node.setAttribute(key, val); +} + + +var nodeOps = Object.freeze({ + createElement: createElement$1, + createElementNS: createElementNS, + createTextNode: createTextNode, + createComment: createComment, + insertBefore: insertBefore, + removeChild: removeChild, + appendChild: appendChild, + parentNode: parentNode, + nextSibling: nextSibling, + tagName: tagName, + setTextContent: setTextContent, + setAttribute: setAttribute +}); + +/* */ + +var ref = { + create: function create (_, vnode) { + registerRef(vnode); + }, + update: function update (oldVnode, vnode) { + if (oldVnode.data.ref !== vnode.data.ref) { + registerRef(oldVnode, true); + registerRef(vnode); + } + }, + destroy: function destroy (vnode) { + registerRef(vnode, true); + } +}; + +function registerRef (vnode, isRemoval) { + var key = vnode.data.ref; + if (!key) { return } + + var vm = vnode.context; + var ref = vnode.child || vnode.elm; + var refs = vm.$refs; + if (isRemoval) { + if (Array.isArray(refs[key])) { + remove$1(refs[key], ref); + } else if (refs[key] === ref) { + refs[key] = undefined; + } + } else { + if (vnode.data.refInFor) { + if (Array.isArray(refs[key]) && refs[key].indexOf(ref) < 0) { + refs[key].push(ref); + } else { + refs[key] = [ref]; + } + } else { + refs[key] = ref; + } + } +} + +/** + * Virtual DOM patching algorithm based on Snabbdom by + * Simon Friis Vindum (@paldepind) + * Licensed under the MIT License + * https://github.com/paldepind/snabbdom/blob/master/LICENSE + * + * modified by Evan You (@yyx990803) + * + +/* + * Not type-checking this because this file is perf-critical and the cost + * of making flow understand it is not worth it. + */ + +var emptyNode = new VNode('', {}, []); + +var hooks$1 = ['create', 'activate', 'update', 'remove', 'destroy']; + +function isUndef (s) { + return s == null +} + +function isDef (s) { + return s != null +} + +function sameVnode (vnode1, vnode2) { + return ( + vnode1.key === vnode2.key && + vnode1.tag === vnode2.tag && + vnode1.isComment === vnode2.isComment && + !vnode1.data === !vnode2.data + ) +} + +function createKeyToOldIdx (children, beginIdx, endIdx) { + var i, key; + var map = {}; + for (i = beginIdx; i <= endIdx; ++i) { + key = children[i].key; + if (isDef(key)) { map[key] = i; } + } + return map +} + +function createPatchFunction (backend) { + var i, j; + var cbs = {}; + + var modules = backend.modules; + var nodeOps = backend.nodeOps; + + for (i = 0; i < hooks$1.length; ++i) { + cbs[hooks$1[i]] = []; + for (j = 0; j < modules.length; ++j) { + if (modules[j][hooks$1[i]] !== undefined) { cbs[hooks$1[i]].push(modules[j][hooks$1[i]]); } + } + } + + function emptyNodeAt (elm) { + return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm) + } + + function createRmCb (childElm, listeners) { + function remove$$1 () { + if (--remove$$1.listeners === 0) { + removeElement(childElm); + } + } + remove$$1.listeners = listeners; + return remove$$1 + } + + function removeElement (el) { + var parent = nodeOps.parentNode(el); + // element may have already been removed due to v-html + if (parent) { + nodeOps.removeChild(parent, el); + } + } + + var inPre = 0; + function createElm (vnode, insertedVnodeQueue, parentElm, refElm, nested) { + vnode.isRootInsert = !nested; // for transition enter check + if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { + return + } + + var data = vnode.data; + var children = vnode.children; + var tag = vnode.tag; + if (isDef(tag)) { + if (process.env.NODE_ENV !== 'production') { + if (data && data.pre) { + inPre++; + } + if ( + !inPre && + !vnode.ns && + !(config.ignoredElements && config.ignoredElements.indexOf(tag) > -1) && + config.isUnknownElement(tag) + ) { + warn( + 'Unknown custom element: <' + tag + '> - did you ' + + 'register the component correctly? For recursive components, ' + + 'make sure to provide the "name" option.', + vnode.context + ); + } + } + vnode.elm = vnode.ns + ? nodeOps.createElementNS(vnode.ns, tag) + : nodeOps.createElement(tag, vnode); + setScope(vnode); + + /* istanbul ignore if */ + { + createChildren(vnode, children, insertedVnodeQueue); + if (isDef(data)) { + invokeCreateHooks(vnode, insertedVnodeQueue); + } + insert(parentElm, vnode.elm, refElm); + } + + if (process.env.NODE_ENV !== 'production' && data && data.pre) { + inPre--; + } + } else if (vnode.isComment) { + vnode.elm = nodeOps.createComment(vnode.text); + insert(parentElm, vnode.elm, refElm); + } else { + vnode.elm = nodeOps.createTextNode(vnode.text); + insert(parentElm, vnode.elm, refElm); + } + } + + function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) { + var i = vnode.data; + if (isDef(i)) { + var isReactivated = isDef(vnode.child) && i.keepAlive; + if (isDef(i = i.hook) && isDef(i = i.init)) { + i(vnode, false /* hydrating */, parentElm, refElm); + } + // after calling the init hook, if the vnode is a child component + // it should've created a child instance and mounted it. the child + // component also has set the placeholder vnode's elm. + // in that case we can just return the element and be done. + if (isDef(vnode.child)) { + initComponent(vnode, insertedVnodeQueue); + if (isReactivated) { + reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm); + } + return true + } + } + } + + function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) { + var i; + // hack for #4339: a reactivated component with inner transition + // does not trigger because the inner node's created hooks are not called + // again. It's not ideal to involve module-specific logic in here but + // there doesn't seem to be a better way to do it. + var innerNode = vnode; + while (innerNode.child) { + innerNode = innerNode.child._vnode; + if (isDef(i = innerNode.data) && isDef(i = i.transition)) { + for (i = 0; i < cbs.activate.length; ++i) { + cbs.activate[i](emptyNode, innerNode); + } + insertedVnodeQueue.push(innerNode); + break + } + } + // unlike a newly created component, + // a reactivated keep-alive component doesn't insert itself + insert(parentElm, vnode.elm, refElm); + } + + function insert (parent, elm, ref) { + if (parent) { + if (ref) { + nodeOps.insertBefore(parent, elm, ref); + } else { + nodeOps.appendChild(parent, elm); + } + } + } + + function createChildren (vnode, children, insertedVnodeQueue) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; ++i) { + createElm(children[i], insertedVnodeQueue, vnode.elm, null, true); + } + } else if (isPrimitive(vnode.text)) { + nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(vnode.text)); + } + } + + function isPatchable (vnode) { + while (vnode.child) { + vnode = vnode.child._vnode; + } + return isDef(vnode.tag) + } + + function invokeCreateHooks (vnode, insertedVnodeQueue) { + for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) { + cbs.create[i$1](emptyNode, vnode); + } + i = vnode.data.hook; // Reuse variable + if (isDef(i)) { + if (i.create) { i.create(emptyNode, vnode); } + if (i.insert) { insertedVnodeQueue.push(vnode); } + } + } + + function initComponent (vnode, insertedVnodeQueue) { + if (vnode.data.pendingInsert) { + insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert); + } + vnode.elm = vnode.child.$el; + if (isPatchable(vnode)) { + invokeCreateHooks(vnode, insertedVnodeQueue); + setScope(vnode); + } else { + // empty component root. + // skip all element-related modules except for ref (#3455) + registerRef(vnode); + // make sure to invoke the insert hook + insertedVnodeQueue.push(vnode); + } + } + + // set scope id attribute for scoped CSS. + // this is implemented as a special case to avoid the overhead + // of going through the normal attribute patching process. + function setScope (vnode) { + var i; + if (isDef(i = vnode.context) && isDef(i = i.$options._scopeId)) { + nodeOps.setAttribute(vnode.elm, i, ''); + } + if (isDef(i = activeInstance) && + i !== vnode.context && + isDef(i = i.$options._scopeId)) { + nodeOps.setAttribute(vnode.elm, i, ''); + } + } + + function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) { + for (; startIdx <= endIdx; ++startIdx) { + createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm); + } + } + + function invokeDestroyHook (vnode) { + var i, j; + var data = vnode.data; + if (isDef(data)) { + if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); } + for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); } + } + if (isDef(i = vnode.children)) { + for (j = 0; j < vnode.children.length; ++j) { + invokeDestroyHook(vnode.children[j]); + } + } + } + + function removeVnodes (parentElm, vnodes, startIdx, endIdx) { + for (; startIdx <= endIdx; ++startIdx) { + var ch = vnodes[startIdx]; + if (isDef(ch)) { + if (isDef(ch.tag)) { + removeAndInvokeRemoveHook(ch); + invokeDestroyHook(ch); + } else { // Text node + nodeOps.removeChild(parentElm, ch.elm); + } + } + } + } + + function removeAndInvokeRemoveHook (vnode, rm) { + if (rm || isDef(vnode.data)) { + var listeners = cbs.remove.length + 1; + if (!rm) { + // directly removing + rm = createRmCb(vnode.elm, listeners); + } else { + // we have a recursively passed down rm callback + // increase the listeners count + rm.listeners += listeners; + } + // recursively invoke hooks on child component root node + if (isDef(i = vnode.child) && isDef(i = i._vnode) && isDef(i.data)) { + removeAndInvokeRemoveHook(i, rm); + } + for (i = 0; i < cbs.remove.length; ++i) { + cbs.remove[i](vnode, rm); + } + if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) { + i(vnode, rm); + } else { + rm(); + } + } else { + removeElement(vnode.elm); + } + } + + function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) { + var oldStartIdx = 0; + var newStartIdx = 0; + var oldEndIdx = oldCh.length - 1; + var oldStartVnode = oldCh[0]; + var oldEndVnode = oldCh[oldEndIdx]; + var newEndIdx = newCh.length - 1; + var newStartVnode = newCh[0]; + var newEndVnode = newCh[newEndIdx]; + var oldKeyToIdx, idxInOld, elmToMove, refElm; + + // removeOnly is a special flag used only by + // to ensure removed elements stay in correct relative positions + // during leaving transitions + var canMove = !removeOnly; + + while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { + if (isUndef(oldStartVnode)) { + oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left + } else if (isUndef(oldEndVnode)) { + oldEndVnode = oldCh[--oldEndIdx]; + } else if (sameVnode(oldStartVnode, newStartVnode)) { + patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); + oldStartVnode = oldCh[++oldStartIdx]; + newStartVnode = newCh[++newStartIdx]; + } else if (sameVnode(oldEndVnode, newEndVnode)) { + patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue); + oldEndVnode = oldCh[--oldEndIdx]; + newEndVnode = newCh[--newEndIdx]; + } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right + patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue); + canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm)); + oldStartVnode = oldCh[++oldStartIdx]; + newEndVnode = newCh[--newEndIdx]; + } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left + patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue); + canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); + oldEndVnode = oldCh[--oldEndIdx]; + newStartVnode = newCh[++newStartIdx]; + } else { + if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); } + idxInOld = isDef(newStartVnode.key) ? oldKeyToIdx[newStartVnode.key] : null; + if (isUndef(idxInOld)) { // New element + createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm); + newStartVnode = newCh[++newStartIdx]; + } else { + elmToMove = oldCh[idxInOld]; + /* istanbul ignore if */ + if (process.env.NODE_ENV !== 'production' && !elmToMove) { + warn( + 'It seems there are duplicate keys that is causing an update error. ' + + 'Make sure each v-for item has a unique key.' + ); + } + if (sameVnode(elmToMove, newStartVnode)) { + patchVnode(elmToMove, newStartVnode, insertedVnodeQueue); + oldCh[idxInOld] = undefined; + canMove && nodeOps.insertBefore(parentElm, newStartVnode.elm, oldStartVnode.elm); + newStartVnode = newCh[++newStartIdx]; + } else { + // same key but different element. treat as new element + createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm); + newStartVnode = newCh[++newStartIdx]; + } + } + } + } + if (oldStartIdx > oldEndIdx) { + refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm; + addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue); + } else if (newStartIdx > newEndIdx) { + removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); + } + } + + function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) { + if (oldVnode === vnode) { + return + } + // reuse element for static trees. + // note we only do this if the vnode is cloned - + // if the new node is not cloned it means the render functions have been + // reset by the hot-reload-api and we need to do a proper re-render. + if (vnode.isStatic && + oldVnode.isStatic && + vnode.key === oldVnode.key && + (vnode.isCloned || vnode.isOnce)) { + vnode.elm = oldVnode.elm; + vnode.child = oldVnode.child; + return + } + var i; + var data = vnode.data; + var hasData = isDef(data); + if (hasData && isDef(i = data.hook) && isDef(i = i.prepatch)) { + i(oldVnode, vnode); + } + var elm = vnode.elm = oldVnode.elm; + var oldCh = oldVnode.children; + var ch = vnode.children; + if (hasData && isPatchable(vnode)) { + for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); } + if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); } + } + if (isUndef(vnode.text)) { + if (isDef(oldCh) && isDef(ch)) { + if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); } + } else if (isDef(ch)) { + if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); } + addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); + } else if (isDef(oldCh)) { + removeVnodes(elm, oldCh, 0, oldCh.length - 1); + } else if (isDef(oldVnode.text)) { + nodeOps.setTextContent(elm, ''); + } + } else if (oldVnode.text !== vnode.text) { + nodeOps.setTextContent(elm, vnode.text); + } + if (hasData) { + if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); } + } + } + + function invokeInsertHook (vnode, queue, initial) { + // delay insert hooks for component root nodes, invoke them after the + // element is really inserted + if (initial && vnode.parent) { + vnode.parent.data.pendingInsert = queue; + } else { + for (var i = 0; i < queue.length; ++i) { + queue[i].data.hook.insert(queue[i]); + } + } + } + + var bailed = false; + // list of modules that can skip create hook during hydration because they + // are already rendered on the client or has no need for initialization + var isRenderedModule = makeMap('attrs,style,class,staticClass,staticStyle,key'); + + // Note: this is a browser-only function so we can assume elms are DOM nodes. + function hydrate (elm, vnode, insertedVnodeQueue) { + if (process.env.NODE_ENV !== 'production') { + if (!assertNodeMatch(elm, vnode)) { + return false + } + } + vnode.elm = elm; + var tag = vnode.tag; + var data = vnode.data; + var children = vnode.children; + if (isDef(data)) { + if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); } + if (isDef(i = vnode.child)) { + // child component. it should have hydrated its own tree. + initComponent(vnode, insertedVnodeQueue); + return true + } + } + if (isDef(tag)) { + if (isDef(children)) { + // empty element, allow client to pick up and populate children + if (!elm.hasChildNodes()) { + createChildren(vnode, children, insertedVnodeQueue); + } else { + var childrenMatch = true; + var childNode = elm.firstChild; + for (var i$1 = 0; i$1 < children.length; i$1++) { + if (!childNode || !hydrate(childNode, children[i$1], insertedVnodeQueue)) { + childrenMatch = false; + break + } + childNode = childNode.nextSibling; + } + // if childNode is not null, it means the actual childNodes list is + // longer than the virtual children list. + if (!childrenMatch || childNode) { + if (process.env.NODE_ENV !== 'production' && + typeof console !== 'undefined' && + !bailed) { + bailed = true; + console.warn('Parent: ', elm); + console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children); + } + return false + } + } + } + if (isDef(data)) { + for (var key in data) { + if (!isRenderedModule(key)) { + invokeCreateHooks(vnode, insertedVnodeQueue); + break + } + } + } + } + return true + } + + function assertNodeMatch (node, vnode) { + if (vnode.tag) { + return ( + vnode.tag.indexOf('vue-component') === 0 || + vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase()) + ) + } else { + return _toString(vnode.text) === node.data + } + } + + return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) { + if (!vnode) { + if (oldVnode) { invokeDestroyHook(oldVnode); } + return + } + + var elm, parent; + var isInitialPatch = false; + var insertedVnodeQueue = []; + + if (!oldVnode) { + // empty mount (likely as component), create new root element + isInitialPatch = true; + createElm(vnode, insertedVnodeQueue, parentElm, refElm); + } else { + var isRealElement = isDef(oldVnode.nodeType); + if (!isRealElement && sameVnode(oldVnode, vnode)) { + // patch existing root node + patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly); + } else { + if (isRealElement) { + // mounting to a real element + // check if this is server-rendered content and if we can perform + // a successful hydration. + if (oldVnode.nodeType === 1 && oldVnode.hasAttribute('server-rendered')) { + oldVnode.removeAttribute('server-rendered'); + hydrating = true; + } + if (hydrating) { + if (hydrate(oldVnode, vnode, insertedVnodeQueue)) { + invokeInsertHook(vnode, insertedVnodeQueue, true); + return oldVnode + } else if (process.env.NODE_ENV !== 'production') { + warn( + 'The client-side rendered virtual DOM tree is not matching ' + + 'server-rendered content. This is likely caused by incorrect ' + + 'HTML markup, for example nesting block-level elements inside ' + + '

, or missing . Bailing hydration and performing ' + + 'full client-side render.' + ); + } + } + // either not server-rendered, or hydration failed. + // create an empty node and replace it + oldVnode = emptyNodeAt(oldVnode); + } + + // replacing existing element + elm = oldVnode.elm; + parent = nodeOps.parentNode(elm); + createElm(vnode, insertedVnodeQueue, parent, nodeOps.nextSibling(elm)); + + if (vnode.parent) { + // component root element replaced. + // update parent placeholder node element, recursively + var ancestor = vnode.parent; + while (ancestor) { + ancestor.elm = vnode.elm; + ancestor = ancestor.parent; + } + if (isPatchable(vnode)) { + for (var i = 0; i < cbs.create.length; ++i) { + cbs.create[i](emptyNode, vnode.parent); + } + } + } + + if (parent !== null) { + removeVnodes(parent, [oldVnode], 0, 0); + } else if (isDef(oldVnode.tag)) { + invokeDestroyHook(oldVnode); + } + } + } + + invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch); + return vnode.elm + } +} + +/* */ + +var directives = { + create: updateDirectives, + update: updateDirectives, + destroy: function unbindDirectives (vnode) { + updateDirectives(vnode, emptyNode); + } +}; + +function updateDirectives (oldVnode, vnode) { + if (oldVnode.data.directives || vnode.data.directives) { + _update(oldVnode, vnode); + } +} + +function _update (oldVnode, vnode) { + var isCreate = oldVnode === emptyNode; + var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context); + var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context); + + var dirsWithInsert = []; + var dirsWithPostpatch = []; + + var key, oldDir, dir; + for (key in newDirs) { + oldDir = oldDirs[key]; + dir = newDirs[key]; + if (!oldDir) { + // new directive, bind + callHook$1(dir, 'bind', vnode, oldVnode); + if (dir.def && dir.def.inserted) { + dirsWithInsert.push(dir); + } + } else { + // existing directive, update + dir.oldValue = oldDir.value; + callHook$1(dir, 'update', vnode, oldVnode); + if (dir.def && dir.def.componentUpdated) { + dirsWithPostpatch.push(dir); + } + } + } + + if (dirsWithInsert.length) { + var callInsert = function () { + for (var i = 0; i < dirsWithInsert.length; i++) { + callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode); + } + }; + if (isCreate) { + mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', callInsert, 'dir-insert'); + } else { + callInsert(); + } + } + + if (dirsWithPostpatch.length) { + mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'postpatch', function () { + for (var i = 0; i < dirsWithPostpatch.length; i++) { + callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode); + } + }, 'dir-postpatch'); + } + + if (!isCreate) { + for (key in oldDirs) { + if (!newDirs[key]) { + // no longer present, unbind + callHook$1(oldDirs[key], 'unbind', oldVnode); + } + } + } +} + +var emptyModifiers = Object.create(null); + +function normalizeDirectives$1 ( + dirs, + vm +) { + var res = Object.create(null); + if (!dirs) { + return res + } + var i, dir; + for (i = 0; i < dirs.length; i++) { + dir = dirs[i]; + if (!dir.modifiers) { + dir.modifiers = emptyModifiers; + } + res[getRawDirName(dir)] = dir; + dir.def = resolveAsset(vm.$options, 'directives', dir.name, true); + } + return res +} + +function getRawDirName (dir) { + return dir.rawName || ((dir.name) + "." + (Object.keys(dir.modifiers || {}).join('.'))) +} + +function callHook$1 (dir, hook, vnode, oldVnode) { + var fn = dir.def && dir.def[hook]; + if (fn) { + fn(vnode.elm, dir, vnode, oldVnode); + } +} + +var baseModules = [ + ref, + directives +]; + +/* */ + +function updateAttrs (oldVnode, vnode) { + if (!oldVnode.data.attrs && !vnode.data.attrs) { + return + } + var key, cur, old; + var elm = vnode.elm; + var oldAttrs = oldVnode.data.attrs || {}; + var attrs = vnode.data.attrs || {}; + // clone observed objects, as the user probably wants to mutate it + if (attrs.__ob__) { + attrs = vnode.data.attrs = extend({}, attrs); + } + + for (key in attrs) { + cur = attrs[key]; + old = oldAttrs[key]; + if (old !== cur) { + setAttr(elm, key, cur); + } + } + // #4391: in IE9, setting type can reset value for input[type=radio] + /* istanbul ignore if */ + if (isIE9 && attrs.value !== oldAttrs.value) { + setAttr(elm, 'value', attrs.value); + } + for (key in oldAttrs) { + if (attrs[key] == null) { + if (isXlink(key)) { + elm.removeAttributeNS(xlinkNS, getXlinkProp(key)); + } else if (!isEnumeratedAttr(key)) { + elm.removeAttribute(key); + } + } + } +} + +function setAttr (el, key, value) { + if (isBooleanAttr(key)) { + // set attribute for blank value + // e.g. + if (isFalsyAttrValue(value)) { + el.removeAttribute(key); + } else { + el.setAttribute(key, key); + } + } else if (isEnumeratedAttr(key)) { + el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'); + } else if (isXlink(key)) { + if (isFalsyAttrValue(value)) { + el.removeAttributeNS(xlinkNS, getXlinkProp(key)); + } else { + el.setAttributeNS(xlinkNS, key, value); + } + } else { + if (isFalsyAttrValue(value)) { + el.removeAttribute(key); + } else { + el.setAttribute(key, value); + } + } +} + +var attrs = { + create: updateAttrs, + update: updateAttrs +}; + +/* */ + +function updateClass (oldVnode, vnode) { + var el = vnode.elm; + var data = vnode.data; + var oldData = oldVnode.data; + if (!data.staticClass && !data.class && + (!oldData || (!oldData.staticClass && !oldData.class))) { + return + } + + var cls = genClassForVnode(vnode); + + // handle transition classes + var transitionClass = el._transitionClasses; + if (transitionClass) { + cls = concat(cls, stringifyClass(transitionClass)); + } + + // set the class + if (cls !== el._prevClass) { + el.setAttribute('class', cls); + el._prevClass = cls; + } +} + +var klass = { + create: updateClass, + update: updateClass +}; + +/* */ + +var target; + +function add$1 (event, handler, once, capture) { + if (once) { + var oldHandler = handler; + handler = function (ev) { + remove$2(event, handler, capture); + arguments.length === 1 + ? oldHandler(ev) + : oldHandler.apply(null, arguments); + }; + } + target.addEventListener(event, handler, capture); +} + +function remove$2 (event, handler, capture) { + target.removeEventListener(event, handler, capture); +} + +function updateDOMListeners (oldVnode, vnode) { + if (!oldVnode.data.on && !vnode.data.on) { + return + } + var on = vnode.data.on || {}; + var oldOn = oldVnode.data.on || {}; + target = vnode.elm; + updateListeners(on, oldOn, add$1, remove$2, vnode.context); +} + +var events = { + create: updateDOMListeners, + update: updateDOMListeners +}; + +/* */ + +function updateDOMProps (oldVnode, vnode) { + if (!oldVnode.data.domProps && !vnode.data.domProps) { + return + } + var key, cur; + var elm = vnode.elm; + var oldProps = oldVnode.data.domProps || {}; + var props = vnode.data.domProps || {}; + // clone observed objects, as the user probably wants to mutate it + if (props.__ob__) { + props = vnode.data.domProps = extend({}, props); + } + + for (key in oldProps) { + if (props[key] == null) { + elm[key] = ''; + } + } + for (key in props) { + cur = props[key]; + // ignore children if the node has textContent or innerHTML, + // as these will throw away existing DOM nodes and cause removal errors + // on subsequent patches (#3360) + if (key === 'textContent' || key === 'innerHTML') { + if (vnode.children) { vnode.children.length = 0; } + if (cur === oldProps[key]) { continue } + } + if (key === 'value') { + // store value as _value as well since + // non-string values will be stringified + elm._value = cur; + // avoid resetting cursor position when value is the same + var strCur = cur == null ? '' : String(cur); + if (!elm.composing && ( + (document.activeElement !== elm && elm.value !== strCur) || + isValueChanged(vnode, strCur) + )) { + elm.value = strCur; + } + } else { + elm[key] = cur; + } + } +} + +function isValueChanged (vnode, newVal) { + var value = vnode.elm.value; + var modifiers = vnode.elm._vModifiers; // injected by v-model runtime + if ((modifiers && modifiers.number) || vnode.elm.type === 'number') { + return toNumber(value) !== toNumber(newVal) + } + if (modifiers && modifiers.trim) { + return value.trim() !== newVal.trim() + } + return value !== newVal +} + +var domProps = { + create: updateDOMProps, + update: updateDOMProps +}; + +/* */ + +var parseStyleText = cached(function (cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res +}); + +// merge static and dynamic style data on the same vnode +function normalizeStyleData (data) { + var style = normalizeStyleBinding(data.style); + // static style is pre-processed into an object during compilation + // and is always a fresh object, so it's safe to merge into it + return data.staticStyle + ? extend(data.staticStyle, style) + : style +} + +// normalize possible array / string values into Object +function normalizeStyleBinding (bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle) + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle) + } + return bindingStyle +} + +/** + * parent component style should be after child's + * so that parent component's style could override it + */ +function getStyle (vnode, checkChild) { + var res = {}; + var styleData; + + if (checkChild) { + var childNode = vnode; + while (childNode.child) { + childNode = childNode.child._vnode; + if (childNode.data && (styleData = normalizeStyleData(childNode.data))) { + extend(res, styleData); + } + } + } + + if ((styleData = normalizeStyleData(vnode.data))) { + extend(res, styleData); + } + + var parentNode = vnode; + while ((parentNode = parentNode.parent)) { + if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) { + extend(res, styleData); + } + } + return res +} + +/* */ + +var cssVarRE = /^--/; +var importantRE = /\s*!important$/; +var setProp = function (el, name, val) { + /* istanbul ignore if */ + if (cssVarRE.test(name)) { + el.style.setProperty(name, val); + } else if (importantRE.test(val)) { + el.style.setProperty(name, val.replace(importantRE, ''), 'important'); + } else { + el.style[normalize(name)] = val; + } +}; + +var prefixes = ['Webkit', 'Moz', 'ms']; + +var testEl; +var normalize = cached(function (prop) { + testEl = testEl || document.createElement('div'); + prop = camelize(prop); + if (prop !== 'filter' && (prop in testEl.style)) { + return prop + } + var upper = prop.charAt(0).toUpperCase() + prop.slice(1); + for (var i = 0; i < prefixes.length; i++) { + var prefixed = prefixes[i] + upper; + if (prefixed in testEl.style) { + return prefixed + } + } +}); + +function updateStyle (oldVnode, vnode) { + var data = vnode.data; + var oldData = oldVnode.data; + + if (!data.staticStyle && !data.style && + !oldData.staticStyle && !oldData.style) { + return + } + + var cur, name; + var el = vnode.elm; + var oldStaticStyle = oldVnode.data.staticStyle; + var oldStyleBinding = oldVnode.data.style || {}; + + // if static style exists, stylebinding already merged into it when doing normalizeStyleData + var oldStyle = oldStaticStyle || oldStyleBinding; + + var style = normalizeStyleBinding(vnode.data.style) || {}; + + vnode.data.style = style.__ob__ ? extend({}, style) : style; + + var newStyle = getStyle(vnode, true); + + for (name in oldStyle) { + if (newStyle[name] == null) { + setProp(el, name, ''); + } + } + for (name in newStyle) { + cur = newStyle[name]; + if (cur !== oldStyle[name]) { + // ie9 setting to null has no effect, must use empty string + setProp(el, name, cur == null ? '' : cur); + } + } +} + +var style = { + create: updateStyle, + update: updateStyle +}; + +/* */ + +/** + * Add class with compatibility for SVG since classList is not supported on + * SVG elements in IE + */ +function addClass (el, cls) { + /* istanbul ignore if */ + if (!cls || !cls.trim()) { + return + } + + /* istanbul ignore else */ + if (el.classList) { + if (cls.indexOf(' ') > -1) { + cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); }); + } else { + el.classList.add(cls); + } + } else { + var cur = ' ' + el.getAttribute('class') + ' '; + if (cur.indexOf(' ' + cls + ' ') < 0) { + el.setAttribute('class', (cur + cls).trim()); + } + } +} + +/** + * Remove class with compatibility for SVG since classList is not supported on + * SVG elements in IE + */ +function removeClass (el, cls) { + /* istanbul ignore if */ + if (!cls || !cls.trim()) { + return + } + + /* istanbul ignore else */ + if (el.classList) { + if (cls.indexOf(' ') > -1) { + cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); }); + } else { + el.classList.remove(cls); + } + } else { + var cur = ' ' + el.getAttribute('class') + ' '; + var tar = ' ' + cls + ' '; + while (cur.indexOf(tar) >= 0) { + cur = cur.replace(tar, ' '); + } + el.setAttribute('class', cur.trim()); + } +} + +/* */ + +var hasTransition = inBrowser && !isIE9; +var TRANSITION = 'transition'; +var ANIMATION = 'animation'; + +// Transition property/event sniffing +var transitionProp = 'transition'; +var transitionEndEvent = 'transitionend'; +var animationProp = 'animation'; +var animationEndEvent = 'animationend'; +if (hasTransition) { + /* istanbul ignore if */ + if (window.ontransitionend === undefined && + window.onwebkittransitionend !== undefined) { + transitionProp = 'WebkitTransition'; + transitionEndEvent = 'webkitTransitionEnd'; + } + if (window.onanimationend === undefined && + window.onwebkitanimationend !== undefined) { + animationProp = 'WebkitAnimation'; + animationEndEvent = 'webkitAnimationEnd'; + } +} + +var raf = (inBrowser && window.requestAnimationFrame) || setTimeout; +function nextFrame (fn) { + raf(function () { + raf(fn); + }); +} + +function addTransitionClass (el, cls) { + (el._transitionClasses || (el._transitionClasses = [])).push(cls); + addClass(el, cls); +} + +function removeTransitionClass (el, cls) { + if (el._transitionClasses) { + remove$1(el._transitionClasses, cls); + } + removeClass(el, cls); +} + +function whenTransitionEnds ( + el, + expectedType, + cb +) { + var ref = getTransitionInfo(el, expectedType); + var type = ref.type; + var timeout = ref.timeout; + var propCount = ref.propCount; + if (!type) { return cb() } + var event = type === TRANSITION ? transitionEndEvent : animationEndEvent; + var ended = 0; + var end = function () { + el.removeEventListener(event, onEnd); + cb(); + }; + var onEnd = function (e) { + if (e.target === el) { + if (++ended >= propCount) { + end(); + } + } + }; + setTimeout(function () { + if (ended < propCount) { + end(); + } + }, timeout + 1); + el.addEventListener(event, onEnd); +} + +var transformRE = /\b(transform|all)(,|$)/; + +function getTransitionInfo (el, expectedType) { + var styles = window.getComputedStyle(el); + var transitioneDelays = styles[transitionProp + 'Delay'].split(', '); + var transitionDurations = styles[transitionProp + 'Duration'].split(', '); + var transitionTimeout = getTimeout(transitioneDelays, transitionDurations); + var animationDelays = styles[animationProp + 'Delay'].split(', '); + var animationDurations = styles[animationProp + 'Duration'].split(', '); + var animationTimeout = getTimeout(animationDelays, animationDurations); + + var type; + var timeout = 0; + var propCount = 0; + /* istanbul ignore if */ + if (expectedType === TRANSITION) { + if (transitionTimeout > 0) { + type = TRANSITION; + timeout = transitionTimeout; + propCount = transitionDurations.length; + } + } else if (expectedType === ANIMATION) { + if (animationTimeout > 0) { + type = ANIMATION; + timeout = animationTimeout; + propCount = animationDurations.length; + } + } else { + timeout = Math.max(transitionTimeout, animationTimeout); + type = timeout > 0 + ? transitionTimeout > animationTimeout + ? TRANSITION + : ANIMATION + : null; + propCount = type + ? type === TRANSITION + ? transitionDurations.length + : animationDurations.length + : 0; + } + var hasTransform = + type === TRANSITION && + transformRE.test(styles[transitionProp + 'Property']); + return { + type: type, + timeout: timeout, + propCount: propCount, + hasTransform: hasTransform + } +} + +function getTimeout (delays, durations) { + /* istanbul ignore next */ + while (delays.length < durations.length) { + delays = delays.concat(delays); + } + + return Math.max.apply(null, durations.map(function (d, i) { + return toMs(d) + toMs(delays[i]) + })) +} + +function toMs (s) { + return Number(s.slice(0, -1)) * 1000 +} + +/* */ + +function enter (vnode, toggleDisplay) { + var el = vnode.elm; + + // call leave callback now + if (el._leaveCb) { + el._leaveCb.cancelled = true; + el._leaveCb(); + } + + var data = resolveTransition(vnode.data.transition); + if (!data) { + return + } + + /* istanbul ignore if */ + if (el._enterCb || el.nodeType !== 1) { + return + } + + var css = data.css; + var type = data.type; + var enterClass = data.enterClass; + var enterActiveClass = data.enterActiveClass; + var appearClass = data.appearClass; + var appearActiveClass = data.appearActiveClass; + var beforeEnter = data.beforeEnter; + var enter = data.enter; + var afterEnter = data.afterEnter; + var enterCancelled = data.enterCancelled; + var beforeAppear = data.beforeAppear; + var appear = data.appear; + var afterAppear = data.afterAppear; + var appearCancelled = data.appearCancelled; + + // activeInstance will always be the component managing this + // transition. One edge case to check is when the is placed + // as the root node of a child component. In that case we need to check + // 's parent for appear check. + var context = activeInstance; + var transitionNode = activeInstance.$vnode; + while (transitionNode && transitionNode.parent) { + transitionNode = transitionNode.parent; + context = transitionNode.context; + } + + var isAppear = !context._isMounted || !vnode.isRootInsert; + + if (isAppear && !appear && appear !== '') { + return + } + + var startClass = isAppear ? appearClass : enterClass; + var activeClass = isAppear ? appearActiveClass : enterActiveClass; + var beforeEnterHook = isAppear ? (beforeAppear || beforeEnter) : beforeEnter; + var enterHook = isAppear ? (typeof appear === 'function' ? appear : enter) : enter; + var afterEnterHook = isAppear ? (afterAppear || afterEnter) : afterEnter; + var enterCancelledHook = isAppear ? (appearCancelled || enterCancelled) : enterCancelled; + + var expectsCSS = css !== false && !isIE9; + var userWantsControl = + enterHook && + // enterHook may be a bound method which exposes + // the length of original fn as _length + (enterHook._length || enterHook.length) > 1; + + var cb = el._enterCb = once(function () { + if (expectsCSS) { + removeTransitionClass(el, activeClass); + } + if (cb.cancelled) { + if (expectsCSS) { + removeTransitionClass(el, startClass); + } + enterCancelledHook && enterCancelledHook(el); + } else { + afterEnterHook && afterEnterHook(el); + } + el._enterCb = null; + }); + + if (!vnode.data.show) { + // remove pending leave element on enter by injecting an insert hook + mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', function () { + var parent = el.parentNode; + var pendingNode = parent && parent._pending && parent._pending[vnode.key]; + if (pendingNode && + pendingNode.context === vnode.context && + pendingNode.tag === vnode.tag && + pendingNode.elm._leaveCb) { + pendingNode.elm._leaveCb(); + } + enterHook && enterHook(el, cb); + }, 'transition-insert'); + } + + // start enter transition + beforeEnterHook && beforeEnterHook(el); + if (expectsCSS) { + addTransitionClass(el, startClass); + addTransitionClass(el, activeClass); + nextFrame(function () { + removeTransitionClass(el, startClass); + if (!cb.cancelled && !userWantsControl) { + whenTransitionEnds(el, type, cb); + } + }); + } + + if (vnode.data.show) { + toggleDisplay && toggleDisplay(); + enterHook && enterHook(el, cb); + } + + if (!expectsCSS && !userWantsControl) { + cb(); + } +} + +function leave (vnode, rm) { + var el = vnode.elm; + + // call enter callback now + if (el._enterCb) { + el._enterCb.cancelled = true; + el._enterCb(); + } + + var data = resolveTransition(vnode.data.transition); + if (!data) { + return rm() + } + + /* istanbul ignore if */ + if (el._leaveCb || el.nodeType !== 1) { + return + } + + var css = data.css; + var type = data.type; + var leaveClass = data.leaveClass; + var leaveActiveClass = data.leaveActiveClass; + var beforeLeave = data.beforeLeave; + var leave = data.leave; + var afterLeave = data.afterLeave; + var leaveCancelled = data.leaveCancelled; + var delayLeave = data.delayLeave; + + var expectsCSS = css !== false && !isIE9; + var userWantsControl = + leave && + // leave hook may be a bound method which exposes + // the length of original fn as _length + (leave._length || leave.length) > 1; + + var cb = el._leaveCb = once(function () { + if (el.parentNode && el.parentNode._pending) { + el.parentNode._pending[vnode.key] = null; + } + if (expectsCSS) { + removeTransitionClass(el, leaveActiveClass); + } + if (cb.cancelled) { + if (expectsCSS) { + removeTransitionClass(el, leaveClass); + } + leaveCancelled && leaveCancelled(el); + } else { + rm(); + afterLeave && afterLeave(el); + } + el._leaveCb = null; + }); + + if (delayLeave) { + delayLeave(performLeave); + } else { + performLeave(); + } + + function performLeave () { + // the delayed leave may have already been cancelled + if (cb.cancelled) { + return + } + // record leaving element + if (!vnode.data.show) { + (el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode; + } + beforeLeave && beforeLeave(el); + if (expectsCSS) { + addTransitionClass(el, leaveClass); + addTransitionClass(el, leaveActiveClass); + nextFrame(function () { + removeTransitionClass(el, leaveClass); + if (!cb.cancelled && !userWantsControl) { + whenTransitionEnds(el, type, cb); + } + }); + } + leave && leave(el, cb); + if (!expectsCSS && !userWantsControl) { + cb(); + } + } +} + +function resolveTransition (def$$1) { + if (!def$$1) { + return + } + /* istanbul ignore else */ + if (typeof def$$1 === 'object') { + var res = {}; + if (def$$1.css !== false) { + extend(res, autoCssTransition(def$$1.name || 'v')); + } + extend(res, def$$1); + return res + } else if (typeof def$$1 === 'string') { + return autoCssTransition(def$$1) + } +} + +var autoCssTransition = cached(function (name) { + return { + enterClass: (name + "-enter"), + leaveClass: (name + "-leave"), + appearClass: (name + "-enter"), + enterActiveClass: (name + "-enter-active"), + leaveActiveClass: (name + "-leave-active"), + appearActiveClass: (name + "-enter-active") + } +}); + +function once (fn) { + var called = false; + return function () { + if (!called) { + called = true; + fn(); + } + } +} + +function _enter (_, vnode) { + if (!vnode.data.show) { + enter(vnode); + } +} + +var transition = inBrowser ? { + create: _enter, + activate: _enter, + remove: function remove (vnode, rm) { + /* istanbul ignore else */ + if (!vnode.data.show) { + leave(vnode, rm); + } else { + rm(); + } + } +} : {}; + +var platformModules = [ + attrs, + klass, + events, + domProps, + style, + transition +]; + +/* */ + +// the directive module should be applied last, after all +// built-in modules have been applied. +var modules = platformModules.concat(baseModules); + +var patch$1 = createPatchFunction({ nodeOps: nodeOps, modules: modules }); + +/** + * Not type checking this file because flow doesn't like attaching + * properties to Elements. + */ + +var modelableTagRE = /^input|select|textarea|vue-component-[0-9]+(-[0-9a-zA-Z_-]*)?$/; + +/* istanbul ignore if */ +if (isIE9) { + // http://www.matts411.com/post/internet-explorer-9-oninput/ + document.addEventListener('selectionchange', function () { + var el = document.activeElement; + if (el && el.vmodel) { + trigger(el, 'input'); + } + }); +} + +var model = { + inserted: function inserted (el, binding, vnode) { + if (process.env.NODE_ENV !== 'production') { + if (!modelableTagRE.test(vnode.tag)) { + warn( + "v-model is not supported on element type: <" + (vnode.tag) + ">. " + + 'If you are working with contenteditable, it\'s recommended to ' + + 'wrap a library dedicated for that purpose inside a custom component.', + vnode.context + ); + } + } + if (vnode.tag === 'select') { + var cb = function () { + setSelected(el, binding, vnode.context); + }; + cb(); + /* istanbul ignore if */ + if (isIE || isEdge) { + setTimeout(cb, 0); + } + } else if (vnode.tag === 'textarea' || el.type === 'text') { + el._vModifiers = binding.modifiers; + if (!binding.modifiers.lazy) { + if (!isAndroid) { + el.addEventListener('compositionstart', onCompositionStart); + el.addEventListener('compositionend', onCompositionEnd); + } + /* istanbul ignore if */ + if (isIE9) { + el.vmodel = true; + } + } + } + }, + componentUpdated: function componentUpdated (el, binding, vnode) { + if (vnode.tag === 'select') { + setSelected(el, binding, vnode.context); + // in case the options rendered by v-for have changed, + // it's possible that the value is out-of-sync with the rendered options. + // detect such cases and filter out values that no longer has a matching + // option in the DOM. + var needReset = el.multiple + ? binding.value.some(function (v) { return hasNoMatchingOption(v, el.options); }) + : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, el.options); + if (needReset) { + trigger(el, 'change'); + } + } + } +}; + +function setSelected (el, binding, vm) { + var value = binding.value; + var isMultiple = el.multiple; + if (isMultiple && !Array.isArray(value)) { + process.env.NODE_ENV !== 'production' && warn( + "