├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github └── FUNDING.yml ├── .gitignore ├── .postcssrc.js ├── LICENSE.md ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── docs ├── css │ └── app.c6a14cafc7612ddaf801b938ae008e83.css ├── img │ └── image_1.01b1131.jpg ├── index.html └── js │ ├── app.145fe87947b563ad6a0a.js │ ├── manifest.a817c9d53d232fb6ad20.js │ └── vendor.dcfc1e274e468f40df16.js ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.vue ├── assets │ └── image_1.jpg ├── components │ └── FocusPoint.vue ├── index.js ├── main.js └── scss │ ├── _focus-point-theme.scss │ ├── _focus-point-variables.scss │ └── _focus-point.scss ├── static └── .gitkeep └── test └── unit ├── .eslintrc ├── jest.conf.js ├── setup.js └── specs └── FocusPoint.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // https://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parserOptions: { 6 | parser: 'babel-eslint' 7 | }, 8 | env: { 9 | browser: true, 10 | }, 11 | extends: 'neonblack/vue', 12 | // check if imports actually resolve 13 | settings: { 14 | 'import/resolver': { 15 | webpack: { 16 | config: 'build/webpack.base.conf.js' 17 | } 18 | } 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://liberapay.com/EvodiaAut 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | /test/unit/coverage/ 8 | 9 | # Editor directories and files 10 | .idea 11 | .vscode 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) EvodiaAut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-focuspoint-component 2 | 3 | > Set focus point on elements 4 | 5 | [![npm](https://img.shields.io/npm/v/vue-focuspoint-component.svg?style=for-the-badge)](https://www.npmjs.com/package/vue-focuspoint-component) 6 | [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](https://github.com/EvodiaAut/vue-focuspoint-component/blob/master/LICENSE.md) 7 | [![npm](https://img.shields.io/npm/dt/vue-focuspoint-component.svg?style=for-the-badge)](https://www.npmjs.com/package/vue-focuspoint-component) 8 | 9 | ## Demo 10 | 11 | [Demo here](https://evodiaaut.github.io/vue-focuspoint-component/) 12 | 13 | ## Install 14 | 15 | `npm install vue-focuspoint-component` or `yarn add vue-focuspoint-component` 16 | 17 | ## Usage 18 | 19 | The most common use case is to register the component globally. 20 | 21 | ```js 22 | // in your main.js or similar file 23 | import Vue from 'vue' 24 | import FocusPoint from 'vue-focuspoint-component' 25 | 26 | Vue.component('focus-point', FocusPoint) 27 | ``` 28 | 29 | Alternatively you can do this to register the components: 30 | 31 | ```js 32 | // HelloWorld.vue 33 | import FocusPoint from 'vue-focuspoint-component' 34 | 35 | export default { 36 | name: 'HelloWorld', 37 | components: { 38 | FocusPoint 39 | } 40 | } 41 | ``` 42 | 43 | On your page you can now use html like this: 44 | 45 | Image element 46 | 47 | ```html 48 | 49 | 52 | 53 | 54 | 55 | 56 | focus: { 57 | "x": 35, 58 | "y": 62 59 | } 60 | 61 | 62 | 63 | 64 | 65 | ``` 66 | 67 | Other elements (use careful element with text has not the same ratio by a resize) 68 | 69 | ```html 70 | 73 |
76 |

Hello, world!

77 |

Lorem ipsum dolor sit amet, consetetur sadipscing elitr...

78 |
79 |
80 | ``` 81 | 82 | ## CSS 83 | 84 | ```scss 85 | // required and to get updates 86 | @import "./node_modules/vue-focuspoint-component/src/scss/focus-point"; 87 | // simple theme 88 | @import "./node_modules/vue-focuspoint-component/src/scss/focus-point-theme"; 89 | ``` 90 | 91 | Do you like my theme but not the colors or paddings, ...? 92 | 93 | ```scss 94 | @import "./node_modules/vue-focuspoint-component/src/scss/focus-point"; 95 | 96 | // overwrite variables from the simple theme 97 | $focuspoint-background: blue; 98 | $focuspoint-border: 3px solid white; 99 | $focuspoint-radius: 2px; 100 | // find more variables in /src/scss/_focus-point-variables.scss 101 | 102 | @import "./node_modules/vue-focuspoint-component/src/scss/focus-point-theme"; 103 | ``` 104 | 105 | ## V-Model 106 | 107 | |Type|Required|Default|Description 108 | |-|-|-|-| 109 | |Object|false|`{ x: 50, y: 50 }`|Focus 110 | 111 | ## Slots 112 | 113 | |Name|Description 114 | |-|-| 115 | |pin|Inner html from pin 116 | 117 | ## Slots example 118 | 119 | Create your own pin 120 | 121 | ```html 122 | 125 | 130 | 131 | 132 | ``` 133 | 134 | ## Build Setup 135 | 136 | ``` bash 137 | # install dependencies 138 | npm install 139 | 140 | # serve with hot reload at localhost:8080 141 | npm run dev 142 | 143 | # build for production with minification 144 | npm run build 145 | 146 | # build for production and view the bundle analyzer report 147 | npm run build --report 148 | 149 | # run unit tests 150 | npm run unit 151 | 152 | # run all tests 153 | npm test 154 | ``` 155 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvodiaAut/vue-focuspoint-component/3b807ca61b47bd75c567946e0033930dd6646e59/build/logo.png -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader' 51 | }) 52 | } else { 53 | return ['vue-style-loader'].concat(loaders) 54 | } 55 | } 56 | 57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 58 | return { 59 | css: generateLoaders(), 60 | postcss: generateLoaders(), 61 | less: generateLoaders('less'), 62 | sass: generateLoaders('sass', { indentedSyntax: true }), 63 | scss: generateLoaders('sass'), 64 | stylus: generateLoaders('stylus'), 65 | styl: generateLoaders('stylus') 66 | } 67 | } 68 | 69 | // Generate loaders for standalone style files (outside of .vue) 70 | exports.styleLoaders = function (options) { 71 | const output = [] 72 | const loaders = exports.cssLoaders(options) 73 | 74 | for (const extension in loaders) { 75 | const loader = loaders[extension] 76 | output.push({ 77 | test: new RegExp('\\.' + extension + '$'), 78 | use: loader 79 | }) 80 | } 81 | 82 | return output 83 | } 84 | 85 | exports.createNotifierCallback = () => { 86 | const notifier = require('node-notifier') 87 | 88 | return (severity, errors) => { 89 | if (severity !== 'error') return 90 | 91 | const error = errors[0] 92 | const filename = error.file && error.file.split('!').pop() 93 | 94 | notifier.notify({ 95 | title: packageConfig.name, 96 | message: severity + ': ' + error.name, 97 | subtitle: filename || '', 98 | icon: path.join(__dirname, 'logo.png') 99 | }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | const createLintingRule = () => ({ 12 | test: /\.(js|vue)$/, 13 | loader: 'eslint-loader', 14 | enforce: 'pre', 15 | include: [resolve('src'), resolve('test')], 16 | options: { 17 | formatter: require('eslint-friendly-formatter'), 18 | emitWarning: !config.dev.showEslintErrorsInOverlay 19 | } 20 | }) 21 | 22 | module.exports = { 23 | context: path.resolve(__dirname, '../'), 24 | entry: { 25 | app: './src/main.js' 26 | }, 27 | output: { 28 | path: config.build.assetsRoot, 29 | filename: '[name].js', 30 | publicPath: process.env.NODE_ENV === 'production' 31 | ? config.build.assetsPublicPath 32 | : config.dev.assetsPublicPath 33 | }, 34 | resolve: { 35 | extensions: ['.js', '.vue', '.json'], 36 | alias: { 37 | '@': resolve('src'), 38 | } 39 | }, 40 | module: { 41 | rules: [ 42 | ...(config.dev.useEslint ? [createLintingRule()] : []), 43 | { 44 | test: /\.vue$/, 45 | loader: 'vue-loader', 46 | options: vueLoaderConfig 47 | }, 48 | { 49 | test: /\.js$/, 50 | loader: 'babel-loader', 51 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 52 | }, 53 | { 54 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 55 | loader: 'url-loader', 56 | options: { 57 | limit: 10000, 58 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 59 | } 60 | }, 61 | { 62 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 63 | loader: 'url-loader', 64 | options: { 65 | limit: 10000, 66 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 67 | } 68 | }, 69 | { 70 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 71 | loader: 'url-loader', 72 | options: { 73 | limit: 10000, 74 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 75 | } 76 | } 77 | ] 78 | }, 79 | node: { 80 | // prevent webpack from injecting useless setImmediate polyfill because Vue 81 | // source contains it (although only uses it if it's native). 82 | setImmediate: false, 83 | // prevent webpack from injecting mocks to Node native modules 84 | // that does not make sense for the client 85 | dgram: 'empty', 86 | fs: 'empty', 87 | net: 'empty', 88 | tls: 'empty', 89 | child_process: 'empty' 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 19 | }, 20 | // cheap-module-eval-source-map is faster for development 21 | devtool: config.dev.devtool, 22 | 23 | // these devServer options should be customized in /config/index.js 24 | devServer: { 25 | clientLogLevel: 'warning', 26 | historyApiFallback: { 27 | rewrites: [ 28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 29 | ], 30 | }, 31 | hot: true, 32 | contentBase: false, // since we use CopyWebpackPlugin. 33 | compress: true, 34 | host: HOST || config.dev.host, 35 | port: PORT || config.dev.port, 36 | open: config.dev.autoOpenBrowser, 37 | overlay: config.dev.errorOverlay 38 | ? { warnings: false, errors: true } 39 | : false, 40 | publicPath: config.dev.assetsPublicPath, 41 | proxy: config.dev.proxyTable, 42 | quiet: true, // necessary for FriendlyErrorsPlugin 43 | watchOptions: { 44 | poll: config.dev.poll, 45 | } 46 | }, 47 | plugins: [ 48 | new webpack.DefinePlugin({ 49 | 'process.env': require('../config/dev.env') 50 | }), 51 | new webpack.HotModuleReplacementPlugin(), 52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 53 | new webpack.NoEmitOnErrorsPlugin(), 54 | // https://github.com/ampedandwired/html-webpack-plugin 55 | new HtmlWebpackPlugin({ 56 | filename: 'index.html', 57 | template: 'index.html', 58 | inject: true 59 | }), 60 | // copy custom static assets 61 | new CopyWebpackPlugin([ 62 | { 63 | from: path.resolve(__dirname, '../static'), 64 | to: config.dev.assetsSubDirectory, 65 | ignore: ['.*'] 66 | } 67 | ]) 68 | ] 69 | }) 70 | 71 | module.exports = new Promise((resolve, reject) => { 72 | portfinder.basePort = process.env.PORT || config.dev.port 73 | portfinder.getPort((err, port) => { 74 | if (err) { 75 | reject(err) 76 | } else { 77 | // publish the new Port, necessary for e2e tests 78 | process.env.PORT = port 79 | // add port to devServer config 80 | devWebpackConfig.devServer.port = port 81 | 82 | // Add FriendlyErrorsPlugin 83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 84 | compilationSuccessInfo: { 85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 86 | }, 87 | onErrors: config.dev.notifyOnErrors 88 | ? utils.createNotifierCallback() 89 | : undefined 90 | })) 91 | 92 | resolve(devWebpackConfig) 93 | } 94 | }) 95 | }) 96 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = process.env.NODE_ENV === 'testing' 15 | ? require('../config/test.env') 16 | : require('../config/prod.env') 17 | 18 | const webpackConfig = merge(baseWebpackConfig, { 19 | module: { 20 | rules: utils.styleLoaders({ 21 | sourceMap: config.build.productionSourceMap, 22 | extract: true, 23 | usePostCSS: true 24 | }) 25 | }, 26 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 27 | output: { 28 | path: config.build.assetsRoot, 29 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 30 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 31 | }, 32 | plugins: [ 33 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 34 | new webpack.DefinePlugin({ 35 | 'process.env': env 36 | }), 37 | new UglifyJsPlugin({ 38 | uglifyOptions: { 39 | compress: { 40 | warnings: false 41 | } 42 | }, 43 | sourceMap: config.build.productionSourceMap, 44 | parallel: true 45 | }), 46 | // extract css into its own file 47 | new ExtractTextPlugin({ 48 | filename: utils.assetsPath('css/[name].[contenthash].css'), 49 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 50 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 51 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 52 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 53 | allChunks: true, 54 | }), 55 | // Compress extracted CSS. We are using this plugin so that possible 56 | // duplicated CSS from different components can be deduped. 57 | new OptimizeCSSPlugin({ 58 | cssProcessorOptions: config.build.productionSourceMap 59 | ? { safe: true, map: { inline: false } } 60 | : { safe: true } 61 | }), 62 | // generate dist index.html with correct asset hash for caching. 63 | // you can customize output by editing /index.html 64 | // see https://github.com/ampedandwired/html-webpack-plugin 65 | new HtmlWebpackPlugin({ 66 | filename: process.env.NODE_ENV === 'testing' 67 | ? 'index.html' 68 | : config.build.index, 69 | template: 'index.html', 70 | inject: true, 71 | minify: { 72 | removeComments: true, 73 | collapseWhitespace: true, 74 | removeAttributeQuotes: true 75 | // more options: 76 | // https://github.com/kangax/html-minifier#options-quick-reference 77 | }, 78 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 79 | chunksSortMode: 'dependency' 80 | }), 81 | // keep module.id stable when vendor modules does not change 82 | new webpack.HashedModuleIdsPlugin(), 83 | // enable scope hoisting 84 | new webpack.optimize.ModuleConcatenationPlugin(), 85 | // split vendor js into its own file 86 | new webpack.optimize.CommonsChunkPlugin({ 87 | name: 'vendor', 88 | minChunks (module) { 89 | // any required modules inside node_modules are extracted to vendor 90 | return ( 91 | module.resource && 92 | /\.js$/.test(module.resource) && 93 | module.resource.indexOf( 94 | path.join(__dirname, '../node_modules') 95 | ) === 0 96 | ) 97 | } 98 | }), 99 | // extract webpack runtime and module manifest to its own file in order to 100 | // prevent vendor hash from being updated whenever app bundle is updated 101 | new webpack.optimize.CommonsChunkPlugin({ 102 | name: 'manifest', 103 | minChunks: Infinity 104 | }), 105 | // This instance extracts shared chunks from code splitted chunks and bundles them 106 | // in a separate chunk, similar to the vendor chunk 107 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 108 | new webpack.optimize.CommonsChunkPlugin({ 109 | name: 'app', 110 | async: 'vendor-async', 111 | children: true, 112 | minChunks: 3 113 | }), 114 | 115 | // copy custom static assets 116 | new CopyWebpackPlugin([ 117 | { 118 | from: path.resolve(__dirname, '../static'), 119 | to: config.build.assetsSubDirectory, 120 | ignore: ['.*'] 121 | } 122 | ]) 123 | ] 124 | }) 125 | 126 | if (config.build.productionGzip) { 127 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 128 | 129 | webpackConfig.plugins.push( 130 | new CompressionWebpackPlugin({ 131 | asset: '[path].gz[query]', 132 | algorithm: 'gzip', 133 | test: new RegExp( 134 | '\\.(' + 135 | config.build.productionGzipExtensions.join('|') + 136 | ')$' 137 | ), 138 | threshold: 10240, 139 | minRatio: 0.8 140 | }) 141 | ) 142 | } 143 | 144 | if (config.build.bundleAnalyzerReport) { 145 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 146 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 147 | } 148 | 149 | module.exports = webpackConfig 150 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: '', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | // Use Eslint Loader? 24 | // If true, your code will be linted during bundling and 25 | // linting errors and warnings will be shown in the console. 26 | useEslint: true, 27 | // If true, eslint errors and warnings will also be shown in the error overlay 28 | // in the browser. 29 | showEslintErrorsInOverlay: false, 30 | 31 | /** 32 | * Source Maps 33 | */ 34 | 35 | // https://webpack.js.org/configuration/devtool/#development 36 | devtool: 'cheap-module-eval-source-map', 37 | 38 | // If you have problems debugging vue-files in devtools, 39 | // set this to false - it *may* help 40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 41 | cacheBusting: true, 42 | 43 | cssSourceMap: true 44 | }, 45 | 46 | build: { 47 | // Template for index.html 48 | index: path.resolve(__dirname, '../docs/index.html'), 49 | 50 | // Paths 51 | assetsRoot: path.resolve(__dirname, '../docs'), 52 | assetsSubDirectory: '', 53 | assetsPublicPath: 'https://evodiaaut.github.io/vue-focuspoint-component/', 54 | 55 | /** 56 | * Source Maps 57 | */ 58 | 59 | productionSourceMap: false, 60 | // https://webpack.js.org/configuration/devtool/#production 61 | devtool: '#source-map', 62 | 63 | // Gzip off by default as many popular static hosts such as 64 | // Surge or Netlify already gzip all static assets for you. 65 | // Before setting to `true`, make sure to: 66 | // npm install --save-dev compression-webpack-plugin 67 | productionGzip: false, 68 | productionGzipExtensions: ['js', 'css'], 69 | 70 | // Run the build command with an extra argument to 71 | // View the bundle analyzer report after build finishes: 72 | // `npm run build --report` 73 | // Set to `true` or `false` to always turn it on or off 74 | bundleAnalyzerReport: process.env.npm_config_report 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const devEnv = require('./dev.env') 4 | 5 | module.exports = merge(devEnv, { 6 | NODE_ENV: '"testing"' 7 | }) 8 | -------------------------------------------------------------------------------- /docs/img/image_1.01b1131.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvodiaAut/vue-focuspoint-component/3b807ca61b47bd75c567946e0033930dd6646e59/docs/img/image_1.01b1131.jpg -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | vue-focuspoint-component
-------------------------------------------------------------------------------- /docs/js/app.145fe87947b563ad6a0a.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{EOwc:function(t,e,s){t.exports=s.p+"img/image_1.01b1131.jpg"},NHnr:function(t,e,s){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=s("Dd8w"),a=s.n(i),n=s("/5sW"),o={name:"FocusPoint",props:{value:{type:Object,default:function(){return{x:50,y:50}}}},data:function(){return{pin:null}},computed:{pinStyle:function(){if(!this.pin)return null;var t=this.pin,e=t.width,s=t.height;if(!this.value)return{left:this.s(50,e),top:this.s(50,s)};var i=this.value,a=i.x,n=i.y;return{left:this.s(a,e),top:this.s(n,s)}}},mounted:function(){this.pin=this.$refs.pin.getBoundingClientRect()},methods:{click:function(t){var e=t.clientX,s=t.clientY,i=this.$el.getBoundingClientRect(),a=i.left,n=i.width,o=i.top,c=i.height;this.$emit("input",{x:this.c(e,a,n),y:this.c(s,o,c)})},c:function(t,e,s){return Math.round((t-e)/s*100)},s:function(t,e){return"calc("+t+"% - "+e/2+"px)"}}},c={render:function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"focus-point",on:{click:this.click}},[this._t("default"),this._v(" "),e("div",{ref:"pin",staticClass:"focus-point-pin",style:this.pinStyle},[this._t("pin")],2)],2)},staticRenderFns:[]},l={name:"App",components:{FocusPoint:s("VU/8")(o,c,!1,null,null,null).exports},data:function(){return{imageOne:null,imageTwo:{x:69,y:60},imageThree:{x:69,y:58},imageFour:null}}},r={render:function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{attrs:{id:"app"}},[i("div",{staticClass:"my-5 container"},[t._m(0),t._v(" "),i("main",{attrs:{role:"main"}},[i("div",{staticClass:"row my-5"},[i("div",{staticClass:"col-md-6"},[i("h4",[t._v("Feel free set a focus point")]),t._v(" "),i("p",[t._v("Click on the element (picture)")]),t._v(" "),i("focus-point",{model:{value:t.imageOne,callback:function(e){t.imageOne=e},expression:"imageOne"}},[i("img",{staticClass:"img-fluid",attrs:{src:s("EOwc"),alt:"vue-focuspoint-component"}})]),t._v(" "),t.imageOne?i("div",{staticClass:"row my-3"},[i("div",{staticClass:"col-6"},[i("pre",[t._v(t._s(t.imageOne))])]),t._v(" "),i("div",{staticClass:"col-5 col-sm-4 ml-auto image-description"},[i("img",{staticClass:"img-fluid preview-image",style:{objectPosition:t.imageOne.x+"% "+t.imageOne.y+"%"},attrs:{src:s("EOwc"),alt:"vue-focuspoint-component"}})])]):t._e()],1),t._v(" "),i("div",{staticClass:"col-md-6"},[i("h4",[t._v("A saved focus point")]),t._v(" "),t._m(1),t._v(" "),i("focus-point",{model:{value:t.imageTwo,callback:function(e){t.imageTwo=e},expression:"imageTwo"}},[i("img",{staticClass:"img-fluid",attrs:{src:s("EOwc"),alt:"vue-focuspoint-component"}})]),t._v(" "),t.imageTwo?i("div",{staticClass:"row my-3"},[i("div",{staticClass:"col-6"},[i("pre",[t._v(t._s(t.imageTwo))])]),t._v(" "),i("div",{staticClass:"col-5 col-sm-4 ml-auto image-description"},[i("img",{staticClass:"img-fluid preview-image",style:{objectPosition:t.imageTwo.x+"% "+t.imageTwo.y+"%"},attrs:{src:s("EOwc"),alt:"vue-focuspoint-component"}})])]):t._e()],1)]),t._v(" "),i("div",{staticClass:"row my-5"},[i("div",{staticClass:"col-md-6"},[i("h4",[t._v("Own focus pin")]),t._v(" "),t._m(2),t._v(" "),i("focus-point",{model:{value:t.imageThree,callback:function(e){t.imageThree=e},expression:"imageThree"}},[i("template",{slot:"pin"},[t._v("\n 😀\n ")]),t._v(" "),i("img",{staticClass:"img-fluid",attrs:{src:s("EOwc"),alt:"vue-focuspoint-component"}})],2),t._v(" "),t.imageThree?i("div",{staticClass:"row my-3"},[i("div",{staticClass:"col-6"},[i("pre",[t._v(t._s(t.imageThree))])]),t._v(" "),i("div",{staticClass:"col-5 col-sm-4 ml-auto image-description"},[i("img",{staticClass:"img-fluid preview-image",style:{objectPosition:t.imageThree.x+"% "+t.imageThree.y+"%"},attrs:{src:s("EOwc"),alt:"vue-focuspoint-component"}})])]):t._e()],1),t._v(" "),i("div",{staticClass:"col-md-6"},[i("h4",[t._v("Other elements")]),t._v(" "),i("p",[t._v("Test on another element")]),t._v(" "),i("focus-point",{model:{value:t.imageFour,callback:function(e){t.imageFour=e},expression:"imageFour"}},[i("div",{staticClass:"jumbotron"},[i("h1",{staticClass:"display-4"},[t._v("Hello, world!")]),t._v(" "),i("p",{staticClass:"lead"},[t._v("\n This is a simple hero unit, a simple jumbotron-style component for\n calling extra attention to featured content or information.\n ")]),t._v(" "),i("hr",{staticClass:"my-4"}),t._v(" "),i("p",[t._v("\n It uses utility classes for typography and spacing to\n space content out within the larger container.\n ")]),t._v(" "),i("p",{staticClass:"lead"},[i("a",{staticClass:"btn btn-primary btn-lg",attrs:{href:"#",role:"button"}},[t._v("\n Learn more\n ")])])])]),t._v(" "),t.imageFour?i("div",{staticClass:"row my-3"},[i("div",{staticClass:"col-6"},[i("pre",[t._v(t._s(t.imageFour))])])]):t._e()],1)])])])])},staticRenderFns:[function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("header",{staticClass:"pb-3 clearfix border-bottom"},[s("ul",{staticClass:"nav float-right"},[s("li",{staticClass:"nav-item"},[s("a",{staticClass:"nav-link",attrs:{href:"https://github.com/EvodiaAut/vue-focuspoint-component",target:"_blank"}},[t._v("\n Github\n ")])])]),t._v(" "),s("h1",{staticClass:"text-muted"},[t._v("vue-focuspoint-component")]),t._v(" "),s("p",{staticClass:"lead"},[t._v("Set focus point on elements ")]),t._v(" "),s("div",{staticClass:"d-flex flex-wrap"},[s("a",{attrs:{href:"https://www.npmjs.com/package/vue-focuspoint-component",target:"_blank"}},[s("img",{staticClass:"m-1",attrs:{src:"https://img.shields.io/npm/v/vue-focuspoint-component.svg?style=for-the-badge",alt:"vue-focuspoint-component npm"}})]),t._v(" "),s("a",{attrs:{href:"https://github.com/EvodiaAut/vue-focuspoint-component/blob/master/LICENSE.md",target:"_blank"}},[s("img",{staticClass:"m-1",attrs:{src:"https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge",alt:"vue-focuspoint-component license"}})]),t._v(" "),s("a",{attrs:{href:"https://www.npmjs.com/package/vue-focuspoint-component",target:"_blank"}},[s("img",{staticClass:"m-1",attrs:{src:"https://img.shields.io/npm/dt/vue-focuspoint-component.svg?style=for-the-badge",alt:"vue-focuspoint-component npm"}})])])])},function(){var t=this.$createElement,e=this._self._c||t;return e("p",[e("code",[this._v('v-model="imageOne"')])])},function(){var t=this.$createElement,e=this._self._c||t;return e("p",[e("code",[this._v('slot="pin"')]),this._v(" Set your own pin")])}]};var m=s("VU/8")(l,r,!1,function(t){s("rZkm")},null,null).exports;n.a.config.productionTip=!1,new n.a(a()({el:"#app"},m))},rZkm:function(t,e){}},["NHnr"]); -------------------------------------------------------------------------------- /docs/js/manifest.a817c9d53d232fb6ad20.js: -------------------------------------------------------------------------------- 1 | !function(o){var t=window.webpackJsonp;window.webpackJsonp=function(n,u,c){for(var i,p,f,a=0,l=[];a=0&&Math.floor(e)===e&&isFinite(t)}function p(t){return null==t?"":"object"==typeof t?JSON.stringify(t,null,2):String(t)}function d(t){var e=parseFloat(t);return isNaN(e)?t:e}function v(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(n,1)}}var y=Object.prototype.hasOwnProperty;function _(t,e){return y.call(t,e)}function g(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var b=/-(\w)/g,w=g(function(t){return t.replace(b,function(t,e){return e?e.toUpperCase():""})}),x=g(function(t){return t.charAt(0).toUpperCase()+t.slice(1)}),C=/\B([A-Z])/g,A=g(function(t){return t.replace(C,"-$1").toLowerCase()});var O=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function $(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function k(t,e){for(var n in e)t[n]=e[n];return t}function S(t){for(var e={},n=0;n0,X=K&&K.indexOf("edge/")>0,Q=(K&&K.indexOf("android"),K&&/iphone|ipad|ipod|ios/.test(K)||"ios"===q),Z=(K&&/chrome\/\d+/.test(K),{}.watch),Y=!1;if(z)try{var tt={};Object.defineProperty(tt,"passive",{get:function(){Y=!0}}),window.addEventListener("test-passive",null,tt)}catch(t){}var et=function(){return void 0===V&&(V=!z&&!W&&void 0!==t&&"server"===t.process.env.VUE_ENV),V},nt=z&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function rt(t){return"function"==typeof t&&/native code/.test(t.toString())}var ot,it="undefined"!=typeof Symbol&&rt(Symbol)&&"undefined"!=typeof Reflect&&rt(Reflect.ownKeys);ot="undefined"!=typeof Set&&rt(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var at=E,st=0,ct=function(){this.id=st++,this.subs=[]};ct.prototype.addSub=function(t){this.subs.push(t)},ct.prototype.removeSub=function(t){m(this.subs,t)},ct.prototype.depend=function(){ct.target&&ct.target.addDep(this)},ct.prototype.notify=function(){for(var t=this.subs.slice(),e=0,n=t.length;e-1)if(i&&!_(o,"default"))a=!1;else if(""===a||a===A(t)){var c=Ut(String,o.type);(c<0||s0&&(ue((u=t(u,(n||"")+"_"+c))[0])&&ue(l)&&(s[f]=ht(l.text+u[0].text),u.shift()),s.push.apply(s,u)):a(u)?ue(l)?s[f]=ht(l.text+u):""!==u&&s.push(ht(u)):ue(u)&&ue(l)?s[f]=ht(l.text+u.text):(i(e._isVList)&&o(u.tag)&&r(u.key)&&o(n)&&(u.key="__vlist"+n+"_"+c+"__"),s.push(u)));return s}(t):void 0}function ue(t){return o(t)&&o(t.text)&&!1===t.isComment}function fe(t,e){return(t.__esModule||it&&"Module"===t[Symbol.toStringTag])&&(t=t.default),s(t)?e.extend(t):t}function le(t){return t.isComment&&t.asyncFactory}function pe(t){if(Array.isArray(t))for(var e=0;eSe&&Ce[n].id>t.id;)n--;Ce.splice(n+1,0,t)}else Ce.push(t);$e||($e=!0,Yt(Ee))}}(this)},Ie.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||s(t)||this.deep){var e=this.value;if(this.value=t,this.user)try{this.cb.call(this.vm,t,e)}catch(t){Bt(t,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,t,e)}}},Ie.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},Ie.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},Ie.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||m(this.vm._watchers,this);for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1}};var Te={enumerable:!0,configurable:!0,get:E,set:E};function Me(t,e,n){Te.get=function(){return this[e][n]},Te.set=function(t){this[e][n]=t},Object.defineProperty(t,n,Te)}function De(t){t._watchers=[];var e=t.$options;e.props&&function(t,e){var n=t.$options.propsData||{},r=t._props={},o=t.$options._propKeys=[];t.$parent&&wt(!1);var i=function(i){o.push(i);var a=Lt(i,e,n,t);$t(r,i,a),i in t||Me(t,"_props",i)};for(var a in e)i(a);wt(!0)}(t,e.props),e.methods&&function(t,e){t.$options.props;for(var n in e)t[n]=null==e[n]?E:O(e[n],t)}(t,e.methods),e.data?function(t){var e=t.$options.data;u(e=t._data="function"==typeof e?function(t,e){ft();try{return t.call(e,e)}catch(t){return Bt(t,e,"data()"),{}}finally{lt()}}(e,t):e||{})||(e={});var n=Object.keys(e),r=t.$options.props,o=(t.$options.methods,n.length);for(;o--;){var i=n[o];0,r&&_(r,i)||R(i)||Me(t,"_data",i)}Ot(e,!0)}(t):Ot(t._data={},!0),e.computed&&function(t,e){var n=t._computedWatchers=Object.create(null),r=et();for(var o in e){var i=e[o],a="function"==typeof i?i:i.get;0,r||(n[o]=new Ie(t,a||E,E,Pe)),o in t||Ne(t,o,i)}}(t,e.computed),e.watch&&e.watch!==Z&&function(t,e){for(var n in e){var r=e[n];if(Array.isArray(r))for(var o=0;o=0||n.indexOf(t[o])<0)&&r.push(t[o]);return r}return t}function ln(t){this._init(t)}function pn(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,o=t._Ctor||(t._Ctor={});if(o[r])return o[r];var i=t.name||n.options.name;var a=function(t){this._init(t)};return(a.prototype=Object.create(n.prototype)).constructor=a,a.cid=e++,a.options=Pt(n.options,t),a.super=n,a.options.props&&function(t){var e=t.options.props;for(var n in e)Me(t.prototype,"_props",n)}(a),a.options.computed&&function(t){var e=t.options.computed;for(var n in e)Ne(t.prototype,n,e[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,N.forEach(function(t){a[t]=n[t]}),i&&(a.options.components[i]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=k({},a.options),o[r]=a,a}}function dn(t){return t&&(t.Ctor.options.name||t.tag)}function vn(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!f(t)&&t.test(e)}function hn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=dn(a.componentOptions);s&&!e(s)&&mn(n,i,r,o)}}}function mn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,m(n,e)}!function(t){t.prototype._init=function(t){var e=this;e._uid=cn++,e._isVue=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r,n._parentElm=e._parentElm,n._refElm=e._refElm;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=Pt(un(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&he(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,r=t.$vnode=e._parentVnode,o=r&&r.context;t.$slots=me(e._renderChildren,o),t.$scopedSlots=n,t._c=function(e,n,r,o){return sn(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return sn(t,e,n,r,o,!0)};var i=r&&r.data;$t(t,"$attrs",i&&i.attrs||n,null,!0),$t(t,"$listeners",e._parentListeners||n,null,!0)}(e),xe(e,"beforeCreate"),function(t){var e=Re(t.$options.inject,t);e&&(wt(!1),Object.keys(e).forEach(function(n){$t(t,n,e[n])}),wt(!0))}(e),De(e),function(t){var e=t.$options.provide;e&&(t._provided="function"==typeof e?e.call(t):e)}(e),xe(e,"created"),e.$options.el&&e.$mount(e.$options.el)}}(ln),function(t){var e={get:function(){return this._data}},n={get:function(){return this._props}};Object.defineProperty(t.prototype,"$data",e),Object.defineProperty(t.prototype,"$props",n),t.prototype.$set=kt,t.prototype.$delete=St,t.prototype.$watch=function(t,e,n){if(u(e))return Fe(this,t,e,n);(n=n||{}).user=!0;var r=new Ie(this,t,e,n);return n.immediate&&e.call(this,r.value),function(){r.teardown()}}}(ln),function(t){var e=/^hook:/;t.prototype.$on=function(t,n){if(Array.isArray(t))for(var r=0,o=t.length;r1?$(n):n;for(var r=$(arguments,1),o=0,i=n.length;oparseInt(this.max)&&mn(a,s[0],s,this._vnode)),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return F}};Object.defineProperty(t,"config",e),t.util={warn:at,extend:k,mergeOptions:Pt,defineReactive:$t},t.set=kt,t.delete=St,t.nextTick=Yt,t.options=Object.create(null),N.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,k(t.options.components,_n),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=$(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=Pt(this.options,t),this}}(t),pn(t),function(t){N.forEach(function(e){t[e]=function(t,n){return n?("component"===e&&u(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"==typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}})}(t)}(ln),Object.defineProperty(ln.prototype,"$isServer",{get:et}),Object.defineProperty(ln.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(ln,"FunctionalRenderContext",{value:Ze}),ln.version="2.5.16";var gn=v("style,class"),bn=v("input,textarea,option,select,progress"),wn=v("contenteditable,draggable,spellcheck"),xn=v("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"),Cn="http://www.w3.org/1999/xlink",An=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},On=function(t){return An(t)?t.slice(6,t.length):""},$n=function(t){return null==t||!1===t};function kn(t){for(var e=t.data,n=t,r=t;o(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=Sn(r.data,e));for(;o(n=n.parent);)n&&n.data&&(e=Sn(e,n.data));return function(t,e){if(o(t)||o(e))return En(t,jn(e));return""}(e.staticClass,e.class)}function Sn(t,e){return{staticClass:En(t.staticClass,e.staticClass),class:o(t.class)?[t.class,e.class]:e.class}}function En(t,e){return t?e?t+" "+e:t:e||""}function jn(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,i=t.length;r-1?Yn(t,e,n):xn(e)?$n(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):wn(e)?t.setAttribute(e,$n(n)||"false"===n?"false":"true"):An(e)?$n(n)?t.removeAttributeNS(Cn,On(e)):t.setAttributeNS(Cn,e,n):Yn(t,e,n)}function Yn(t,e,n){if($n(n))t.removeAttribute(e);else{if(G&&!J&&"TEXTAREA"===t.tagName&&"placeholder"===e&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var tr={create:Qn,update:Qn};function er(t,e){var n=e.elm,i=e.data,a=t.data;if(!(r(i.staticClass)&&r(i.class)&&(r(a)||r(a.staticClass)&&r(a.class)))){var s=kn(e),c=n._transitionClasses;o(c)&&(s=En(s,jn(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var nr,rr={create:er,update:er},or="__r",ir="__c";function ar(t,e,n,r,o){var i;e=(i=e)._withTask||(i._withTask=function(){Jt=!0;var t=i.apply(null,arguments);return Jt=!1,t}),n&&(e=function(t,e,n){var r=nr;return function o(){null!==t.apply(null,arguments)&&sr(e,o,n,r)}}(e,t,r)),nr.addEventListener(t,e,Y?{capture:r,passive:o}:r)}function sr(t,e,n,r){(r||nr).removeEventListener(t,e._withTask||e,n)}function cr(t,e){if(!r(t.data.on)||!r(e.data.on)){var n=e.data.on||{},i=t.data.on||{};nr=e.elm,function(t){if(o(t[or])){var e=G?"change":"input";t[e]=[].concat(t[or],t[e]||[]),delete t[or]}o(t[ir])&&(t.change=[].concat(t[ir],t.change||[]),delete t[ir])}(n),ie(n,i,ar,sr,e.context),nr=void 0}}var ur={create:cr,update:cr};function fr(t,e){if(!r(t.data.domProps)||!r(e.data.domProps)){var n,i,a=e.elm,s=t.data.domProps||{},c=e.data.domProps||{};for(n in o(c.__ob__)&&(c=e.data.domProps=k({},c)),s)r(c[n])&&(a[n]="");for(n in c){if(i=c[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),i===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n){a._value=i;var u=r(i)?"":String(i);lr(a,u)&&(a.value=u)}else a[n]=i}}}function lr(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(o(r)){if(r.lazy)return!1;if(r.number)return d(n)!==d(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var pr={create:fr,update:fr},dr=g(function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach(function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}}),e});function vr(t){var e=hr(t.style);return t.staticStyle?k(t.staticStyle,e):e}function hr(t){return Array.isArray(t)?S(t):"string"==typeof t?dr(t):t}var mr,yr=/^--/,_r=/\s*!important$/,gr=function(t,e,n){if(yr.test(e))t.style.setProperty(e,n);else if(_r.test(n))t.style.setProperty(e,n.replace(_r,""),"important");else{var r=wr(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Or(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function $r(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&k(e,kr(t.name||"v")),k(e,t),e}return"string"==typeof t?kr(t):void 0}}var kr=g(function(t){return{enterClass:t+"-enter",enterToClass:t+"-enter-to",enterActiveClass:t+"-enter-active",leaveClass:t+"-leave",leaveToClass:t+"-leave-to",leaveActiveClass:t+"-leave-active"}}),Sr=z&&!J,Er="transition",jr="animation",Ir="transition",Tr="transitionend",Mr="animation",Dr="animationend";Sr&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Ir="WebkitTransition",Tr="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Mr="WebkitAnimation",Dr="webkitAnimationEnd"));var Pr=z?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function Nr(t){Pr(function(){Pr(t)})}function Lr(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Ar(t,e))}function Fr(t,e){t._transitionClasses&&m(t._transitionClasses,e),Or(t,e)}function Rr(t,e,n){var r=Br(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s=o===Er?Tr:Dr,c=0,u=function(){t.removeEventListener(s,f),n()},f=function(e){e.target===t&&++c>=a&&u()};setTimeout(function(){c0&&(n=Er,f=a,l=i.length):e===jr?u>0&&(n=jr,f=u,l=c.length):l=(n=(f=Math.max(a,u))>0?a>u?Er:jr:null)?n===Er?i.length:c.length:0,{type:n,timeout:f,propCount:l,hasTransform:n===Er&&Ur.test(r[Ir+"Property"])}}function Vr(t,e){for(;t.length1}function Gr(t,e){!0!==e.data.show&&zr(e)}var Jr=function(t){var e,n,s={},c=t.modules,u=t.nodeOps;for(e=0;ev?g(t,r(n[y+1])?null:n[y+1].elm,n,d,y,i):d>y&&w(0,e,p,v)}(c,d,v,n,a):o(v)?(o(t.text)&&u.setTextContent(c,""),g(c,null,v,0,v.length-1,n)):o(d)?w(0,d,0,d.length-1):o(t.text)&&u.setTextContent(c,""):t.text!==e.text&&u.setTextContent(c,e.text),o(p)&&o(f=p.hook)&&o(f=f.postpatch)&&f(t,e)}}}function O(t,e,n){if(i(n)&&o(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(T(to(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function Yr(t,e){return e.every(function(e){return!T(e,t)})}function to(t){return"_value"in t?t._value:t.value}function eo(t){t.target.composing=!0}function no(t){t.target.composing&&(t.target.composing=!1,ro(t.target,"input"))}function ro(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function oo(t){return!t.componentInstance||t.data&&t.data.transition?t:oo(t.componentInstance._vnode)}var io={model:Xr,show:{bind:function(t,e,n){var r=e.value,o=(n=oo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,zr(n,function(){t.style.display=i})):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=oo(n)).data&&n.data.transition?(n.data.show=!0,r?zr(n,function(){t.style.display=t.__vOriginalDisplay}):Wr(n,function(){t.style.display="none"})):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},ao={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function so(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?so(pe(e.children)):t}function co(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var i in o)e[w(i)]=o[i];return e}function uo(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var fo={name:"transition",props:ao,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(function(t){return t.tag||le(t)})).length){0;var r=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=so(o);if(!i)return o;if(this._leaving)return uo(t,o);var s="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?s+"comment":s+i.tag:a(i.key)?0===String(i.key).indexOf(s)?i.key:s+i.key:i.key;var c=(i.data||(i.data={})).transition=co(this),u=this._vnode,f=so(u);if(i.data.directives&&i.data.directives.some(function(t){return"show"===t.name})&&(i.data.show=!0),f&&f.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,f)&&!le(f)&&(!f.componentInstance||!f.componentInstance._vnode.isComment)){var l=f.data.transition=k({},c);if("out-in"===r)return this._leaving=!0,ae(l,"afterLeave",function(){e._leaving=!1,e.$forceUpdate()}),uo(t,o);if("in-out"===r){if(le(i))return u;var p,d=function(){p()};ae(c,"afterEnter",d),ae(c,"enterCancelled",d),ae(l,"delayLeave",function(t){p=t})}}return o}}},lo=k({tag:String,moveClass:String},ao);function po(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function vo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ho(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate("+r+"px,"+o+"px)",i.transitionDuration="0s"}}delete lo.mode;var mo={Transition:fo,TransitionGroup:{props:lo,render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=co(this),s=0;s-1?Pn[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Pn[t]=/HTMLUnknownElement/.test(e.toString())},k(ln.options.directives,io),k(ln.options.components,mo),ln.prototype.__patch__=z?Jr:E,ln.prototype.$mount=function(t,e){return function(t,e,n){return t.$el=e,t.$options.render||(t.$options.render=vt),xe(t,"beforeMount"),new Ie(t,function(){t._update(t._render(),n)},E,null,!0),n=!1,null==t.$vnode&&(t._isMounted=!0,xe(t,"mounted")),t}(this,t=t&&z?function(t){if("string"==typeof t){var e=document.querySelector(t);return e||document.createElement("div")}return t}(t):void 0,e)},z&&setTimeout(function(){F.devtools&&nt&&nt.emit("init",ln)},0),e.a=ln}).call(e,n("DuR2"))},"1kS7":function(t,e){e.f=Object.getOwnPropertySymbols},"3Eo+":function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},"52gC":function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},"77Pl":function(t,e,n){var r=n("EqjI");t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},"7KvD":function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},D2L2:function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},Dd8w:function(t,e,n){"use strict";e.__esModule=!0;var r,o=n("woOf"),i=(r=o)&&r.__esModule?r:{default:r};e.default=i.default||function(t){for(var e=1;ec;)r(s,n=e[c++])&&(~i(u,n)||u.push(n));return u}},MU5D:function(t,e,n){var r=n("R9M2");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},MmMw:function(t,e,n){var r=n("EqjI");t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},NpIQ:function(t,e){e.f={}.propertyIsEnumerable},ON07:function(t,e,n){var r=n("EqjI"),o=n("7KvD").document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},QRG4:function(t,e,n){var r=n("UuGF"),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},R4wc:function(t,e,n){var r=n("kM2E");r(r.S+r.F,"Object",{assign:n("To3L")})},R9M2:function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},S82l:function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},SfB7:function(t,e,n){t.exports=!n("+E39")&&!n("S82l")(function(){return 7!=Object.defineProperty(n("ON07")("div"),"a",{get:function(){return 7}}).a})},TcQ7:function(t,e,n){var r=n("MU5D"),o=n("52gC");t.exports=function(t){return r(o(t))}},To3L:function(t,e,n){"use strict";var r=n("lktj"),o=n("1kS7"),i=n("NpIQ"),a=n("sB3e"),s=n("MU5D"),c=Object.assign;t.exports=!c||n("S82l")(function(){var t={},e={},n=Symbol(),r="abcdefghijklmnopqrst";return t[n]=7,r.split("").forEach(function(t){e[t]=t}),7!=c({},t)[n]||Object.keys(c({},e)).join("")!=r})?function(t,e){for(var n=a(t),c=arguments.length,u=1,f=o.f,l=i.f;c>u;)for(var p,d=s(arguments[u++]),v=f?r(d).concat(f(d)):r(d),h=v.length,m=0;h>m;)l.call(d,p=v[m++])&&(n[p]=d[p]);return n}:c},UuGF:function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},V3tA:function(t,e,n){n("R4wc"),t.exports=n("FeBl").Object.assign},"VU/8":function(t,e){t.exports=function(t,e,n,r,o,i){var a,s=t=t||{},c=typeof t.default;"object"!==c&&"function"!==c||(a=t,s=t.default);var u,f="function"==typeof s?s.options:s;if(e&&(f.render=e.render,f.staticRenderFns=e.staticRenderFns,f._compiled=!0),n&&(f.functional=!0),o&&(f._scopeId=o),i?(u=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),r&&r.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(i)},f._ssrRegister=u):r&&(u=r),u){var l=f.functional,p=l?f.render:f.beforeCreate;l?(f._injectStyles=u,f.render=function(t,e){return u.call(e),p(t,e)}):f.beforeCreate=p?[].concat(p,u):[u]}return{esModule:a,exports:s,options:f}}},X8DO:function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},ax3d:function(t,e,n){var r=n("e8AB")("keys"),o=n("3Eo+");t.exports=function(t){return r[t]||(r[t]=o(t))}},e8AB:function(t,e,n){var r=n("7KvD"),o=r["__core-js_shared__"]||(r["__core-js_shared__"]={});t.exports=function(t){return o[t]||(o[t]={})}},evD5:function(t,e,n){var r=n("77Pl"),o=n("SfB7"),i=n("MmMw"),a=Object.defineProperty;e.f=n("+E39")?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return a(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},fkB2:function(t,e,n){var r=n("UuGF"),o=Math.max,i=Math.min;t.exports=function(t,e){return(t=r(t))<0?o(t+e,0):i(t,e)}},hJx8:function(t,e,n){var r=n("evD5"),o=n("X8DO");t.exports=n("+E39")?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},kM2E:function(t,e,n){var r=n("7KvD"),o=n("FeBl"),i=n("+ZMJ"),a=n("hJx8"),s=n("D2L2"),c=function(t,e,n){var u,f,l,p=t&c.F,d=t&c.G,v=t&c.S,h=t&c.P,m=t&c.B,y=t&c.W,_=d?o:o[e]||(o[e]={}),g=_.prototype,b=d?r:v?r[e]:(r[e]||{}).prototype;for(u in d&&(n=e),n)(f=!p&&b&&void 0!==b[u])&&s(_,u)||(l=f?b[u]:n[u],_[u]=d&&"function"!=typeof b[u]?n[u]:m&&f?i(l,r):y&&b[u]==l?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e.prototype=t.prototype,e}(l):h&&"function"==typeof l?i(Function.call,l):l,h&&((_.virtual||(_.virtual={}))[u]=l,t&c.R&&g&&!g[u]&&a(g,u,l)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},lOnJ:function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},lktj:function(t,e,n){var r=n("Ibhu"),o=n("xnc9");t.exports=Object.keys||function(t){return r(t,o)}},sB3e:function(t,e,n){var r=n("52gC");t.exports=function(t){return Object(r(t))}},"vFc/":function(t,e,n){var r=n("TcQ7"),o=n("QRG4"),i=n("fkB2");t.exports=function(t){return function(e,n,a){var s,c=r(e),u=o(c.length),f=i(a,u);if(t&&n!=n){for(;u>f;)if((s=c[f++])!=s)return!0}else for(;u>f;f++)if((t||f in c)&&c[f]===n)return t||f||0;return!t&&-1}}},woOf:function(t,e,n){t.exports={default:n("V3tA"),__esModule:!0}},xnc9:function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")}}); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vue-focuspoint-component 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-focuspoint-component", 3 | "version": "2.0.1", 4 | "description": "Set focus point on elements", 5 | "author": "EvodiaAut ", 6 | "main": "src/index.js", 7 | "directories": { 8 | "doc": "docs", 9 | "test": "test" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/EvodiaAut/vue-focuspoint-component.git" 14 | }, 15 | "keywords": [ 16 | "vue", 17 | "vuejs", 18 | "vue2", 19 | "vuejs2", 20 | "vue-component", 21 | "component", 22 | "javascript", 23 | "focuspoint" 24 | ], 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/EvodiaAut/vue-focuspoint-component/issues" 28 | }, 29 | "homepage": "https://github.com/EvodiaAut/vue-focuspoint-component", 30 | "scripts": { 31 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 32 | "start": "npm run dev", 33 | "unit": "jest --config test/unit/jest.conf.js --coverage", 34 | "test": "npm run unit", 35 | "lint": "eslint --ext .js,.vue src test/unit", 36 | "build": "node build/build.js" 37 | }, 38 | "dependencies": { 39 | "vue": "^2.5.2" 40 | }, 41 | "devDependencies": { 42 | "autoprefixer": "^7.1.2", 43 | "babel-core": "^6.22.1", 44 | "babel-eslint": "^8.2.1", 45 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 46 | "babel-jest": "^21.0.2", 47 | "babel-loader": "^7.1.1", 48 | "babel-plugin-dynamic-import-node": "^1.2.0", 49 | "babel-plugin-syntax-jsx": "^6.18.0", 50 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", 51 | "babel-plugin-transform-runtime": "^6.22.0", 52 | "babel-plugin-transform-vue-jsx": "^3.5.0", 53 | "babel-preset-env": "^1.3.2", 54 | "babel-preset-stage-2": "^6.22.0", 55 | "bootstrap": "^4.1.0", 56 | "chalk": "^2.0.1", 57 | "copy-webpack-plugin": "^4.0.1", 58 | "css-loader": "^0.28.0", 59 | "eslint": "^4.15.0", 60 | "eslint-config-neonblack": "^3.0.0", 61 | "eslint-friendly-formatter": "^3.0.0", 62 | "eslint-import-resolver-webpack": "^0.8.3", 63 | "eslint-loader": "^1.7.1", 64 | "eslint-plugin-import": "^2.7.0", 65 | "eslint-plugin-vue": "^4.0.0", 66 | "extract-text-webpack-plugin": "^3.0.0", 67 | "file-loader": "^1.1.4", 68 | "friendly-errors-webpack-plugin": "^1.6.1", 69 | "html-webpack-plugin": "^2.30.1", 70 | "jest": "^22.0.4", 71 | "jest-serializer-vue": "^0.3.0", 72 | "node-notifier": "^5.1.2", 73 | "node-sass": "^4.7.2", 74 | "optimize-css-assets-webpack-plugin": "^3.2.0", 75 | "ora": "^1.2.0", 76 | "portfinder": "^1.0.13", 77 | "postcss-import": "^11.0.0", 78 | "postcss-loader": "^2.0.8", 79 | "postcss-url": "^7.2.1", 80 | "rimraf": "^2.6.0", 81 | "sass-loader": "^6.0.7", 82 | "semver": "^5.3.0", 83 | "shelljs": "^0.7.6", 84 | "uglifyjs-webpack-plugin": "^1.1.1", 85 | "url-loader": "^0.5.8", 86 | "vue-jest": "^1.0.2", 87 | "vue-loader": "^13.3.0", 88 | "vue-style-loader": "^3.0.1", 89 | "vue-template-compiler": "^2.5.2", 90 | "vue-test-utils": "^1.0.0-beta.11", 91 | "webpack": "^3.6.0", 92 | "webpack-bundle-analyzer": "^3.3.2", 93 | "webpack-dev-server": "^2.9.1", 94 | "webpack-merge": "^4.1.0" 95 | }, 96 | "engines": { 97 | "node": ">= 6.0.0", 98 | "npm": ">= 3.0.0" 99 | }, 100 | "browserslist": [ 101 | "> 1%", 102 | "last 2 versions", 103 | "not ie <= 8" 104 | ] 105 | } 106 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 201 | 202 | 226 | 227 | 271 | -------------------------------------------------------------------------------- /src/assets/image_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvodiaAut/vue-focuspoint-component/3b807ca61b47bd75c567946e0033930dd6646e59/src/assets/image_1.jpg -------------------------------------------------------------------------------- /src/components/FocusPoint.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 79 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import FocusPoint from './components/FocusPoint' 2 | 3 | export default FocusPoint 4 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from '@/App' 3 | 4 | Vue.config.productionTip = false 5 | 6 | /* eslint-disable no-new */ 7 | new Vue({ 8 | el: '#app', 9 | ...App 10 | }) 11 | -------------------------------------------------------------------------------- /src/scss/_focus-point-theme.scss: -------------------------------------------------------------------------------- 1 | @import "focus-point-variables"; 2 | 3 | .focus-point { 4 | cursor: $focuspoint-cursor; 5 | 6 | &-pin { 7 | transition: $focuspoint-transition; 8 | padding: $focuspoint-padding; 9 | border-radius: $focuspoint-radius; 10 | background: $focuspoint-background; 11 | box-shadow:$focuspoint-shadow; 12 | border: $focuspoint-border; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/scss/_focus-point-variables.scss: -------------------------------------------------------------------------------- 1 | $focuspoint-cursor: pointer !default; 2 | $focuspoint-transition: all .2s ease-in-out !default; 3 | $focuspoint-padding: 10px !default; 4 | $focuspoint-radius: 5px !default; 5 | $focuspoint-background: rgba(255, 0, 0, .6) !default; 6 | $focuspoint-shadow: inset 0 0 3px rgba(0, 0, 0, .5) !default; 7 | $focuspoint-border: 1px solid #fff !default; 8 | -------------------------------------------------------------------------------- /src/scss/_focus-point.scss: -------------------------------------------------------------------------------- 1 | .focus-point { 2 | position: relative; 3 | 4 | &-pin { 5 | position: absolute; 6 | } 7 | 8 | * { 9 | pointer-events: none; 10 | user-select: none; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvodiaAut/vue-focuspoint-component/3b807ca61b47bd75c567946e0033930dd6646e59/static/.gitkeep -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true 4 | }, 5 | "globals": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/unit/jest.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | rootDir: path.resolve(__dirname, '../../'), 5 | moduleFileExtensions: [ 6 | 'js', 7 | 'json', 8 | 'vue' 9 | ], 10 | moduleNameMapper: { 11 | '^@/(.*)$': '/src/$1' 12 | }, 13 | transform: { 14 | '^.+\\.js$': '/node_modules/babel-jest', 15 | '.*\\.(vue)$': '/node_modules/vue-jest' 16 | }, 17 | snapshotSerializers: ['/node_modules/jest-serializer-vue'], 18 | setupFiles: ['/test/unit/setup'], 19 | mapCoverage: true, 20 | coverageDirectory: '/test/unit/coverage', 21 | collectCoverageFrom: [ 22 | 'src/components/**/*.{js,vue}', 23 | '!src/main.js', 24 | '!**/node_modules/**' 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /test/unit/setup.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | Vue.config.productionTip = false 4 | -------------------------------------------------------------------------------- /test/unit/specs/FocusPoint.spec.js: -------------------------------------------------------------------------------- 1 | import { shallow } from 'vue-test-utils' 2 | import FocusPoint from '@/components/FocusPoint' 3 | 4 | const propsData = { 5 | focus: { 6 | x: 94, 7 | y: 19 8 | } 9 | } 10 | 11 | describe('FocusPoint.vue', () => { 12 | it('should render correct contents', () => { 13 | const wrapper = shallow(FocusPoint, { propsData }) 14 | expect(wrapper.isVueInstance()).toBe(true) 15 | expect(wrapper.is('div')).toBe(true) 16 | expect(wrapper.props().focus).toBe(propsData.focus) 17 | expect(wrapper.props().default).toBe(wrapper.props().default) 18 | 19 | const pin = wrapper.find('.focus-point-pin') 20 | expect(pin.isVueInstance()).toBe(false) 21 | expect(pin.exists()).toBe(true) 22 | expect(pin.is('div')).toBe(true) 23 | expect(pin.classes()).toContain('focus-point-pin') 24 | 25 | // expect(pin.hasStyle('left', 'calc(94% - 11px)')).toBe(true) 26 | // expect(pin.hasStyle('top', 'calc(19% - 11px)')).toBe(true) 27 | }) 28 | }) 29 | --------------------------------------------------------------------------------