Commit a2e95692 authored by nature's avatar nature

Initial commit

parents
{
"presets": [
["env", {
"modules": false
}],
"stage-2"
],
"plugins": ["transform-runtime"]
}
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
build/
config/
static/
test/
dist/
src/assets/
src/libs/
!src/data/config/
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
// 指定环境
env: {
browser: true,
node: true,
jest: true,
es6: true,
},
// 全局变量
"globals": {
navigator: false,
cordova: false,
HandBridge: false,
process: true,
$config: true,
JMessagePlugin:true,
vum:true,
hlsPopup:true,
hlsHttp:true,
hlsUtil:true,
wx:true
},
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
extends: ['plugin:vue/recommended', 'standard'],
// required to lint *.vue files
plugins: ['vue', 'import'],
// check if imports actually resolve
settings: {
'import/resolver': {
webpack: {
config: 'build/webpack.base.conf.js'
}
}
},
// add your custom rules here
// "off" 或 0 - 关闭规则
// "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
// "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
rules: {
// 以下为自定义的 javascript 规则:
// 箭头函数当只有一个参数时允许省略圆括号
'arrow-parens': 0,
// 允许生成器
'generator-star-spacing': 0,
// 对象和数组结尾强制分号
"comma-dangle": [2, {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "ignore",
}],
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
"no-array-constructor": 0,
"no-irregular-whitespace": 0,
"no-new-wrappers": 0,
"no-alert": 0,
"no-eq-null": 2,
// 以下为自定义的 plugin-vue 规则:
// 单行中允许多个属性
"vue/max-attributes-per-line": ['error', {
"singleline": 4,
"multiline": {
"max": 4,
"allowFirstLine": false
}
}],
// 关闭属性名必须是 '-' 连接
"vue/attribute-hyphenation": 0,
"vue/require-v-for-key": 0,
// 以下为自定义的 plugin-import 规则:
// https://github.com/benmosher/eslint-plugin-import
// don't require .vue extension when importing
'import/extensions': ['error', 'always', {
js: 'never',
vue: 'never'
}],
// allow optionalDependencies
'import/no-extraneous-dependencies': ['error', {
optionalDependencies: ['test/unit/index.js']
}],
// 关闭必须默认输出
'import/prefer-default-export': ['off'],
}
}
.DS_Store
node_modules/
platforms/
www/
.idea/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*~
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
Thumbs.db
UserInterfaceState.xcuserstate
# OS X
.DS_Store
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
// to edit target browsers: use "browserslist" field in package.json
"postcss-import": {},
"autoprefixer": {}
}
}
*.min.css
iconfont.css
// https://stylelint.io/user-guide/configuration
module.exports = {
defaultSeverity: 'warning',
extends: 'stylelint-config-standard',
rules: {
'rule-empty-line-before': null,
'selector-list-comma-newline-after': 'always-multi-line',
},
};
# hls-car-vue
> A Vue.js project
## Build Setup
``` bash
# install dependencies
yarn install
# serve with hot reload at localhost:8080
yarn run dev
# build for production with minification
yarn run build
# build for production and view the bundle analyzer report
yarn run build --report
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
### 文件命名规范
1. 文件夹全部采用驼峰命名法,即首字母小写后面每个单词首字母大写
2. 文件名全部使用小写字母,单词与单词之间采用**-**连接,如 **user-info.vue,user-info-detail.vue**,
3. 路由的注册 `import` 语句后的单词采用 Pascal命名法,所有单词的首字母大写,其余字母小写,单词与单词之间不使用任何符号风格。如
路由全部按需加载,按照如下写法,路由后面的单词为打包后的js名称,按照模块进行分割打包,注意不要全部一样,那样没有任何意义
```javascript
const HomeManager = resolve => require.ensure([], () => { resolve(require('@/pages/homeManager/home-manager')) }, 'home')
const LoadMore = resolve => require.ensure([], () => { resolve(require('@/pages/loadMore/load-more')) }, 'loadMore')
const UserInfo = resolve => require.ensure([], () => { resolve(require('@/pages/userInfo/user-info')) }, 'userInfo')
const UserInfoDetail = resolve => require.ensure([], () => { resolve(require('@/pages/userInfo/user-info-detail')) }, 'userInfo')
```
4. 实际路由注册需安照如下写法,`path``/tab/文件名`,`/tab`是否保留视实际情况而定。`component`后接的单词需和`import`的单词保持一致,`name`后接的单词也需和`import`的单词保持一致
```javascript
{path: "/tab/home-manager", component: HomeManager, name: 'HomeManager', meta: {keepAlive: true}},
{path: '/tab/load-more', component: LoadMore, name: 'LoadMore', meta: {keepAlive: true}},
{path: '/tab/user-info', component: UserInfo, name: 'UserInfo', meta: {keepAlive: true}},
```
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
require('./check-versions')()
var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable
var app = express()
var compiler = webpack(webpackConfig)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
})
// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())
// serve webpack bundle output
app.use(devMiddleware)
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
var uri = 'http://localhost:' + port
var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
})
console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
})
var server = app.listen(port)
module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const pkg = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const px2remLoader = {
loader: 'px2rem-loader',
options: {
remUnit: options.remUnit,
},
};
var postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
//const loaders = options.usePostCSS ? [cssLoader, postcssLoader,px2remLoader] : [cssLoader]
let loaders = options.useFlexible ? [cssLoader, px2remLoader]: [cssLoader]
loaders = options.usePostCSS ? [...loaders, postcssLoader] : loaders
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath:'../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = function () {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') {
return
}
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: pkg.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
useFlexible: config.base.useFlexible,
remUnit: config.base.remUnit,
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: 'src',
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const vuxLoader = require('vux-loader')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
let webpackConfig = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'),resolve('node_modules/hls-easy-ui/packages')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
module.exports = vuxLoader.merge(webpackConfig, {
plugins: [
'vux-ui',
'progress-bar',
{
name: 'duplicate-style',
options: {
cssProcessorOptions : {
safe: true,
zindex: false,
autoprefixer: {
add: true,
browsers: [
'iOS >= 7',
'Android >= 4.1'
]
}
}
}
},
{name: 'less-theme', path: 'src/styles/variables.less'}
]
})
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: true,
hot: true,
compress: true,
host: process.env.HOST || config.dev.host,
port: process.env.PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay ? {
warnings: false,
errors: true,
} : false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env'),
$config: require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${config.dev.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
//console.log(config)
const env = require(`../config/${config.ENV}.env`)
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: false
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
$config: env,
}),
// UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: !env.debug,
drop_console: !env.debug
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// set the following option to `true` if you want to extract CSS from
// codesplit chunks into this main css file as well.
// This will result in *all* of your app's CSS being loaded upfront.
allChunks: false,
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vender modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: true,
isMobilePlatform: false,
hmapUrl:'"http://hippius.hand-china.com/hmap220"',
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"'
});
'use strict'
// Template version: 1.2.4
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
const CONFIG_ENV = process.env.CONFIG_ENV
module.exports = {
ENV:CONFIG_ENV,
base: {
// Use Flexible?
useFlexible: true,
remUnit: 50, // 启用flexible时的根字体大小(px)
// Use PostCSS?
usePostCSS: false,
},
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false,
ENV:CONFIG_ENV
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../www/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../www'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report,
ENV:CONFIG_ENV
}
}
'use strict'
module.exports = {
NODE_ENV: '"production"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: false,
isMobilePlatform: true,
hmapUrl:'"http://hippius.hand-china.com/hmap220"',
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"'
}
'use strict'
module.exports = {
NODE_ENV: '"production"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: true,
isMobilePlatform: true,
hmapUrl:'"http://hippius.hand-china.com/hmap220"',
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"'
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, width=device-width, viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="email=no">
<!-- safari私有meta标签 允许全屏模式浏览 指定safari顶部状态栏样式(黑色) -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<script type="text/javascript" src="./static/prototype.js"></script>
<title>车租易</title>
</head>
<body>
<div id="app-box"></div>
<!-- built files will be auto injected -->
</body>
</html>
{
"name": "vue-web-demo",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "nature <nature@sina.com>",
"private": true,
"scripts": {
"dev": "cross-env CONFIG_ENV=dev webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build:uat": "cross-env CONFIG_ENV=uat node build/build.js",
"build": "cross-env CONFIG_ENV=prod node build/build.js",
"clean": "rimraf www/*"
},
"dependencies": {
"autosize": "^3.0.20",
"better-scroll": "^1.10.3",
"hls-easy-ui": "https://hel.hand-china.com/easyUI/hls-easy-ui.git",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vux": "^2.9.2"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.1",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^5.2.0",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-import-resolver-webpack": "^0.8.3",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.5.0",
"eventsource-polyfill": "^0.9.6",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"less": "^2.7.1",
"less-loader": "^2.2.3",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"prelude-ls": "^1.1.2",
"px2rem-loader": "^0.1.9",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"style-loader": "^0.21.0",
"stylelint": "^8.0.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-webpack-plugin": "^0.10.4",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"url-loader": "^0.5.8",
"vconsole": "^3.2.0",
"vue-infinite-scroll": "^2.0.2",
"vue-loader": "^13.3.0",
"vue-loading-template": "^1.3.0",
"vue-slim-better-scroll": "^1.4.1",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"vux-loader": "^1.2.9",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-middleware": "^1.10.0",
"webpack-dev-server": "^2.9.1",
"webpack-hot-middleware": "^2.16.1",
"webpack-merge": "^4.1.0",
"yaml-loader": "^0.4.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"iOS >= 7",
"Android >= 4.1"
]
}
<template>
<div id="app">
<transition :name="transitionName">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
</transition>
<transition :name="transitionName">
<router-view v-if="!$route.meta.keepAlive"/>
</transition>
</div>
</template>
<script>
export default {
data () {
return {
pathList: [],
transitionName: 'router-slide-right',
}
},
watch: { // 监听路由变化
$route (to, from) {
if (this.pathList.includes(to.path)) {
const index = (this.pathList.findIndex(() => {
return from.path
}))
this.pathList.splice(index, 1)
this.$router.isBack = true
} else {
this.pathList.push(to.path)
this.$router.isBack = false
}
if (to.path === 'Home') {
this.$router.isBack = true
this.pathList = []
}
this.$router.isBack = false
},
},
mounted () {
},
methods: {
onSwipeLeft () {
this.$router.go(-1)
},
},
}
</script>
<style lang="less">
@import "styles/variables";
html, body, #app {
height: 100%;
width: 100%;
overflow-x: hidden;
}
</style>
### 此文件夹存放第三方js
/**
* 基础 mixins
*/
import { case2Param } from '../utils'
const preName = 'hls'
export default {
methods: {
/**
* 生成 css class helper
* c() // 'hls-componentName'
* c('wrap') // 'hls-componentName-wrap'
* c('wrap--active') // 'hls-componentName-wrap--active'
* @param {String} className 类名
* @returns String
*/
c (className) {
const { name } = this.$options // 组件名
return className ? `${preName}-${case2Param(name)}-${className}` : `${preName}-${case2Param(name)}`
},
},
}
import base from './base'
import prefix from './prefix'
import touch from './touch'
export {
base,
prefix,
touch,
}
const preName = 'hls'
export default {
methods: {
// 生成 css class
b (className) {
return className ? `${preName}-${className}` : ''
},
},
}
export default {
methods: {
onTouchStart (event) {
this.direction = ''
this.deltaX = 0
this.deltaY = 0
this.offsetX = 0
this.offsetY = 0
this.startX = event.touches[0].clientX
this.startY = event.touches[0].clientY
},
onTouchMove (event) {
const touch = event.touches[0]
this.deltaX = touch.clientX - this.startX
this.deltaY = touch.clientY - this.startY
this.offsetX = Math.abs(this.deltaX)
this.offsetY = Math.abs(this.deltaY)
this.direction = this.offsetX > this.offsetY ? 'horizontal' : this.offsetX < this.offsetY ? 'vertical' : ''
},
},
}
/*!
* =====================================================
* Mui v3.7.2 (http://dev.dcloud.net.cn/mui)
* =====================================================
*/
.mui-content
{
background-color: #efeff4;
-webkit-overflow-scrolling: touch;
}
.mui-bar-nav ~ .mui-content
{
padding-top: 44px;
}
.mui-bar-nav ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
{
top: 44px;
}
.mui-bar-header-secondary ~ .mui-content
{
padding-top: 88px;
}
.mui-bar-header-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
{
top: 88px;
}
.mui-bar-footer ~ .mui-content
{
padding-bottom: 44px;
}
.mui-bar-footer ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
{
bottom: 44px;
}
.mui-bar-footer-secondary ~ .mui-content
{
padding-bottom: 88px;
}
.mui-bar-footer-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
{
bottom: 88px;
}
.mui-bar-tab ~ .mui-content
{
padding-bottom: 50px;
}
.mui-bar-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
{
bottom: 50px;
}
.mui-bar-footer-secondary-tab ~ .mui-content
{
padding-bottom: 94px;
}
.mui-bar-footer-secondary-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
{
bottom: 94px;
}
.mui-content-padded
{
margin: 10px;
}
.mui-inline
{
display: inline-block;
vertical-align: top;
}
.mui-block
{
display: block !important;
}
.mui-visibility
{
visibility: visible !important;
}
.mui-hidden
{
display: none !important;
}
.mui-ellipsis
{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mui-ellipsis-2
{
display: -webkit-box;
overflow: hidden;
white-space: normal !important;
text-overflow: ellipsis;
word-wrap: break-word;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.mui-table
{
display: table;
width: 100%;
table-layout: fixed;
}
.mui-table-cell
{
position: relative;
display: table-cell;
}
.mui-text-left
{
text-align: left !important;
}
.mui-text-center
{
text-align: center !important;
}
.mui-text-justify
{
text-align: justify !important;
}
.mui-text-right
{
text-align: right !important;
}
.mui-pull-left
{
float: left;
}
.mui-pull-right
{
float: right;
}
.mui-list-unstyled
{
padding-left: 0;
list-style: none;
}
.mui-list-inline
{
margin-left: -5px;
padding-left: 0;
list-style: none;
}
.mui-list-inline > li
{
display: inline-block;
padding-right: 5px;
padding-left: 5px;
}
.mui-clearfix:before, .mui-clearfix:after
{
display: table;
content: ' ';
}
.mui-clearfix:after
{
clear: both;
}
.mui-bg-primary
{
background-color: #007aff;
}
.mui-bg-positive
{
background-color: #4cd964;
}
.mui-bg-negative
{
background-color: #dd524d;
}
.mui-error
{
margin: 88px 35px;
padding: 10px;
border-radius: 6px;
background-color: #bbb;
}
.mui-subtitle
{
font-size: 15px;
}
.mui-h1
{
font-size: 36px;
}
.mui-h2
{
font-size: 30px;
}
.mui-h3
{
font-size: 24px;
}
.mui-h4
{
font-size: 18px;
}
.mui-h5
{
font-size: 14px;
font-weight: normal;
color: #8f8f94;
}
.mui-h6
{
font-size: 12px;
font-weight: normal;
color: #8f8f94;
}
.mui-row:before, .mui-row:after
{
display: table;
content: ' ';
}
.mui-row:after
{
clear: both;
}
.mui-col-xs-1, .mui-col-sm-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-xs-12, .mui-col-sm-12
{
position: relative;
min-height: 1px;
}
.mui-row > [class*='mui-col-']
{
float: left;
}
.mui-col-xs-12
{
width: 100%;
}
.mui-col-xs-11
{
width: 91.66666667%;
}
.mui-col-xs-10
{
width: 83.33333333%;
}
.mui-col-xs-9
{
width: 75%;
}
.mui-col-xs-8
{
width: 66.66666667%;
}
.mui-col-xs-7
{
width: 58.33333333%;
}
.mui-col-xs-6
{
width: 50%;
}
.mui-col-xs-5
{
width: 41.66666667%;
}
.mui-col-xs-4
{
width: 33.33333333%;
}
.mui-col-xs-3
{
width: 25%;
}
.mui-col-xs-2
{
width: 16.66666667%;
}
.mui-col-xs-1
{
width: 8.33333333%;
}
@media (min-width: 400px)
{
.mui-col-sm-12
{
width: 100%;
}
.mui-col-sm-11
{
width: 91.66666667%;
}
.mui-col-sm-10
{
width: 83.33333333%;
}
.mui-col-sm-9
{
width: 75%;
}
.mui-col-sm-8
{
width: 66.66666667%;
}
.mui-col-sm-7
{
width: 58.33333333%;
}
.mui-col-sm-6
{
width: 50%;
}
.mui-col-sm-5
{
width: 41.66666667%;
}
.mui-col-sm-4
{
width: 33.33333333%;
}
.mui-col-sm-3
{
width: 25%;
}
.mui-col-sm-2
{
width: 16.66666667%;
}
.mui-col-sm-1
{
width: 8.33333333%;
}
}
.mui-scroll-wrapper
{
position: absolute;
z-index: 2;
top: 0;
bottom: 0;
left: 0;
overflow: hidden;
width: 100%;
}
.mui-scroll
{
position: absolute;
z-index: 1;
width: 100%;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.mui-scrollbar
{
position: absolute;
z-index: 9998;
overflow: hidden;
-webkit-transition: 500ms;
transition: 500ms;
transform: translateZ(0px);
pointer-events: none;
opacity: 0;
}
.mui-scrollbar-vertical
{
top: 0;
right: 1px;
bottom: 2px;
width: 4px;
}
.mui-scrollbar-vertical .mui-scrollbar-indicator
{
width: 100%;
}
.mui-scrollbar-horizontal
{
right: 2px;
bottom: 0;
left: 2px;
height: 4px;
}
.mui-scrollbar-horizontal .mui-scrollbar-indicator
{
height: 100%;
}
.mui-scrollbar-indicator
{
position: absolute;
display: block;
box-sizing: border-box;
-webkit-transition: .01s cubic-bezier(.1, .57, .1, 1);
transition: .01s cubic-bezier(.1, .57, .1, 1);
transform: translate(0px, 0px) translateZ(0px);
border: 1px solid rgba(255, 255, 255, .80196);
border-radius: 2px;
background: rgba(0, 0, 0, .39804);
}
.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper
{
position: absolute;
top: 0;
bottom: 0;
left: 0;
overflow: hidden;
width: 100%;
}
.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll
{
position: absolute;
width: 100%;
}
.mui-plus-pullrefresh .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-slider-group
{
position: static;
top: auto;
bottom: auto;
left: auto;
overflow: auto;
width: auto;
}
.mui-plus-pullrefresh .mui-slider-group
{
overflow: visible;
}
.mui-plus-pullrefresh .mui-scroll
{
position: static;
width: auto;
}
.mui-off-canvas-wrap .mui-bar
{
position: absolute !important;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-box-shadow: none;
box-shadow: none;
}
.mui-off-canvas-wrap
{
position: relative;
z-index: 1;
overflow: hidden;
width: 100%;
height: 100%;
}
.mui-off-canvas-wrap .mui-inner-wrap
{
position: relative;
z-index: 1;
width: 100%;
height: 100%;
}
.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning
{
-webkit-transition: -webkit-transform 350ms;
transition: transform 350ms cubic-bezier(.165, .84, .44, 1);
}
.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left
{
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right
{
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
.mui-off-canvas-wrap.mui-active
{
overflow: hidden;
height: 100%;
}
.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop
{
position: absolute;
z-index: 998;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
transition: background 350ms cubic-bezier(.165, .84, .44, 1);
background: rgba(0, 0, 0, .4);
box-shadow: -4px 0 4px rgba(0, 0, 0, .5), 4px 0 4px rgba(0, 0, 0, .5);
-webkit-tap-highlight-color: transparent;
}
.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right
{
z-index: 10000 !important;
-webkit-transform: translate3d(100%, 0px, 0px);
}
.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left
{
z-index: 10000 !important;
-webkit-transform: translate3d(-100%, 0px, 0px);
}
.mui-off-canvas-left, .mui-off-canvas-right
{
position: absolute;
z-index: -1;
top: 0;
bottom: 0;
visibility: hidden;
box-sizing: content-box;
width: 70%;
min-height: 100%;
background: #333;
-webkit-overflow-scrolling: touch;
}
.mui-off-canvas-left.mui-transitioning, .mui-off-canvas-right.mui-transitioning
{
-webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1);
transition: transform 350ms cubic-bezier(.165, .84, .44, 1);
}
.mui-off-canvas-left
{
left: 0;
}
.mui-off-canvas-right
{
right: 0;
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable
{
background-color: #333;
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
{
width: 80%;
-webkit-transform: scale(.8);
transform: scale(.8);
opacity: .1;
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left.mui-transitioning, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right.mui-transitioning
{
-webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
transition: transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left
{
-webkit-transform-origin: -100%;
transform-origin: -100%;
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
{
-webkit-transform-origin: 200%;
transform-origin: 200%;
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-inner-wrap
{
-webkit-transform: scale(.8);
transform: scale(.8);
}
.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-right
{
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
.mui-loading .mui-spinner
{
display: block;
margin: 0 auto;
}
.mui-spinner
{
display: inline-block;
width: 24px;
height: 24px;
-webkit-transform-origin: 50%;
transform-origin: 50%;
-webkit-animation: spinner-spin 1s step-end infinite;
animation: spinner-spin 1s step-end infinite;
}
.mui-spinner:after
{
display: block;
width: 100%;
height: 100%;
content: '';
background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\"0 0 120 120\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><defs><line id=\"l\" x1=\"60\" x2=\"60\" y1=\"7\" y2=\"27\" stroke=\"%236c6c6c\" stroke-width=\"11\" stroke-linecap=\"round\"/></defs><g><use xlink:href=\"%23l\" opacity=\".27\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(30 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(60 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(90 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(120 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(150 60,60)\"/><use xlink:href=\"%23l\" opacity=\".37\" transform=\"rotate(180 60,60)\"/><use xlink:href=\"%23l\" opacity=\".46\" transform=\"rotate(210 60,60)\"/><use xlink:href=\"%23l\" opacity=\".56\" transform=\"rotate(240 60,60)\"/><use xlink:href=\"%23l\" opacity=\".66\" transform=\"rotate(270 60,60)\"/><use xlink:href=\"%23l\" opacity=\".75\" transform=\"rotate(300 60,60)\"/><use xlink:href=\"%23l\" opacity=\".85\" transform=\"rotate(330 60,60)\"/></g></svg>');
background-repeat: no-repeat;
background-position: 50%;
background-size: 100%;
}
.mui-spinner-white:after
{
background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\"0 0 120 120\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><defs><line id=\"l\" x1=\"60\" x2=\"60\" y1=\"7\" y2=\"27\" stroke=\"%23fff\" stroke-width=\"11\" stroke-linecap=\"round\"/></defs><g><use xlink:href=\"%23l\" opacity=\".27\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(30 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(60 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(90 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(120 60,60)\"/><use xlink:href=\"%23l\" opacity=\".27\" transform=\"rotate(150 60,60)\"/><use xlink:href=\"%23l\" opacity=\".37\" transform=\"rotate(180 60,60)\"/><use xlink:href=\"%23l\" opacity=\".46\" transform=\"rotate(210 60,60)\"/><use xlink:href=\"%23l\" opacity=\".56\" transform=\"rotate(240 60,60)\"/><use xlink:href=\"%23l\" opacity=\".66\" transform=\"rotate(270 60,60)\"/><use xlink:href=\"%23l\" opacity=\".75\" transform=\"rotate(300 60,60)\"/><use xlink:href=\"%23l\" opacity=\".85\" transform=\"rotate(330 60,60)\"/></g></svg>');
}
@-webkit-keyframes spinner-spin
{
0%
{
-webkit-transform: rotate(0deg);
}
8.33333333%
{
-webkit-transform: rotate(30deg);
}
16.66666667%
{
-webkit-transform: rotate(60deg);
}
25%
{
-webkit-transform: rotate(90deg);
}
33.33333333%
{
-webkit-transform: rotate(120deg);
}
41.66666667%
{
-webkit-transform: rotate(150deg);
}
50%
{
-webkit-transform: rotate(180deg);
}
58.33333333%
{
-webkit-transform: rotate(210deg);
}
66.66666667%
{
-webkit-transform: rotate(240deg);
}
75%
{
-webkit-transform: rotate(270deg);
}
83.33333333%
{
-webkit-transform: rotate(300deg);
}
91.66666667%
{
-webkit-transform: rotate(330deg);
}
100%
{
-webkit-transform: rotate(360deg);
}
}
@keyframes spinner-spin
{
0%
{
transform: rotate(0deg);
}
8.33333333%
{
transform: rotate(30deg);
}
16.66666667%
{
transform: rotate(60deg);
}
25%
{
transform: rotate(90deg);
}
33.33333333%
{
transform: rotate(120deg);
}
41.66666667%
{
transform: rotate(150deg);
}
50%
{
transform: rotate(180deg);
}
58.33333333%
{
transform: rotate(210deg);
}
66.66666667%
{
transform: rotate(240deg);
}
75%
{
transform: rotate(270deg);
}
83.33333333%
{
transform: rotate(300deg);
}
91.66666667%
{
transform: rotate(330deg);
}
100%
{
transform: rotate(360deg);
}
}
.mui-btn
{
font-size: 14px;
font-weight: 400;
line-height: 1.42;
position: relative;
display: inline-block;
margin-bottom: 0;
padding: 6px 12px;
cursor: pointer;
-webkit-transition: all;
transition: all;
-webkit-transition-timing-function: linear;
transition-timing-function: linear;
-webkit-transition-duration: .2s;
transition-duration: .2s;
text-align: center;
vertical-align: top;
white-space: nowrap;
color: #333;
border: 1px solid #ccc;
border-radius: 3px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
background-color: #fff;
background-clip: padding-box;
}
.mui-btn:enabled:active,
.mui-btn.mui-active:enabled
{
color: #fff;
background-color: #929292;
}
.mui-btn:disabled,
.mui-btn.mui-disabled
{
opacity: .6;
}
.mui-btn-primary,
.mui-btn-blue
{
color: #fff;
border: 1px solid #007aff;
background-color: #007aff;
}
.mui-btn-primary:enabled:active,
.mui-btn-primary.mui-active:enabled,
.mui-btn-blue:enabled:active,
.mui-btn-blue.mui-active:enabled
{
color: #fff;
border: 1px solid #0062cc;
background-color: #0062cc;
}
.mui-btn-positive,
.mui-btn-success,
.mui-btn-green
{
color: #fff;
border: 1px solid #4cd964;
background-color: #4cd964;
}
.mui-btn-positive:enabled:active, .mui-btn-positive.mui-active:enabled,
.mui-btn-success:enabled:active,
.mui-btn-success.mui-active:enabled,
.mui-btn-green:enabled:active,
.mui-btn-green.mui-active:enabled
{
color: #fff;
border: 1px solid #2ac845;
background-color: #2ac845;
}
.mui-btn-warning,
.mui-btn-yellow
{
color: #fff;
border: 1px solid #f0ad4e;
background-color: #f0ad4e;
}
.mui-btn-warning:enabled:active, .mui-btn-warning.mui-active:enabled,
.mui-btn-yellow:enabled:active,
.mui-btn-yellow.mui-active:enabled
{
color: #fff;
border: 1px solid #ec971f;
background-color: #ec971f;
}
.mui-btn-negative,
.mui-btn-danger,
.mui-btn-red
{
color: #fff;
border: 1px solid #dd524d;
background-color: #dd524d;
}
.mui-btn-negative:enabled:active, .mui-btn-negative.mui-active:enabled,
.mui-btn-danger:enabled:active,
.mui-btn-danger.mui-active:enabled,
.mui-btn-red:enabled:active,
.mui-btn-red.mui-active:enabled
{
color: #fff;
border: 1px solid #cf2d28;
background-color: #cf2d28;
}
.mui-btn-royal,
.mui-btn-purple
{
color: #fff;
border: 1px solid #8a6de9;
background-color: #8a6de9;
}
.mui-btn-royal:enabled:active, .mui-btn-royal.mui-active:enabled,
.mui-btn-purple:enabled:active,
.mui-btn-purple.mui-active:enabled
{
color: #fff;
border: 1px solid #6641e2;
background-color: #6641e2;
}
.mui-btn-grey
{
color: #fff;
border: 1px solid #c7c7cc;
background-color: #c7c7cc;
}
.mui-btn-grey:enabled:active, .mui-btn-grey.mui-active:enabled
{
color: #fff;
border: 1px solid #acacb4;
background-color: #acacb4;
}
.mui-btn-outlined
{
background-color: transparent;
}
.mui-btn-outlined.mui-btn-primary, .mui-btn-outlined.mui-btn-blue
{
color: #007aff;
}
.mui-btn-outlined.mui-btn-positive, .mui-btn-outlined.mui-btn-success, .mui-btn-outlined.mui-btn-green
{
color: #4cd964;
}
.mui-btn-outlined.mui-btn-warning, .mui-btn-outlined.mui-btn-yellow
{
color: #f0ad4e;
}
.mui-btn-outlined.mui-btn-negative, .mui-btn-outlined.mui-btn-danger, .mui-btn-outlined.mui-btn-red
{
color: #dd524d;
}
.mui-btn-outlined.mui-btn-royal, .mui-btn-outlined.mui-btn-purple
{
color: #8a6de9;
}
.mui-btn-outlined.mui-btn-primary:enabled:active, .mui-btn-outlined.mui-btn-blue:enabled:active, .mui-btn-outlined.mui-btn-positive:enabled:active, .mui-btn-outlined.mui-btn-success:enabled:active, .mui-btn-outlined.mui-btn-green:enabled:active, .mui-btn-outlined.mui-btn-warning:enabled:active, .mui-btn-outlined.mui-btn-yellow:enabled:active, .mui-btn-outlined.mui-btn-negative:enabled:active, .mui-btn-outlined.mui-btn-danger:enabled:active, .mui-btn-outlined.mui-btn-red:enabled:active, .mui-btn-outlined.mui-btn-royal:enabled:active, .mui-btn-outlined.mui-btn-purple:enabled:active
{
color: #fff;
}
.mui-btn-link
{
padding-top: 6px;
padding-bottom: 6px;
color: #007aff;
border: 0;
background-color: transparent;
}
.mui-btn-link:enabled:active, .mui-btn-link.mui-active:enabled
{
color: #0062cc;
background-color: transparent;
}
.mui-btn-block
{
font-size: 18px;
display: block;
width: 100%;
margin-bottom: 10px;
padding: 15px 0;
}
.mui-btn .mui-badge
{
font-size: 14px;
margin: -2px -4px -2px 4px;
background-color: rgba(0, 0, 0, .15);
}
.mui-btn .mui-badge-inverted,
.mui-btn:enabled:active .mui-badge-inverted
{
background-color: transparent;
}
.mui-btn-primary:enabled:active .mui-badge-inverted,
.mui-btn-positive:enabled:active .mui-badge-inverted,
.mui-btn-negative:enabled:active .mui-badge-inverted
{
color: #fff;
}
.mui-btn-block .mui-badge
{
position: absolute;
right: 0;
margin-right: 10px;
}
.mui-btn .mui-icon
{
font-size: inherit;
}
.mui-btn.mui-icon
{
font-size: 14px;
line-height: 1.42;
}
.mui-btn.mui-fab
{
width: 56px;
height: 56px;
padding: 16px;
border-radius: 50%;
outline: none;
}
.mui-btn.mui-fab.mui-btn-mini
{
width: 40px;
height: 40px;
padding: 8px;
}
.mui-btn.mui-fab .mui-icon
{
font-size: 24px;
line-height: 24px;
width: 24px;
height: 24px;
}
.mui-btn .mui-spinner
{
width: 14px;
height: 14px;
vertical-align: text-bottom;
}
.mui-btn-block .mui-spinner
{
width: 22px;
height: 22px;
}
.mui-bar
{
position: fixed;
z-index: 10;
right: 0;
left: 0;
height: 44px;
padding-right: 10px;
padding-left: 10px;
border-bottom: 0;
background-color: #f7f7f7;
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .85);
box-shadow: 0 0 1px rgba(0, 0, 0, .85);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.mui-bar .mui-title
{
right: 40px;
left: 40px;
display: inline-block;
overflow: hidden;
width: auto;
margin: 0;
text-overflow: ellipsis;
}
.mui-bar .mui-backdrop
{
background: none;
}
.mui-bar-header-secondary
{
top: 44px;
}
.mui-bar-footer
{
bottom: 0;
}
.mui-bar-footer-secondary
{
bottom: 44px;
}
.mui-bar-footer-secondary-tab
{
bottom: 50px;
}
.mui-bar-footer,
.mui-bar-footer-secondary,
.mui-bar-footer-secondary-tab
{
border-top: 0;
}
.mui-bar-transparent
{
top: 0;
background-color: rgba(247, 247, 247, 0);
-webkit-box-shadow: none;
box-shadow: none;
}
.mui-bar-nav
{
top: 0;
-webkit-box-shadow: 0 1px 6px #ccc;
box-shadow: 0 1px 6px #ccc;
}
.mui-bar-nav ~ .mui-content .mui-anchor
{
display: block;
visibility: hidden;
height: 45px;
margin-top: -45px;
}
.mui-bar-nav.mui-bar .mui-icon
{
margin-right: -10px;
margin-left: -10px;
padding-right: 10px;
padding-left: 10px;
}
.mui-title
{
font-size: 17px;
font-weight: 500;
line-height: 44px;
position: absolute;
display: block;
width: 100%;
margin: 0 -10px;
padding: 0;
text-align: center;
white-space: nowrap;
color: #000;
}
.mui-title a
{
color: inherit;
}
.mui-bar-tab
{
bottom: 0;
display: table;
width: 100%;
height: 50px;
padding: 0;
table-layout: fixed;
border-top: 0;
border-bottom: 0;
-webkit-touch-callout: none;
}
.mui-bar-tab .mui-tab-item
{
display: table-cell;
overflow: hidden;
width: 1%;
height: 50px;
text-align: center;
vertical-align: middle;
white-space: nowrap;
text-overflow: ellipsis;
color: #929292;
}
.mui-bar-tab .mui-tab-item.mui-active
{
color: #007aff;
}
.mui-bar-tab .mui-tab-item .mui-icon
{
top: 3px;
width: 24px;
height: 24px;
padding-top: 0;
padding-bottom: 0;
}
.mui-bar-tab .mui-tab-item .mui-icon ~ .mui-tab-label
{
font-size: 11px;
display: block;
overflow: hidden;
text-overflow: ellipsis;
}
.mui-bar-tab .mui-tab-item .mui-icon:active
{
background: none;
}
.mui-focusin > .mui-bar-nav,
.mui-focusin > .mui-bar-header-secondary
{
position: absolute;
}
.mui-focusin > .mui-bar ~ .mui-content
{
padding-bottom: 0;
}
.mui-bar .mui-btn
{
font-weight: 400;
position: relative;
z-index: 20;
top: 7px;
margin-top: 0;
padding: 6px 12px 7px;
}
.mui-bar .mui-btn.mui-pull-right
{
margin-left: 10px;
}
.mui-bar .mui-btn.mui-pull-left
{
margin-right: 10px;
}
.mui-bar .mui-btn-link
{
font-size: 16px;
line-height: 44px;
top: 0;
padding: 0;
color: #007aff;
border: 0;
}
.mui-bar .mui-btn-link:active, .mui-bar .mui-btn-link.mui-active
{
color: #0062cc;
}
.mui-bar .mui-btn-block
{
font-size: 16px;
top: 6px;
margin-bottom: 0;
padding: 5px 0;
}
.mui-bar .mui-btn-nav.mui-pull-left
{
margin-left: -5px;
}
.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav
{
margin-right: -3px;
}
.mui-bar .mui-btn-nav.mui-pull-right
{
margin-right: -5px;
}
.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav
{
margin-left: -3px;
}
.mui-bar .mui-btn-nav:active
{
opacity: .3;
}
.mui-bar .mui-icon
{
font-size: 24px;
position: relative;
z-index: 20;
padding-top: 10px;
padding-bottom: 10px;
}
.mui-bar .mui-icon:active
{
opacity: .3;
}
.mui-bar .mui-btn .mui-icon
{
top: 1px;
margin: 0;
padding: 0;
}
.mui-bar .mui-title .mui-icon
{
margin: 0;
padding: 0;
}
.mui-bar .mui-title .mui-icon.mui-icon-caret
{
top: 4px;
margin-left: -5px;
}
.mui-bar input[type='search']
{
height: 29px;
margin: 6px 0;
}
.mui-bar .mui-input-row .mui-btn
{
padding: 12px 10px;
}
.mui-bar .mui-search:before
{
margin-top: -10px;
}
.mui-bar .mui-input-row .mui-input-clear ~ .mui-icon-clear,
.mui-bar .mui-input-row .mui-input-speech ~ .mui-icon-speech
{
top: 0;
right: 12px;
}
.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear ~ .mui-icon-clear,
.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech ~ .mui-icon-speech
{
top: 0;
right: 0;
}
.mui-bar .mui-segmented-control
{
top: 7px;
width: auto;
margin: 0 auto;
}
.mui-bar.mui-bar-header-secondary .mui-segmented-control
{
top: 0;
}
.mui-badge
{
font-size: 12px;
line-height: 1;
display: inline-block;
padding: 3px 6px;
color: #333;
border-radius: 100px;
background-color: rgba(0, 0, 0, .15);
}
.mui-badge.mui-badge-inverted
{
padding: 0 5px 0 0;
color: #929292;
background-color: transparent;
}
.mui-badge-primary, .mui-badge-blue
{
color: #fff;
background-color: #007aff;
}
.mui-badge-primary.mui-badge-inverted, .mui-badge-blue.mui-badge-inverted
{
color: #007aff;
background-color: transparent;
}
.mui-badge-success, .mui-badge-green
{
color: #fff;
background-color: #4cd964;
}
.mui-badge-success.mui-badge-inverted, .mui-badge-green.mui-badge-inverted
{
color: #4cd964;
background-color: transparent;
}
.mui-badge-warning, .mui-badge-yellow
{
color: #fff;
background-color: #f0ad4e;
}
.mui-badge-warning.mui-badge-inverted, .mui-badge-yellow.mui-badge-inverted
{
color: #f0ad4e;
background-color: transparent;
}
.mui-badge-danger, .mui-badge-red
{
color: #fff;
background-color: #dd524d;
}
.mui-badge-danger.mui-badge-inverted, .mui-badge-red.mui-badge-inverted
{
color: #dd524d;
background-color: transparent;
}
.mui-badge-royal, .mui-badge-purple
{
color: #fff;
background-color: #8a6de9;
}
.mui-badge-royal.mui-badge-inverted, .mui-badge-purple.mui-badge-inverted
{
color: #8a6de9;
background-color: transparent;
}
.mui-icon .mui-badge
{
font-size: 10px;
line-height: 1.4;
position: absolute;
top: -2px;
left: 100%;
margin-left: -10px;
padding: 1px 5px;
color: white;
background: red;
}
.mui-card
{
font-size: 14px;
position: relative;
overflow: hidden;
margin: 10px;
border-radius: 2px;
background-color: white;
background-clip: padding-box;
box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}
.mui-content > .mui-card:first-child
{
margin-top: 15px;
}
.mui-card .mui-input-group:before, .mui-card .mui-input-group:after
{
height: 0;
}
.mui-card .mui-input-group .mui-input-row:last-child:before, .mui-card .mui-input-group .mui-input-row:last-child:after
{
height: 0;
}
.mui-card .mui-table-view
{
margin-bottom: 0;
border-top: 0;
border-bottom: 0;
border-radius: 6px;
}
.mui-card .mui-table-view .mui-table-view-divider:first-child, .mui-card .mui-table-view .mui-table-view-cell:first-child
{
top: 0;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
.mui-card .mui-table-view .mui-table-view-divider:last-child, .mui-card .mui-table-view .mui-table-view-cell:last-child
{
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
}
.mui-card .mui-table-view:before, .mui-card .mui-table-view:after
{
height: 0;
}
.mui-card > .mui-table-view > .mui-table-view-cell:last-child:before, .mui-card > .mui-table-view > .mui-table-view-cell:last-child:after
{
height: 0;
}
.mui-card-header,
.mui-card-footer
{
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
min-height: 44px;
padding: 10px 15px;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
justify-content: space-between;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.mui-card-header .mui-card-link,
.mui-card-footer .mui-card-link
{
line-height: 44px;
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 44px;
margin-top: -10px;
margin-bottom: -10px;
-webkit-transition-duration: .3s;
transition-duration: .3s;
text-decoration: none;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
justify-content: flex-start;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.mui-card-header:after,
.mui-card-footer:before
{
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-card-header
{
font-size: 17px;
border-radius: 2px 2px 0 0;
}
.mui-card-header:after
{
top: auto;
bottom: 0;
}
.mui-card-header > img:first-child
{
font-size: 0;
line-height: 0;
float: left;
width: 34px;
height: 34px;
}
.mui-card-footer
{
color: #6d6d72;
border-radius: 0 0 2px 2px;
}
.mui-card-content
{
font-size: 14px;
position: relative;
}
.mui-card-content-inner
{
position: relative;
padding: 15px;
}
.mui-card-media
{
vertical-align: bottom;
color: #fff;
background-position: center;
background-size: cover;
}
.mui-card-header.mui-card-media
{
display: block;
padding: 10px;
}
.mui-card-header.mui-card-media .mui-media-body
{
font-size: 14px;
font-weight: 500;
line-height: 17px;
margin-bottom: 0;
margin-left: 44px;
color: #333;
}
.mui-card-header.mui-card-media .mui-media-body p
{
font-size: 13px;
margin-bottom: 0;
}
.mui-table-view
{
position: relative;
margin-top: 0;
margin-bottom: 0;
padding-left: 0;
list-style: none;
background-color: #fff;
}
.mui-table-view:after
{
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view:before
{
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view:before
{
top: -1px;
}
.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon
{
font-size: 20px;
margin-top: -1px;
margin-right: 5px;
margin-left: -5px;
}
.mui-table-view-icon .mui-table-view-cell:after
{
left: 40px;
}
.mui-table-view-chevron .mui-table-view-cell
{
padding-right: 65px;
}
.mui-table-view-chevron .mui-table-view-cell > a:not(.mui-btn)
{
margin-right: -65px;
}
.mui-table-view-radio .mui-table-view-cell
{
padding-right: 65px;
}
.mui-table-view-radio .mui-table-view-cell > a:not(.mui-btn)
{
margin-right: -65px;
}
.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after
{
font-size: 30px;
font-weight: 600;
right: 9px;
content: '';
color: #007aff;
}
.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after
{
content: '\e472';
}
.mui-table-view-inverted
{
color: #fff;
background: #333;
}
.mui-table-view-inverted:after
{
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #222;
}
.mui-table-view-inverted:before
{
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #222;
}
.mui-table-view-inverted .mui-table-view-cell:after
{
position: absolute;
right: 0;
bottom: 0;
left: 15px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #222;
}
.mui-table-view-inverted .mui-table-view-cell.mui-active
{
background-color: #242424;
}
.mui-table-view-inverted .mui-table-view-cell > a:not(.mui-btn).mui-active
{
background-color: #242424;
}
.mui-table-view-cell
{
position: relative;
overflow: hidden;
padding: 11px 15px;
-webkit-touch-callout: none;
}
.mui-table-view-cell:after
{
position: absolute;
right: 0;
bottom: 0;
left: 15px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view-cell.mui-radio input[type=radio], .mui-table-view-cell.mui-checkbox input[type=checkbox]
{
top: 8px;
}
.mui-table-view-cell.mui-radio.mui-left, .mui-table-view-cell.mui-checkbox.mui-left
{
padding-left: 58px;
}
.mui-table-view-cell.mui-active
{
background-color: #eee;
}
.mui-table-view-cell:last-child:before, .mui-table-view-cell:last-child:after
{
height: 0;
}
.mui-table-view-cell > a:not(.mui-btn)
{
position: relative;
display: block;
overflow: hidden;
margin: -11px -15px;
padding: inherit;
white-space: nowrap;
text-overflow: ellipsis;
color: inherit;
/*&:active {
background-color: #eee;
}*/
}
.mui-table-view-cell > a:not(.mui-btn).mui-active
{
background-color: #eee;
}
.mui-table-view-cell p
{
margin-bottom: 0;
}
.mui-table-view-cell.mui-transitioning > .mui-slider-handle, .mui-table-view-cell.mui-transitioning > .mui-slider-left .mui-btn, .mui-table-view-cell.mui-transitioning > .mui-slider-right .mui-btn
{
-webkit-transition: -webkit-transform 300ms ease;
transition: transform 300ms ease;
}
.mui-table-view-cell.mui-active > .mui-slider-handle
{
background-color: #eee;
}
.mui-table-view-cell > .mui-slider-handle
{
position: relative;
background-color: #fff;
}
.mui-table-view-cell > .mui-slider-handle.mui-navigate-right:after, .mui-table-view-cell > .mui-slider-handle .mui-navigate-right:after
{
right: 0;
}
.mui-table-view-cell > .mui-slider-handle, .mui-table-view-cell > .mui-slider-left .mui-btn, .mui-table-view-cell > .mui-slider-right .mui-btn
{
-webkit-transition: -webkit-transform 0ms ease;
transition: transform 0ms ease;
}
.mui-table-view-cell > .mui-slider-left, .mui-table-view-cell > .mui-slider-right
{
position: absolute;
top: 0;
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 100%;
}
.mui-table-view-cell > .mui-slider-left > .mui-btn, .mui-table-view-cell > .mui-slider-right > .mui-btn
{
position: relative;
left: 0;
display: -webkit-box;
display: -webkit-flex;
display: flex;
padding: 0 30px;
color: #fff;
border: 0;
border-radius: 0;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.mui-table-view-cell > .mui-slider-left > .mui-btn:after, .mui-table-view-cell > .mui-slider-right > .mui-btn:after
{
position: absolute;
z-index: -1;
top: 0;
width: 600%;
height: 100%;
content: '';
background: inherit;
}
.mui-table-view-cell > .mui-slider-left > .mui-btn.mui-icon, .mui-table-view-cell > .mui-slider-right > .mui-btn.mui-icon
{
font-size: 30px;
}
.mui-table-view-cell > .mui-slider-right
{
right: 0;
-webkit-transition: -webkit-transform 0ms ease;
transition: transform 0ms ease;
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
.mui-table-view-cell > .mui-slider-left
{
left: 0;
-webkit-transition: -webkit-transform 0ms ease;
transition: transform 0ms ease;
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
.mui-table-view-cell > .mui-slider-left > .mui-btn:after
{
right: 100%;
margin-right: -1px;
}
.mui-table-view-divider
{
font-weight: 500;
position: relative;
margin-top: -1px;
margin-left: 0;
padding-top: 6px;
padding-bottom: 6px;
padding-left: 15px;
color: #999;
background-color: #fafafa;
}
.mui-table-view-divider:after
{
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view-divider:before
{
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view .mui-media,
.mui-table-view .mui-media-body
{
overflow: hidden;
}
.mui-table-view .mui-media-large .mui-media-object
{
line-height: 80px;
max-width: 80px;
height: 80px;
}
.mui-table-view .mui-media .mui-subtitle
{
color: #000;
}
.mui-table-view .mui-media-object
{
line-height: 42px;
max-width: 42px;
height: 42px;
}
.mui-table-view .mui-media-object.mui-pull-left
{
margin-right: 10px;
}
.mui-table-view .mui-media-object.mui-pull-right
{
margin-left: 10px;
}
.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object
{
line-height: 29px;
max-width: 29px;
height: 29px;
margin: -4px 0;
}
.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img
{
line-height: 29px;
max-width: 29px;
height: 29px;
}
.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left
{
margin-right: 10px;
}
.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon
{
font-size: 29px;
}
.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after
{
position: absolute;
right: 0;
bottom: 0;
left: 55px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view .mui-table-view-cell.mui-media-icon:after
{
height: 0 !important;
}
.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view
{
display: block;
}
.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after
{
height: 0 !important;
}
.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after
{
position: absolute;
right: 0;
bottom: 0;
left: 70px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view-cell > .mui-btn,
.mui-table-view-cell > .mui-badge,
.mui-table-view-cell > .mui-switch,
.mui-table-view-cell > a > .mui-btn,
.mui-table-view-cell > a > .mui-badge,
.mui-table-view-cell > a > .mui-switch
{
position: absolute;
top: 50%;
right: 15px;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.mui-table-view-cell .mui-navigate-right > .mui-btn,
.mui-table-view-cell .mui-navigate-right > .mui-badge,
.mui-table-view-cell .mui-navigate-right > .mui-switch,
.mui-table-view-cell .mui-push-left > .mui-btn,
.mui-table-view-cell .mui-push-left > .mui-badge,
.mui-table-view-cell .mui-push-left > .mui-switch,
.mui-table-view-cell .mui-push-right > .mui-btn,
.mui-table-view-cell .mui-push-right > .mui-badge,
.mui-table-view-cell .mui-push-right > .mui-switch,
.mui-table-view-cell > a .mui-navigate-right > .mui-btn,
.mui-table-view-cell > a .mui-navigate-right > .mui-badge,
.mui-table-view-cell > a .mui-navigate-right > .mui-switch,
.mui-table-view-cell > a .mui-push-left > .mui-btn,
.mui-table-view-cell > a .mui-push-left > .mui-badge,
.mui-table-view-cell > a .mui-push-left > .mui-switch,
.mui-table-view-cell > a .mui-push-right > .mui-btn,
.mui-table-view-cell > a .mui-push-right > .mui-badge,
.mui-table-view-cell > a .mui-push-right > .mui-switch
{
right: 35px;
}
.mui-content > .mui-table-view:first-child
{
margin-top: 15px;
}
.mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view-cell.mui-collapse .mui-table-view:after
{
height: 0;
}
.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after
{
height: 0;
}
.mui-table-view-cell.mui-collapse > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse > .mui-push-right:after
{
content: '\e581';
}
.mui-table-view-cell.mui-collapse.mui-active
{
margin-top: -1px;
}
.mui-table-view-cell.mui-collapse.mui-active .mui-table-view, .mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content
{
display: block;
}
.mui-table-view-cell.mui-collapse.mui-active > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse.mui-active > .mui-push-right:after
{
content: '\e580';
}
.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell > a:not(.mui-btn).mui-active
{
margin-left: -31px;
padding-left: 47px;
}
.mui-table-view-cell.mui-collapse .mui-collapse-content
{
position: relative;
display: none;
overflow: hidden;
margin: 11px -15px -11px;
padding: 8px 15px;
-webkit-transition: height .35s ease;
-o-transition: height .35s ease;
transition: height .35s ease;
background: white;
}
.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-input-group, .mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
{
width: auto;
height: auto;
margin: -8px -15px;
}
.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
{
margin: -8px -16px;
}
.mui-table-view-cell.mui-collapse .mui-table-view
{
display: none;
margin-top: 11px;
margin-right: -15px;
margin-bottom: -11px;
margin-left: -15px;
border: 0;
}
.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron
{
margin-right: -65px;
}
.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell
{
padding-left: 31px;
background-position: 31px 100%;
}
.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after
{
position: absolute;
right: 0;
bottom: 0;
left: 30px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-table-view.mui-grid-view
{
font-size: 0;
display: block;
width: 100%;
padding: 0 10px 10px 0;
white-space: normal;
}
.mui-table-view.mui-grid-view .mui-table-view-cell
{
font-size: 17px;
display: inline-block;
margin-right: -4px;
padding: 10px 0 0 14px;
text-align: center;
vertical-align: middle;
background: none;
}
.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object
{
width: 100%;
max-width: 100%;
height: auto;
}
.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn)
{
margin: -10px 0 0 -14px;
}
.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn):active, .mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn).mui-active
{
background: none;
}
.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body
{
font-size: 15px;
line-height: 15px;
display: block;
width: 100%;
height: 15px;
margin-top: 8px;
text-overflow: ellipsis;
color: #333;
}
.mui-table-view.mui-grid-view .mui-table-view-cell:before, .mui-table-view.mui-grid-view .mui-table-view-cell:after
{
height: 0;
}
.mui-grid-view.mui-grid-9
{
margin: 0;
padding: 0;
border-top: 1px solid #eee;
border-left: 1px solid #eee;
background-color: #f2f2f2;
}
.mui-grid-view.mui-grid-9:before, .mui-grid-view.mui-grid-9:after
{
display: table;
content: ' ';
}
.mui-grid-view.mui-grid-9:after
{
clear: both;
}
.mui-grid-view.mui-grid-9:after
{
position: static;
}
.mui-grid-view.mui-grid-9 .mui-table-view-cell
{
margin: 0;
padding: 11px 15px;
vertical-align: top;
border-right: 1px solid #eee;
border-bottom: 1px solid #eee;
}
.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active
{
background-color: #eee;
}
.mui-grid-view.mui-grid-9 .mui-table-view-cell > a:not(.mui-btn)
{
margin: 0;
padding: 10px 0;
}
.mui-grid-view.mui-grid-9:before
{
height: 0;
}
.mui-grid-view.mui-grid-9 .mui-media
{
color: #797979;
}
.mui-grid-view.mui-grid-9 .mui-media .mui-icon
{
font-size: 2.4em;
position: relative;
}
.mui-slider-cell
{
position: relative;
}
.mui-slider-cell > .mui-slider-handle
{
z-index: 1;
}
.mui-slider-cell > .mui-slider-left, .mui-slider-cell > .mui-slider-right
{
position: absolute;
z-index: 0;
top: 0;
bottom: 0;
}
.mui-slider-cell > .mui-slider-left
{
left: 0;
}
.mui-slider-cell > .mui-slider-right
{
right: 0;
}
.mui-input-group
{
position: relative;
padding: 0;
border: 0;
background-color: #fff;
}
.mui-input-group:after
{
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-input-group:before
{
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-input-group input,
.mui-input-group textarea
{
margin-bottom: 0;
border: 0;
border-radius: 0;
background-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
}
.mui-input-group input[type='search']
{
background: none;
}
.mui-input-group input:last-child
{
background-image: none;
}
.mui-input-row
{
clear: left;
overflow: hidden;
}
.mui-input-row select
{
font-size: 17px;
height: 37px;
padding: 0;
}
.mui-input-row:last-child,
.mui-input-row label + input, .mui-input-row .mui-btn + input
{
background: none;
}
.mui-input-group .mui-input-row
{
height: 40px;
}
.mui-input-group .mui-input-row:after
{
position: absolute;
right: 0;
bottom: 0;
left: 15px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-input-row label
{
font-family: 'Helvetica Neue', Helvetica, sans-serif;
line-height: 1.1;
float: left;
width: 35%;
padding: 11px 15px;
}
.mui-input-row label ~ input, .mui-input-row label ~ select, .mui-input-row label ~ textarea
{
float: right;
width: 65%;
margin-bottom: 0;
padding-left: 0;
border: 0;
}
.mui-input-row .mui-btn
{
line-height: 1.1;
float: right;
width: 15%;
padding: 10px 15px;
}
.mui-input-row .mui-btn ~ input, .mui-input-row .mui-btn ~ select, .mui-input-row .mui-btn ~ textarea
{
float: left;
width: 85%;
margin-bottom: 0;
padding-left: 0;
border: 0;
}
.mui-button-row
{
position: relative;
padding-top: 5px;
text-align: center;
}
.mui-input-group .mui-button-row
{
height: 45px;
}
.mui-input-row
{
position: relative;
}
.mui-input-row.mui-input-range
{
overflow: visible;
padding-right: 20px;
}
.mui-input-row .mui-inline
{
padding: 8px 0;
}
.mui-input-row .mui-input-clear ~ .mui-icon-clear, .mui-input-row .mui-input-speech ~ .mui-icon-speech, .mui-input-row .mui-input-password ~ .mui-icon-eye
{
font-size: 20px;
position: absolute;
z-index: 1;
top: 10px;
right: 0;
width: 38px;
height: 38px;
text-align: center;
color: #999;
}
.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-active, .mui-input-row .mui-input-speech ~ .mui-icon-speech.mui-active, .mui-input-row .mui-input-password ~ .mui-icon-eye.mui-active
{
color: #007aff;
}
.mui-input-row .mui-input-speech ~ .mui-icon-speech
{
font-size: 24px;
top: 8px;
}
.mui-input-row .mui-input-clear ~ .mui-icon-clear ~ .mui-icon-speech
{
display: none;
}
.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-hidden ~ .mui-icon-speech
{
display: inline-block;
}
.mui-input-row .mui-icon-speech ~ .mui-placeholder
{
right: 38px;
}
.mui-input-row.mui-search .mui-icon-clear
{
top: 7px;
}
.mui-input-row.mui-search .mui-icon-speech
{
top: 5px;
}
.mui-radio, .mui-checkbox
{
position: relative;
}
.mui-select
{
position: relative;
}
.mui-select:before
{
font-family: Muiicons;
position: absolute;
top: 8px;
right: 21px;
content: '\e581';
color: rgba(170, 170, 170, .6);
}
.mui-input-row .mui-switch
{
float: right;
margin-top: 5px;
margin-right: 20px;
}
.mui-input-range
{
/*input[type="range"] {
-webkit-appearance: none;
background: #999;
height: 36px;
border-radius: 1px;
overflow: hidden;
margin-top: 2px;
margin-bottom: 2px;
outline:none;
position:relative;
width:100%;
}*/
/*input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none!important;
opacity: 0.5;
height:28px;
width:28px;
border-radius: 50%;
background:#00b7fb;
position: relative;
pointer-events: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
&:before{
position: absolute;
top: 13px;
left: -2000px;
width: 2000px;
height: 2px;
background: #00b7fb;
content:' ';
}
}*/
}
.mui-input-range input[type='range']
{
position: relative;
width: 100%;
height: 2px;
margin: 17px 0;
padding: 0;
cursor: pointer;
border: 0;
border-radius: 3px;
outline: none;
background-color: #999;
-webkit-appearance: none !important;
}
.mui-input-range input[type='range']::-webkit-slider-thumb
{
width: 28px;
height: 28px;
border-color: #0062cc;
border-radius: 50%;
background-color: #007aff;
background-clip: padding-box;
-webkit-appearance: none !important;
}
.mui-input-range label ~ input[type='range']
{
width: 65%;
}
.mui-input-range .mui-tooltip
{
font-size: 36px;
line-height: 64px;
position: absolute;
z-index: 1;
top: -70px;
width: 64px;
height: 64px;
text-align: center;
opacity: .8;
color: #333;
border: 1px solid #ddd;
border-radius: 6px;
background-color: #fff;
text-shadow: 0 1px 0 #f3f3f3;
}
.mui-search
{
position: relative;
}
.mui-search input[type='search']
{
padding-left: 30px;
}
.mui-search .mui-placeholder
{
font-size: 16px;
line-height: 34px;
position: absolute;
z-index: 1;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: inline-block;
height: 34px;
text-align: center;
color: #999;
border: 0;
border-radius: 6px;
background: none;
}
.mui-search .mui-placeholder .mui-icon
{
font-size: 20px;
color: #333;
}
.mui-search:before
{
font-family: Muiicons;
font-size: 20px;
font-weight: normal;
position: absolute;
top: 50%;
right: 50%;
display: none;
margin-top: -18px;
margin-right: 31px;
content: '\e466';
}
.mui-search.mui-active:before
{
font-size: 20px;
right: auto;
left: 5px;
display: block;
margin-right: 0;
}
.mui-search.mui-active input[type='search']
{
text-align: left;
}
.mui-search.mui-active .mui-placeholder
{
display: none;
}
.mui-segmented-control
{
font-size: 15px;
font-weight: 400;
position: relative;
display: table;
overflow: hidden;
width: 100%;
table-layout: fixed;
border: 1px solid #007aff;
border-radius: 3px;
background-color: transparent;
-webkit-touch-callout: none;
}
.mui-segmented-control.mui-segmented-control-vertical
{
border-collapse: collapse;
border-width: 0;
border-radius: 0;
}
.mui-segmented-control.mui-segmented-control-vertical .mui-control-item
{
display: block;
border-bottom: 1px solid #c8c7cc;
border-left-width: 0;
}
.mui-segmented-control.mui-scroll-wrapper
{
height: 38px;
}
.mui-segmented-control.mui-scroll-wrapper .mui-scroll
{
width: auto;
height: 40px;
white-space: nowrap;
}
.mui-segmented-control.mui-scroll-wrapper .mui-control-item
{
display: inline-block;
width: auto;
padding: 0 20px;
border: 0;
}
.mui-segmented-control .mui-control-item
{
line-height: 38px;
display: table-cell;
overflow: hidden;
width: 1%;
-webkit-transition: background-color .1s linear;
transition: background-color .1s linear;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
color: #007aff;
border-color: #007aff;
border-left: 1px solid #007aff;
}
.mui-segmented-control .mui-control-item:first-child
{
border-left-width: 0;
}
.mui-segmented-control .mui-control-item.mui-active
{
color: #fff;
background-color: #007aff;
}
.mui-segmented-control.mui-segmented-control-inverted
{
width: 100%;
border: 0;
border-radius: 0;
}
.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item
{
border-bottom: 1px solid #c8c7cc;
}
.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active
{
border-bottom: 1px solid #c8c7cc;
}
.mui-segmented-control.mui-segmented-control-inverted .mui-control-item
{
color: inherit;
border: 0;
}
.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
{
color: #007aff;
border-bottom: 2px solid #007aff;
background: none;
}
.mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-progress-bar
{
background-color: #007aff;
}
.mui-segmented-control-positive
{
border: 1px solid #4cd964;
}
.mui-segmented-control-positive .mui-control-item
{
color: #4cd964;
border-color: inherit;
}
.mui-segmented-control-positive .mui-control-item.mui-active
{
color: #fff;
background-color: #4cd964;
}
.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active
{
color: #4cd964;
border-bottom: 2px solid #4cd964;
background: none;
}
.mui-segmented-control-positive.mui-segmented-control-inverted ~ .mui-slider-progress-bar
{
background-color: #4cd964;
}
.mui-segmented-control-negative
{
border: 1px solid #dd524d;
}
.mui-segmented-control-negative .mui-control-item
{
color: #dd524d;
border-color: inherit;
}
.mui-segmented-control-negative .mui-control-item.mui-active
{
color: #fff;
background-color: #dd524d;
}
.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active
{
color: #dd524d;
border-bottom: 2px solid #dd524d;
background: none;
}
.mui-segmented-control-negative.mui-segmented-control-inverted ~ .mui-slider-progress-bar
{
background-color: #dd524d;
}
.mui-control-content
{
position: relative;
display: none;
}
.mui-control-content.mui-active
{
display: block;
}
.mui-popover
{
position: absolute;
z-index: 999;
display: none;
width: 280px;
-webkit-transition: opacity .3s;
transition: opacity .3s;
-webkit-transition-property: opacity;
transition-property: opacity;
-webkit-transform: none;
transform: none;
opacity: 0;
border-radius: 7px;
background-color: #f7f7f7;
-webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .1);
box-shadow: 0 0 15px rgba(0, 0, 0, .1);
}
.mui-popover .mui-popover-arrow
{
position: absolute;
z-index: 1000;
top: -25px;
left: 0;
overflow: hidden;
width: 26px;
height: 26px;
}
.mui-popover .mui-popover-arrow:after
{
position: absolute;
top: 19px;
left: 0;
width: 26px;
height: 26px;
content: ' ';
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
border-radius: 3px;
background: #f7f7f7;
}
.mui-popover .mui-popover-arrow.mui-bottom
{
top: 100%;
left: -26px;
margin-top: -1px;
}
.mui-popover .mui-popover-arrow.mui-bottom:after
{
top: -19px;
left: 0;
}
.mui-popover.mui-popover-action
{
bottom: 0;
width: 100%;
-webkit-transition: -webkit-transform .3s, opacity .3s;
transition: transform .3s, opacity .3s;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
border-radius: 0;
background: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.mui-popover.mui-popover-action .mui-popover-arrow
{
display: none;
}
.mui-popover.mui-popover-action.mui-popover-bottom
{
position: fixed;
}
.mui-popover.mui-popover-action.mui-active
{
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.mui-popover.mui-popover-action .mui-table-view
{
margin: 8px;
text-align: center;
color: #007aff;
border-radius: 4px;
}
.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after
{
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.mui-popover.mui-popover-action .mui-table-view small
{
font-weight: 400;
line-height: 1.3;
display: block;
}
.mui-popover.mui-active
{
display: block;
opacity: 1;
}
.mui-popover .mui-bar ~ .mui-table-view
{
padding-top: 44px;
}
.mui-backdrop
{
position: fixed;
z-index: 998;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, .3);
}
.mui-bar-backdrop.mui-backdrop
{
bottom: 50px;
background: none;
}
.mui-backdrop-action.mui-backdrop
{
background-color: rgba(0, 0, 0, .3);
}
.mui-bar-backdrop.mui-backdrop, .mui-backdrop-action.mui-backdrop
{
opacity: 0;
}
.mui-bar-backdrop.mui-backdrop.mui-active, .mui-backdrop-action.mui-backdrop.mui-active
{
-webkit-transition: all .4s ease;
transition: all .4s ease;
opacity: 1;
}
.mui-popover .mui-btn-block
{
margin-bottom: 5px;
}
.mui-popover .mui-btn-block:last-child
{
margin-bottom: 0;
}
.mui-popover .mui-bar
{
-webkit-box-shadow: none;
box-shadow: none;
}
.mui-popover .mui-bar-nav
{
border-bottom: 1px solid rgba(0, 0, 0, .15);
border-top-left-radius: 12px;
border-top-right-radius: 12px;
-webkit-box-shadow: none;
box-shadow: none;
}
.mui-popover .mui-scroll-wrapper
{
margin: 7px 0;
border-radius: 7px;
background-clip: padding-box;
}
.mui-popover .mui-scroll .mui-table-view
{
max-height: none;
}
.mui-popover .mui-table-view
{
overflow: auto;
max-height: 300px;
margin-bottom: 0;
border-radius: 7px;
background-color: #f7f7f7;
background-image: none;
-webkit-overflow-scrolling: touch;
}
.mui-popover .mui-table-view:before, .mui-popover .mui-table-view:after
{
height: 0;
}
.mui-popover .mui-table-view .mui-table-view-cell:first-child,
.mui-popover .mui-table-view .mui-table-view-cell:first-child > a:not(.mui-btn)
{
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
.mui-popover .mui-table-view .mui-table-view-cell:last-child,
.mui-popover .mui-table-view .mui-table-view-cell:last-child > a:not(.mui-btn)
{
border-bottom-right-radius: 12px;
border-bottom-left-radius: 12px;
}
.mui-popover.mui-bar-popover .mui-table-view
{
width: 106px;
}
.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell
{
padding: 11px 15px 11px 15px;
background-position: 0 100%;
}
.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell > a:not(.mui-btn)
{
margin: -11px -15px -11px -15px;
}
.mui-popup-backdrop
{
position: fixed;
z-index: 998;
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-transition-duration: 400ms;
transition-duration: 400ms;
opacity: 0;
background: rgba(0, 0, 0, .4);
}
.mui-popup-backdrop.mui-active
{
opacity: 1;
}
.mui-popup
{
position: fixed;
z-index: 10000;
top: 50%;
left: 50%;
display: none;
overflow: hidden;
width: 270px;
-webkit-transition-property: -webkit-transform,opacity;
transition-property: transform,opacity;
-webkit-transform: translate3d(-50%, -50%, 0) scale(1.185);
transform: translate3d(-50%, -50%, 0) scale(1.185);
text-align: center;
opacity: 0;
color: #000;
border-radius: 13px;
}
.mui-popup.mui-popup-in
{
display: block;
-webkit-transition-duration: 400ms;
transition-duration: 400ms;
-webkit-transform: translate3d(-50%, -50%, 0) scale(1);
transform: translate3d(-50%, -50%, 0) scale(1);
opacity: 1;
}
.mui-popup.mui-popup-out
{
-webkit-transition-duration: 400ms;
transition-duration: 400ms;
-webkit-transform: translate3d(-50%, -50%, 0) scale(1);
transform: translate3d(-50%, -50%, 0) scale(1);
opacity: 0;
}
.mui-popup-inner
{
position: relative;
padding: 15px;
border-radius: 13px 13px 0 0;
background: rgba(255, 255, 255, .95);
}
.mui-popup-inner:after
{
position: absolute;
z-index: 15;
top: auto;
right: auto;
bottom: 0;
left: 0;
display: block;
width: 100%;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
background-color: rgba(0, 0, 0, .2);
}
.mui-popup-title
{
font-size: 18px;
font-weight: 500;
text-align: center;
}
.mui-popup-title + .mui-popup-text
{
font-family: inherit;
font-size: 14px;
margin: 5px 0 0;
}
.mui-popup-buttons
{
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 44px;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.mui-popup-button
{
font-size: 17px;
line-height: 44px;
position: relative;
display: block;
overflow: hidden;
box-sizing: border-box;
width: 100%;
height: 44px;
padding: 0 5px;
cursor: pointer;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
color: #007aff;
background: rgba(255, 255, 255, .95);
-webkit-box-flex: 1;
}
.mui-popup-button:after
{
position: absolute;
z-index: 15;
top: 0;
right: 0;
bottom: auto;
left: auto;
display: block;
width: 1px;
height: 100%;
content: '';
-webkit-transform: scaleX(.5);
transform: scaleX(.5);
-webkit-transform-origin: 100% 50%;
transform-origin: 100% 50%;
background-color: rgba(0, 0, 0, .2);
}
.mui-popup-button:first-child
{
border-radius: 0 0 0 13px;
}
.mui-popup-button:first-child:last-child
{
border-radius: 0 0 13px 13px;
}
.mui-popup-button:last-child
{
border-radius: 0 0 13px 0;
}
.mui-popup-button:last-child:after
{
display: none;
}
.mui-popup-button.mui-popup-button-bold
{
font-weight: 600;
}
.mui-popup-input input
{
font-size: 14px;
width: 100%;
height: 26px;
margin: 15px 0 0;
padding: 0 5px;
border: 1px solid rgba(0, 0, 0, .3);
border-radius: 0;
background: #fff;
}
.mui-plus.mui-android .mui-popup-backdrop
{
-webkit-transition-duration: 1ms;
transition-duration: 1ms;
}
.mui-plus.mui-android .mui-popup
{
-webkit-transition-duration: 1ms;
transition-duration: 1ms;
-webkit-transform: translate3d(-50%, -50%, 0) scale(1);
transform: translate3d(-50%, -50%, 0) scale(1);
}
/* === Progress Bar === */
.mui-progressbar
{
position: relative;
display: block;
overflow: hidden;
width: 100%;
height: 2px;
-webkit-transform-origin: center top;
transform-origin: center top;
vertical-align: middle;
border-radius: 2px;
background: #b6b6b6;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.mui-progressbar span
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-transition: 150ms;
transition: 150ms;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
background: #007aff;
}
.mui-progressbar.mui-progressbar-infinite:before
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: '';
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-transform-origin: left center;
transform-origin: left center;
-webkit-animation: mui-progressbar-infinite 1s linear infinite;
animation: mui-progressbar-infinite 1s linear infinite;
background: #007aff;
}
body > .mui-progressbar
{
position: absolute;
z-index: 10000;
top: 44px;
left: 0;
border-radius: 0;
}
.mui-progressbar-in
{
-webkit-animation: mui-progressbar-in 300ms forwards;
animation: mui-progressbar-in 300ms forwards;
}
.mui-progressbar-out
{
-webkit-animation: mui-progressbar-out 300ms forwards;
animation: mui-progressbar-out 300ms forwards;
}
@-webkit-keyframes mui-progressbar-in
{
from
{
-webkit-transform: scaleY(0);
opacity: 0;
}
to
{
-webkit-transform: scaleY(1);
opacity: 1;
}
}
@keyframes mui-progressbar-in
{
from
{
transform: scaleY(0);
opacity: 0;
}
to
{
transform: scaleY(1);
opacity: 1;
}
}
@-webkit-keyframes mui-progressbar-out
{
from
{
-webkit-transform: scaleY(1);
opacity: 1;
}
to
{
-webkit-transform: scaleY(0);
opacity: 0;
}
}
@keyframes mui-progressbar-out
{
from
{
transform: scaleY(1);
opacity: 1;
}
to
{
transform: scaleY(0);
opacity: 0;
}
}
@-webkit-keyframes mui-progressbar-infinite
{
0%
{
-webkit-transform: translate3d(-50%, 0, 0) scaleX(.5);
}
100%
{
-webkit-transform: translate3d(100%, 0, 0) scaleX(.5);
}
}
@keyframes mui-progressbar-infinite
{
0%
{
transform: translate3d(-50%, 0, 0) scaleX(.5);
}
100%
{
transform: translate3d(100%, 0, 0) scaleX(.5);
}
}
.mui-pagination
{
display: inline-block;
margin: 0 auto;
padding-left: 0;
border-radius: 6px;
}
.mui-pagination > li
{
display: inline;
}
.mui-pagination > li > a,
.mui-pagination > li > span
{
line-height: 1.428571429;
position: relative;
float: left;
margin-left: -1px;
padding: 6px 12px;
text-decoration: none;
color: #007aff;
border: 1px solid #ddd;
background-color: #fff;
}
.mui-pagination > li:first-child > a,
.mui-pagination > li:first-child > span
{
margin-left: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
background-clip: padding-box;
}
.mui-pagination > li:last-child > a,
.mui-pagination > li:last-child > span
{
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
background-clip: padding-box;
}
.mui-pagination > li:active > a, .mui-pagination > li:active > a:active,
.mui-pagination > li:active > span,
.mui-pagination > li:active > span:active,
.mui-pagination > li.mui-active > a,
.mui-pagination > li.mui-active > a:active,
.mui-pagination > li.mui-active > span,
.mui-pagination > li.mui-active > span:active
{
z-index: 2;
cursor: default;
color: #fff;
border-color: #007aff;
background-color: #007aff;
}
.mui-pagination > li.mui-disabled > span,
.mui-pagination > li.mui-disabled > span:active,
.mui-pagination > li.mui-disabled > a,
.mui-pagination > li.mui-disabled > a:active
{
opacity: .6;
color: #777;
border: 1px solid #ddd;
background-color: #fff;
}
.mui-pagination-lg > li > a,
.mui-pagination-lg > li > span
{
font-size: 18px;
padding: 10px 16px;
}
.mui-pagination-sm > li > a,
.mui-pagination-sm > li > span
{
font-size: 12px;
padding: 5px 10px;
}
.mui-pager
{
padding-left: 0;
list-style: none;
text-align: center;
}
.mui-pager:before, .mui-pager:after
{
display: table;
content: ' ';
}
.mui-pager:after
{
clear: both;
}
.mui-pager li
{
display: inline;
}
.mui-pager li > a,
.mui-pager li > span
{
display: inline-block;
padding: 5px 14px;
border: 1px solid #ddd;
border-radius: 6px;
background-color: #fff;
background-clip: padding-box;
}
.mui-pager li:active > a, .mui-pager li:active > span, .mui-pager li.mui-active > a, .mui-pager li.mui-active > span
{
cursor: default;
text-decoration: none;
color: #fff;
border-color: #007aff;
background-color: #007aff;
}
.mui-pager .mui-next > a,
.mui-pager .mui-next > span
{
float: right;
}
.mui-pager .mui-previous > a,
.mui-pager .mui-previous > span
{
float: left;
}
.mui-pager .mui-disabled > a,
.mui-pager .mui-disabled > a:active,
.mui-pager .mui-disabled > span,
.mui-pager .mui-disabled > span:active
{
opacity: .6;
color: #777;
border: 1px solid #ddd;
background-color: #fff;
}
.mui-modal
{
position: fixed;
z-index: 999;
top: 0;
overflow: hidden;
width: 100%;
min-height: 100%;
-webkit-transition: -webkit-transform .25s, opacity 1ms .25s;
transition: transform .25s, opacity 1ms .25s;
-webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
transition-timing-function: cubic-bezier(.1, .5, .1, 1);
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
opacity: 0;
background-color: #fff;
}
.mui-modal.mui-active
{
height: 100%;
-webkit-transition: -webkit-transform .25s;
transition: transform .25s;
-webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
transition-timing-function: cubic-bezier(.1, .5, .1, 1);
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1;
}
.mui-android .mui-modal .mui-bar
{
position: static;
}
.mui-android .mui-modal .mui-bar-nav ~ .mui-content
{
padding-top: 0;
}
.mui-slider
{
position: relative;
z-index: 1;
overflow: hidden;
width: 100%;
}
.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
{
border-bottom: 0;
}
.mui-slider .mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-group .mui-slider-item
{
border-top: 1px solid #c8c7cc;
border-bottom: 1px solid #c8c7cc;
}
.mui-slider .mui-slider-group
{
font-size: 0;
position: relative;
-webkit-transition: all 0s linear;
transition: all 0s linear;
white-space: nowrap;
}
.mui-slider .mui-slider-group .mui-slider-item
{
font-size: 14px;
position: relative;
display: inline-block;
width: 100%;
height: 100%;
vertical-align: top;
white-space: normal;
}
.mui-slider .mui-slider-group .mui-slider-item > a:not(.mui-control-item)
{
line-height: 0;
position: relative;
display: block;
}
.mui-slider .mui-slider-group .mui-slider-item img
{
width: 100%;
}
.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before, .mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after
{
height: 0;
}
.mui-slider .mui-slider-group.mui-slider-loop
{
-webkit-transform: translate(-100%, 0px);
transform: translate(-100%, 0px);
}
.mui-slider-title
{
line-height: 30px;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 30px;
margin: 0;
text-align: left;
text-indent: 12px;
opacity: .8;
background-color: #000;
}
.mui-slider-indicator
{
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
background: none;
}
.mui-slider-indicator.mui-segmented-control
{
position: relative;
bottom: auto;
}
.mui-slider-indicator .mui-indicator
{
display: inline-block;
width: 6px;
height: 6px;
margin: 1px 6px;
cursor: pointer;
border-radius: 50%;
background: #aaa;
-webkit-box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
}
.mui-slider-indicator .mui-active.mui-indicator
{
background: #fff;
}
.mui-slider-indicator .mui-icon
{
font-size: 20px;
line-height: 30px;
width: 40px;
height: 30px;
margin: 3px;
text-align: center;
border: 1px solid #ddd;
}
.mui-slider-indicator .mui-number
{
line-height: 32px;
display: inline-block;
width: 58px;
}
.mui-slider-indicator .mui-number span
{
color: #ff5053;
}
.mui-slider-progress-bar
{
z-index: 1;
height: 2px;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.mui-switch
{
position: relative;
display: block;
width: 74px;
height: 30px;
-webkit-transition-timing-function: ease-in-out;
transition-timing-function: ease-in-out;
-webkit-transition-duration: .2s;
transition-duration: .2s;
-webkit-transition-property: background-color, border;
transition-property: background-color, border;
border: 2px solid #ddd;
border-radius: 20px;
background-color: #fff;
background-clip: padding-box;
}
.mui-switch.mui-disabled
{
opacity: .3;
}
.mui-switch .mui-switch-handle
{
position: absolute;
z-index: 1;
top: -1px;
left: -1px;
width: 28px;
height: 28px;
-webkit-transition: .2s ease-in-out;
transition: .2s ease-in-out;
-webkit-transition-property: -webkit-transform, width,left;
transition-property: transform, width,left;
border-radius: 16px;
background-color: #fff;
background-clip: padding-box;
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
}
.mui-switch:before
{
font-size: 13px;
position: absolute;
top: 3px;
right: 11px;
content: 'Off';
text-transform: uppercase;
color: #999;
}
.mui-switch.mui-dragging
{
border-color: #f7f7f7;
background-color: #f7f7f7;
}
.mui-switch.mui-dragging .mui-switch-handle
{
width: 38px;
}
.mui-switch.mui-dragging.mui-active .mui-switch-handle
{
left: -11px;
width: 38px;
}
.mui-switch.mui-active
{
border-color: #4cd964;
background-color: #4cd964;
}
.mui-switch.mui-active .mui-switch-handle
{
-webkit-transform: translate(43px, 0);
transform: translate(43px, 0);
}
.mui-switch.mui-active:before
{
right: auto;
left: 15px;
content: 'On';
color: #fff;
}
.mui-switch input[type='checkbox']
{
display: none;
}
.mui-switch-mini
{
width: 47px;
}
.mui-switch-mini:before
{
display: none;
}
.mui-switch-mini.mui-active .mui-switch-handle
{
-webkit-transform: translate(16px, 0);
transform: translate(16px, 0);
}
.mui-switch-blue.mui-active
{
border: 2px solid #007aff;
background-color: #007aff;
}
.mui-content.mui-fade
{
left: 0;
opacity: 0;
}
.mui-content.mui-fade.mui-in
{
opacity: 1;
}
.mui-content.mui-sliding
{
z-index: 2;
-webkit-transition: -webkit-transform .4s;
transition: transform .4s;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.mui-content.mui-sliding.mui-left
{
z-index: 1;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
.mui-content.mui-sliding.mui-right
{
z-index: 3;
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
.mui-navigate-right:after,
.mui-push-left:after,
.mui-push-right:after
{
font-family: Muiicons;
font-size: inherit;
line-height: 1;
position: absolute;
top: 50%;
display: inline-block;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
text-decoration: none;
color: #bbb;
-webkit-font-smoothing: antialiased;
}
.mui-push-left:after
{
left: 15px;
content: '\e582';
}
.mui-navigate-right:after,
.mui-push-right:after
{
right: 15px;
content: '\e583';
}
.mui-pull-top-pocket, .mui-pull-bottom-pocket
{
position: absolute;
left: 0;
display: block;
visibility: hidden;
overflow: hidden;
width: 100%;
height: 50px;
}
.mui-plus-pullrefresh .mui-pull-top-pocket, .mui-plus-pullrefresh .mui-pull-bottom-pocket
{
display: none;
visibility: visible;
}
.mui-pull-top-pocket
{
top: 0;
}
.mui-bar-nav ~ .mui-content .mui-pull-top-pocket
{
top: 44px;
}
.mui-bar-nav ~ .mui-bar-header-secondary ~ .mui-content .mui-pull-top-pocket
{
top: 88px;
}
.mui-pull-bottom-pocket
{
position: relative;
bottom: 0;
height: 40px;
}
.mui-pull-bottom-pocket .mui-pull-loading
{
visibility: hidden;
}
.mui-pull-bottom-pocket .mui-pull-loading.mui-in
{
display: inline-block;
}
.mui-pull
{
font-weight: bold;
position: absolute;
right: 0;
bottom: 10px;
left: 0;
text-align: center;
color: #777;
}
.mui-pull-loading
{
margin-right: 10px;
-webkit-transition: -webkit-transform .4s;
transition: transform .4s;
-webkit-transition-duration: 400ms;
transition-duration: 400ms;
vertical-align: middle;
}
.mui-pull-loading.mui-reverse
{
-webkit-transform: rotate(180deg) translateZ(0);
transform: rotate(180deg) translateZ(0);
}
.mui-pull-caption
{
font-size: 15px;
line-height: 24px;
position: relative;
display: inline-block;
overflow: visible;
margin-top: 0;
vertical-align: middle;
}
.mui-pull-caption span
{
display: none;
}
.mui-pull-caption span.mui-in
{
display: inline;
}
.mui-toast-container
{
line-height: 17px;
position: fixed;
z-index: 9999;
bottom: 50px;
left: 50%;
-webkit-transition: opacity .3s;
transition: opacity .3s;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
opacity: 0;
}
.mui-toast-container.mui-active
{
opacity: .9;
}
.mui-toast-message
{
font-size: 14px;
padding: 10px 25px;
text-align: center;
color: #fff;
border-radius: 6px;
background-color: #323232;
}
.mui-numbox
{
position: relative;
display: inline-block;
overflow: hidden;
width: 120px;
height: 35px;
padding: 0 40px 0 40px;
vertical-align: top;
vertical-align: middle;
border: solid 1px #bbb;
border-radius: 3px;
background-color: #efeff4;
}
.mui-numbox [class*=numbox-btn], .mui-numbox [class*=btn-numbox]
{
font-size: 18px;
font-weight: normal;
line-height: 100%;
position: absolute;
top: 0;
overflow: hidden;
width: 40px;
height: 100%;
padding: 0;
color: #555;
border: none;
border-radius: 0;
background-color: #f9f9f9;
}
.mui-numbox [class*=numbox-btn]:active, .mui-numbox [class*=btn-numbox]:active
{
background-color: #ccc;
}
.mui-numbox [class*=numbox-btn][disabled], .mui-numbox [class*=btn-numbox][disabled]
{
color: #c0c0c0;
}
.mui-numbox .mui-numbox-btn-plus, .mui-numbox .mui-btn-numbox-plus
{
right: 0;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
.mui-numbox .mui-numbox-btn-minus, .mui-numbox .mui-btn-numbox-minus
{
left: 0;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.mui-numbox .mui-numbox-input, .mui-numbox .mui-input-numbox
{
display: inline-block;
overflow: hidden;
width: 100% !important;
height: 100%;
margin: 0;
padding: 0 3px !important;
text-align: center;
text-overflow: ellipsis;
word-break: normal;
border: none !important;
border-right: solid 1px #ccc !important;
border-left: solid 1px #ccc !important;
border-radius: 0 !important;
}
.mui-input-row .mui-numbox
{
float: right;
margin: 2px 8px;
}
.mui-fullscreen
{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.mui-fullscreen.mui-slider .mui-slider-group
{
height: 100%;
}
.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
{
position: absolute;
top: 40px;
bottom: 0;
width: 100%;
height: auto;
}
.mui-fullscreen.mui-slider .mui-slider-item > a
{
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item > a
{
top: auto;
-webkit-transform: none;
transform: none;
}
.mui-bar-nav ~ .mui-content .mui-slider.mui-fullscreen
{
top: 44px;
}
.mui-bar-tab ~ .mui-content .mui-slider.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
{
bottom: 50px;
}
.mui-android.mui-android-4-0 input:focus,
.mui-android.mui-android-4-0 textarea:focus
{
-webkit-user-modify: inherit;
}
.mui-android.mui-android-4-2 input,
.mui-android.mui-android-4-2 textarea, .mui-android.mui-android-4-3 input,
.mui-android.mui-android-4-3 textarea
{
-webkit-user-select: text;
}
.mui-ios .mui-table-view-cell
{
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.mui-plus-visible, .mui-wechat-visible
{
display: none !important;
}
.mui-plus-hidden, .mui-wechat-hidden
{
display: block !important;
}
.mui-tab-item.mui-plus-hidden, .mui-tab-item.mui-wechat-hidden
{
display: table-cell !important;
}
.mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible
{
display: block !important;
}
.mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible
{
display: table-cell !important;
}
.mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden
{
display: none !important;
}
.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav
{
height: 64px;
padding-top: 20px;
}
.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content
{
padding-top: 64px;
}
.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content .mui-pull-top-pocket
{
top: 64px;
}
.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary
{
top: 64px;
}
.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary ~ .mui-content
{
padding-top: 94px;
}
.mui-iframe-wrapper
{
position: absolute;
right: 0;
left: 0;
-webkit-overflow-scrolling: touch;
}
.mui-iframe-wrapper iframe
{
width: 100%;
height: 100%;
border: 0;
}
/**
* 一些帮助函数
*/
/**
* setTimeout 的 promise 封装
* @param {Number} time
* @returns
*/
export function timeout (time) {
return new Promise(resolve => {
setTimeout(resolve, time)
})
}
/**
* 断言
* @param {any} condition 条件
* @param {any} msg 信息
*/
export function assert (condition, msg) {
if (!condition) throw new Error(`[hls-ui] ${msg}`)
}
/**
* 改变 case 格式为 param
* @param {String} str 字符串
*/
export function case2Param (str) {
assert(typeof str === 'string', 'case2Param 传入数据类型错误:应为 String')
str = str.replace(/^[A-Z]/g, $0 => $0.toLowerCase())
return str.replace(/[A-Z]/g, $0 => `-${$0.toLowerCase()}`)
}
/**
* 判断平台
* @return {String} 平台
*/
export function detectOS () {
const ua = navigator.userAgent.toLowerCase()
if (/MicroMessenger/i.test(ua)) {
return 'weixin'
} else if (/iPhone|iPad|iPod|iOS/i.test(ua)) {
return 'ios'
} else if (/Android/i.test(ua)) {
return 'android'
} else {
return 'other'
}
}
/**
* 取URL上的参数
* @param {String} param 参数名
* @return {String}
*/
export function getUrlParam (param) {
const result = window.location.href.match(new RegExp('(\\?|&)' + param + '(\\[\\])?=([^&#]*)'))
return result ? result[3] : undefined
}
/**
* 动态插入 script to html
* @param url
* @param callback
*/
export function createScript (url, callback) {
const oScript = document.createElement('script')
oScript.type = 'text/javascript'
oScript.async = true
oScript.src = url
/**
* IE6/7/8 -- onreadystatechange
* IE9/10 -- onreadystatechange, onload
* Firefox/Chrome/Opera -- onload
*/
const isIE = !-[1,] // eslint-disable-line
if (isIE) {
// 判断IE8及以下浏览器
oScript.onreadystatechange = function () {
if (this.readyState === 'loaded' || this.readyState === 'complete') {
callback && callback()
}
}
} else {
// IE9及以上浏览器,Firefox,Chrome,Opera
oScript.onload = function () {
callback && callback()
}
}
document.body.appendChild(oScript)
}
export function range (num, min, max) {
return Math.min(Math.max(num, min), max)
}
function trimExtraChar (value, char, regExp) {
const index = value.indexOf(char)
if (index === -1) {
return value
}
if (char === '-' && index !== 0) {
return value.slice(0, index)
}
return value.slice(0, index + 1) + value.slice(index).replace(regExp, '')
}
export function formatNumber (value, allowDot) {
if (value) {
if (allowDot) {
value = trimExtraChar(value, '.', /\./g)
} else {
value = value.split('.')[0]
}
value = trimExtraChar(value, '-', /-/g)
const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g
return value.replace(regExp, '')
}
}
export function isDef (val) {
return val !== undefined && val !== null && val !== ''
}
export function isUndefined (value) {
return Object.prototype.toString.call(value) === '[object Undefined]'
}
export function isString (value) {
return Object.prototype.toString.call(value) === '[object String]'
}
export function isNumber (value) {
return Object.prototype.toString.call(value) === '[object Number]'
}
export function isBoolean (value) {
return Object.prototype.toString.call(value) === '[object Boolean]'
}
export function isNull (value) {
return Object.prototype.toString.call(value) === '[object Null]'
}
export function isObject (value) {
return Object.prototype.toString.call(value) === '[object Object]'
}
export function isFunction (value) {
return Object.prototype.toString.call(value) === '[object Function]'
}
export function isArray (value) {
return Object.prototype.toString.call(value) === '[object Array]'
}
export function isDate (value) {
return Object.prototype.toString.call(value) === '[object Date]'
}
export function isRegExp (value) {
return Object.prototype.toString.call(value) === '[object RegExp]'
}
/* eslint-disable */
/**
* YDUI 可伸缩布局方案
* rem计算方式:设计图尺寸px / 50 = 实际rem 例: 100px = 2rem
*/
!(function(window) {
/* 设计图文档宽度 */
var docWidth = 750;
var doc = window.document,
docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var recalc = (function refreshRem() {
var clientWidth = docEl.getBoundingClientRect().width;
/* 8.55:小于320px不再缩小,11.2:大于420px不再放大 */
docEl.style.fontSize = Math.max(Math.min(20 * (clientWidth / docWidth), 11.2), 8.55) * 5 + 'px';
return refreshRem;
})();
/* 添加倍屏标识,安卓倍屏为1 */
docEl.setAttribute('data-dpr', window.navigator.appVersion.match(/iphone/gi) ? window.devicePixelRatio : 1);
if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) {
/* 添加IOS标识 */
doc.documentElement.classList.add('ios');
/* IOS8以上给html添加hairline样式,以便特殊处理 */
if (parseInt(window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/)[1], 10) >= 8) doc.documentElement.classList.add('hairline');
}
if (!doc.addEventListener) return;
window.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(window);
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// import FastClick from 'fastclick'
import App from './App'
import router from './router/index'
import flexible from './common/ydui.flexible'
import {componentInstall, appStyle} from 'hls-easy-ui'
/**
* 指令
*/
import directives from './scripts/directives'
import filter from './scripts/filter'
/**
* 弹框组件
*/
import hlsPopup from './scripts/hlsPopup'
/**
* http
*/
import {post, get} from './scripts/hlsHttp'
/** 全局函数hlsUtil**/
import hlsUtil from './scripts/hlsUtil'
if (process.env.CONFIG_ENV === 'uat') {
const VConsole = require('vconsole')
new VConsole() // eslint-disable-line
}
Vue.use(directives)
Vue.use(filter)
/**
* 组件
*/
Vue.use(componentInstall)
Vue.use(appStyle)
Vue.use(flexible)
Vue.prototype.hlsPopup = window.hlsPopup = hlsPopup
Vue.prototype.$devicePixelRatio = 2
let hlsHttp = {
get: get,
post: post,
}
Vue.prototype.hlsHttp = window.hlsHttp = hlsHttp
Vue.prototype.hlsUtil = window.hlsUtil = hlsUtil
/** end**/
/**
* 全局返回上一页面
* @param index
*/
let routeGo = function (index) {
if (!index) {
index = -1
}
this.$router.go(index)
}
Vue.prototype.$routeGo = routeGo
/*let hlsExit = function () {
if (vum.Platform.isIOS()) {
cordova.exec(null, null, 'BridgePlugin', 'closeWebView', [])
} else {
var dict = {
'className': 'WebBridge',
'function': 'close',
'successCallBack': 'sCallBack',
'failureCallBack': 'eCallBack',
}
HandBridge.postMessage(JSON.stringify(dict))
}
}
Vue.prototype.$hlsExit = hlsExit*/
// FastClick.attach(document.body)
Vue.config.productionTip = true
/* eslint-disable no-new */
new Vue({
data () {
return {
pathList: [],
transitionName: null,
}
},
router,
watch: { // 监听路由变化
$route (to, from) {
document.body.scrollTop = 0
document.documentElement.scrollTop = 0
},
},
render: h => h(App),
}).$mount('#app-box')
<template>
<h-view id="home" class="public-style" title="车租易" >
<h-header>
<div slot="left" class="h-header-btn" @click="$hlsExit()">
<i class="ion-ios-arrow-back"/>
</div>
<div slot="center">车租易</div>
</h-header>
<s-tab :show-divider="true" :defaultActive="1" @tabClick="tabClick">
<tab-item>APP</tab-item>
<tab-item>Vue</tab-item>
</s-tab>
<h-content>
<div class="icon">
<img src="@/assets/image/icon.png">
</div>
<h3>Welcome to Your Vue.js App</h3>
<h-file :file-list="fileList" v-model="fileList"/>
</h-content>
</h-view>
</template>
<script>
export default {
data () {
return {
fileList: [],
}
},
activated: function () {
},
updated: function () {
},
methods: {
tabClick (index) {
console.log(index)
},
},
}
</script>
<style lang="less" scoped type="text/less">
#home {
.content{
display: flex;
align-items: center;
flex-direction: column;
font-size: 24px;
.icon{
margin-top: 60px;
margin-bottom: 20px;
width: 100px;
height: 100px;
img{
width: 100%;
border-radius: 18px;
}
}
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios {
#home{
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.platform-ios {
#home{
}
}
}
}
</style>
import Vue from 'vue'
import Router from 'vue-router'
const Home = resolve => require.ensure([], () => { resolve(require('@/pages/home')) }, 'home')
Vue.use(Router)
// 全局跳转路由方法
Router.prototype.pushPage = function (param, bool) {
let key = true
if (bool === undefined) {
key = true
} else if (bool === true || bool === false) {
key = bool
}
this.currentRoute.meta.nextReload = key
this.push(param)
}
export default new Router({
routes: [
{
path: '/',
redirect: '/home',
},
{path: '/home', component: Home, name: 'Home', meta: {keepAlive: true}},
],
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash,
}
}
},
})
import Autosize from 'autosize'
function vueTouch (el, binding, type) {
var _this = this
this.obj = el
this.binding = binding
this.touchType = type
this.vueTouches = {x: 0, y: 0}
this.vueMoves = true
this.vueLeave = true
this.longTouch = true
this.vueCallBack = typeof (binding.value) === 'object' ? binding.value.fn : binding.value
this.obj.addEventListener('touchstart', function (e) {
_this.start(e)
}, false)
this.obj.addEventListener('touchend', function (e) {
_this.end(e)
}, false)
this.obj.addEventListener('touchmove', function (e) {
_this.move(e)
}, false)
};
vueTouch.prototype = {
start: function (e) {
this.vueMoves = true
this.vueLeave = true
this.longTouch = true
this.vueTouches = {x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY}
this.time = setTimeout(function () {
if (this.vueLeave && this.vueMoves) {
this.touchType === 'longtap' && this.vueCallBack(this.binding.value, e)
this.longTouch = false
}
}.bind(this), 1000)
},
end: function (e) {
var disX = e.changedTouches[0].pageX - this.vueTouches.x
var disY = e.changedTouches[0].pageY - this.vueTouches.y
clearTimeout(this.time)
if (Math.abs(disX) > 100 || Math.abs(disY) > 100) {
this.touchType === 'swipe' && this.vueCallBack(this.binding.value, e)
if (Math.abs(disX) > Math.abs(disY)) {
if (disX > 100) {
this.touchType === 'swiperight' && this.vueCallBack(this.binding.value, e)
}
if (disX < -100) {
this.touchType === 'swipeleft' && this.vueCallBack(this.binding.value, e)
}
} else {
if (disY > 100) {
this.touchType === 'swipedown' && this.vueCallBack(this.binding.value, e)
}
if (disY < -100) {
this.touchType === 'swipeup' && this.vueCallBack(this.binding.value, e)
}
}
} else {
if (this.longTouch && this.vueMoves) {
this.touchType === 'tap' && this.vueCallBack(this.binding.value, e)
this.vueLeave = false
}
}
},
move: function (e) {
this.vueMoves = false
},
} // prop.autosize
export default (Vue) => {
Vue.directive('focus', {
// 自动获取鼠标焦点
inserted: function (el) {
el.focus()
},
})
Vue.directive('tap', {// 点击事件
bind: function (el, binding) {
new vueTouch(el, binding, 'tap') // eslint-disable-line
},
})
Vue.directive('swipe', {// 滑动事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipe') // eslint-disable-line
},
})
Vue.directive('swipeleft', {// 左滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipeleft') // eslint-disable-line
},
})
Vue.directive('swiperight', {// 右滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swiperight') // eslint-disable-line
},
})
Vue.directive('swipedown', {// 下滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipedown') // eslint-disable-line
},
})
Vue.directive('swipeup', {// 上滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipeup') // eslint-disable-line
},
})
Vue.directive('longtap', {// 长按事件
bind: function (el, binding) {
new vueTouch(el, binding, 'longtap') // eslint-disable-line
},
})
Vue.directive('hlsImgZoom', {
componentUpdated: function (element) {
var elWidth, elHeight
// mode : 'pinch' or 'swipe'
var mode = ''
// distance between two touche points (mode : 'pinch')
var distance = 0
var initialDistance = 0
// image scaling
var scale = 1
var relativeScale = 1
var initialScale = 1
var maxScale = 5
if (isNaN(maxScale) || maxScale <= 1) {
maxScale = 3
}
// position of the upper left corner of the element
var positionX = 0
var positionY = 0
var initialPositionX = 0
var initialPositionY = 0
// central origin (mode : 'pinch')
var originX = 0
var originY = 0
// start coordinate and amount of movement (mode : 'swipe')
var startX = 0
var startY = 0
var moveX = 0
var moveY = 0
var image = new Image()
image.onload = function () {
elWidth = element.clientWidth
elHeight = element.clientHeight
element.style.webkitTransformOrigin = '0px 0px 0px'
element.style.transformOrigin = '0px 0px 0px'
element.addEventListener('touchstart', touchstartHandler)
element.addEventListener('touchmove', touchmoveHandler)
element.addEventListener('touchend', touchendHandler)
}
image.src = element.src
/**
* @param {object} evt
*/
function touchstartHandler (evt) {
var touches = evt.originalEvent ? evt.originalEvent.touches : evt.touches
startX = touches[0].clientX
startY = touches[0].clientY
initialPositionX = positionX
initialPositionY = positionY
moveX = 0
moveY = 0
}
/**
* @param {object} evt
*/
function touchmoveHandler (evt) {
var touches = evt.originalEvent ? evt.originalEvent.touches : evt.touches
if (mode === '') {
if (touches.length === 1 && scale > 1) {
mode = 'swipe'
} else if (touches.length === 2) {
mode = 'pinch'
initialScale = scale
initialDistance = getDistance(touches)
originX = touches[0].clientX -
parseInt((touches[0].clientX - touches[1].clientX) / 2, 10) -
element.offsetLeft - initialPositionX
originY = touches[0].clientY -
parseInt((touches[0].clientY - touches[1].clientY) / 2, 10) -
element.offsetTop - initialPositionY
}
}
if (mode === 'swipe') {
evt.preventDefault()
moveX = touches[0].clientX - startX
moveY = touches[0].clientY - startY
positionX = initialPositionX + moveX
positionY = initialPositionY + moveY
transformElement()
} else if (mode === 'pinch') {
evt.preventDefault()
distance = getDistance(touches)
relativeScale = distance / initialDistance
scale = relativeScale * initialScale
positionX = originX * (1 - relativeScale) + initialPositionX + moveX
positionY = originY * (1 - relativeScale) + initialPositionY + moveY
transformElement()
}
}
/**
* @param {object} evt
*/
function touchendHandler (evt) {
var touches = evt.originalEvent ? evt.originalEvent.touches : evt.touches
if (mode === '' || touches.length > 0) {
return
}
if (scale < 1) {
scale = 1
positionX = 0
positionY = 0
} else if (scale > maxScale) {
scale = maxScale
relativeScale = scale / initialScale
positionX = originX * (1 - relativeScale) + initialPositionX + moveX
positionY = originY * (1 - relativeScale) + initialPositionY + moveY
} else {
if (positionX > 0) {
positionX = 0
} else if (positionX < elWidth * (1 - scale)) {
positionX = elWidth * (1 - scale)
}
if (positionY > 0) {
positionY = 0
} else if (positionY < elHeight * (1 - scale)) {
positionY = elHeight * (1 - scale)
}
}
transformElement(0.1)
mode = ''
}
/**
* @param {Array} touches
* @return {number}
*/
function getDistance (touches) {
var d = Math.sqrt(Math.pow(touches[0].clientX - touches[1].clientX, 2) +
Math.pow(touches[0].clientY - touches[1].clientY, 2))
return parseInt(d, 10)
}
/**
* @param {number} [duration]
*/
function transformElement (duration) {
var transition = duration ? 'all cubic-bezier(0,0,.5,1) ' + duration + 's' : ''
var matrixArray = [scale, 0, 0, scale, positionX, positionY]
var matrix = 'matrix(' + matrixArray.join(',') + ')'
element.style.webkitTransition = transition
element.style.transition = transition
element.style.webkitTransform = matrix + ' translate3d(0,0,0)'
element.style.transform = matrix + ' translate3d(0,0,0)'
}
},
})
Vue.directive('keyboardAttach', {// 监听键盘
inserted: function (el, binding) {
let KEYBOARD_OPEN_CSS = 'foot-keyboard-open'
function keyboardHeight () {
let innerHeight = window.innerHeight
let innerWidth = window.innerWidth
if (vum.Platform.isIOS()) {
if (!vum.Platform.isWebView()) {
return 266
}
if (innerWidth >= 375 && innerHeight >= 812) {
return 330
}
return 300
} else {
return 275
}
}
let height = keyboardHeight()
function hasClass (element, csName) {
return element.className.match(RegExp('(\\s|^)' + csName + '(\\s|$)'))
}
function addClass (element, csName) {
if (!hasClass(element, csName)) {
element.className += ' ' + csName
}
element.style.marginBottom = height + 'px'
}
function removeClass (element, csName) {
if (hasClass(element, csName)) {
element.classList.remove(csName)
}
element.style.marginBottom = 0 + 'px'
}
window.addEventListener('native.keyboardshow', function (e) {
addClass(el, KEYBOARD_OPEN_CSS)
})
window.addEventListener('native.keyboardhide', function (e) {
removeClass(el, KEYBOARD_OPEN_CSS)
})
},
unbind: function (el, binding) {
let KEYBOARD_OPEN_CSS = 'foot-keyboard-open'
function hasClass (element, csName) {
return element.className.match(RegExp('(\\s|^)' + csName + '(\\s|$)'))
}
function removeClass (element, csName) {
if (hasClass(element, csName)) {
element.classList.remove(csName)
}
element.style.marginBottom = 0 + 'px'
}
removeClass(el, KEYBOARD_OPEN_CSS)
window.removeEventListener('native.keyboardshow', function (e) {
})
window.removeEventListener('native.keyboardhide', function (e) {
})
},
})
Vue.directive('autoSize', {
bind: function (el, binding) {
if (el.nodeName === 'TEXTAREA') {
Autosize(el)
}
el.addEventListener('oninput', function (e) {
Autosize.update(el)
})
},
unbind: function (el, binding) {
Autosize.update(el)
Autosize.destroy(el)
el.removeEventListener('oninput', function (e) {
})
},
})
}
export default{
createElement: function (marker, tag) {
let el = document.createElement(tag || 'div')
el.setAttribute(marker, '')
document.body.appendChild(el)
},
removeElement: function (marker) {
let el = document.querySelector(marker) || document.querySelector(`[${marker}]`)
if (el) { document.body.removeChild(el) }
},
timeout: function (duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration)
})
},
}
export default (Vue) => {
Vue.filter('currency', function (val) {
if (!val) return '0.00'
var intPart = parseInt(Number(val)) // 获取整数部分
var intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
var floatPart = '.00' // 预定义小数部分
var value2Array = (val + '').split('.')
// =2表示数据有小数位
if (value2Array.length === 2) {
floatPart = value2Array[1].toString() // 拿到小数部分
if (floatPart.length === 1) { // 补0,实际上用不着
return intPartFormat + '.' + floatPart + '0'
} else {
return intPartFormat + '.' + floatPart
}
} else {
return intPartFormat + floatPart
}
})
Vue.filter('uncurrency', function (val) {
if (!val) return null
return Number((val).replace(/,/gi, ''))
})
Vue.filter('datetime', timestamp => {
function format (number) {
return number.toString().padStart(2, '0')
}
const date = new Date(Number.parseInt(timestamp, 10))
const YYYY = date.getFullYear()
const MM = date.getMonth() + 1
const DD = date.getDate()
const hh = date.getHours()
const mm = date.getMinutes()
const ss = date.getSeconds()
return `${YYYY}-${format(MM)}-${format(DD)} ${format(hh)}:${format(mm)}:${format(ss)}`
})
}
// 引入axios
import axios from 'axios'
import hlsPopup from './hlsPopup'
import router from '../router/index'
let promiseArr = {}
let cancel = {}
const CancelToken = axios.CancelToken
// 请求拦截器
axios.interceptors.request.use(config => {
// 发起请求时,取消掉当前正在进行的相同请求
config.cancelToken = new CancelToken(c => {
cancel = c
})
if (promiseArr[config.url]) {
promiseArr[config.url]('操作取消')
promiseArr[config.url] = cancel
} else {
promiseArr[config.url] = cancel
}
return config
}, error => {
return Promise.reject(error)
})
// 响应拦截器即异常处理
axios.interceptors.response.use(response => {
if ($config.debug) {
let postName = 'post'
console.log(postName + ' success')
console.log(postName + ' response ' + JSON.stringify(response.data, '', 2))
console.log(postName + ' End!')
}
if (response.data.result === 'E' || response.data.code === 'E') {
hlsPopup.hideLoading()
const err = {}
err.message = response.data.message
hlsPopup.showError(err.message)
return Promise.resolve(err)
} else {
return response.data
}
}, err => {
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = '错误请求'
break
case 401:
err.message = '登录已失效,请重新登录'
break
case 403:
err.message = '拒绝访问'
break
case 404:
err.message = '请求错误,未找到该资源'
break
case 405:
err.message = '不支持的请求类型'
break
case 408:
err.message = '请求超时'
break
case 500:
err.message = '服务器端出错'
break
case 501:
err.message = '网络未实现'
break
case 502:
err.message = '网络错误'
break
case 503:
err.message = '服务不可用'
break
case 504:
err.message = '网络超时'
break
case 505:
err.message = 'http版本不支持该请求'
break
default:
err.message = `连接错误${err.response.status}`
}
} else {
err.message = '连接到服务器失败'
}
if (err.response && err.response.status === 401) {
hlsPopup.hideLoading()
hlsPopup.showPopup({
title: '登录失效,重新登录',
onConfirm: () => {
router.push({name: 'Login'})
},
})
} else {
hlsPopup.hideLoading()
hlsPopup.showError(err.message)
}
return Promise.resolve(err)
})
axios.defaults.baseURL = ''
axios.defaults.timeout = 100000
// get请求
export function get (url) {
let param = {}
let headers = {}
if (window.localStorage.access_token) {
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
} else {
headers = {
'Content-Type': 'application/json',
}
}
if ($config.debug) {
let postName = 'GET'
console.log(postName + ' Start!')
console.log(postName + ' url ' + url)
}
return new Promise((resolve, reject) => {
axios({
method: 'get',
url,
headers: headers,
params: param,
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
// post请求
export function post (url, param) {
param.user_id = window.localStorage.user_id
param.access_token = window.localStorage.access_token
let headers = {}
if (window.localStorage.access_token) {
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
} else {
headers = {
'Content-Type': 'application/json',
}
}
if ($config.debug) {
let postName = 'POST'
console.log(postName + ' Start!')
console.log(postName + ' url ' + url)
console.log(postName + ' parameter ' + JSON.stringify(param, '', 2))
}
return new Promise((resolve, reject) => {
axios({
method: 'post',
headers: headers,
url,
data: param,
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
import Vue from 'vue'
import {ToastPlugin, AlertPlugin, ConfirmPlugin, LoadingPlugin, DatetimePlugin} from 'vux'
import {ActionSheetPlugin, ShowPicturePlugin, SelectPlugin, NotifyPlugin, NumberKeyboardPlugin} from 'hls-easy-ui'
Vue.use(ToastPlugin)
Vue.use(AlertPlugin)
Vue.use(ConfirmPlugin)
Vue.use(LoadingPlugin)
Vue.use(DatetimePlugin)
Vue.use(ActionSheetPlugin)
Vue.use(ShowPicturePlugin)
Vue.use(SelectPlugin)
Vue.use(NumberKeyboardPlugin)
Vue.use(NotifyPlugin)
export default {
isLoading: false,
SHOW_TIMES: 2000,
IS_SHOW_MASK: true,
/**
* 锁屏函数 超过10s后自动解屏用于防止屏幕锁死
* 自动截屏成弹出错误提示框
* @param content 锁屏内容
*/
showLoading: function (content) {
let vm = this
Vue.$vux.loading.show({
text: content || 'Loading',
})
this.isLoading = true
// 10s后自动解屏用于防止屏幕锁死
setTimeout(() => {
if (vm.isLoading) {
Vue.$vux.loading.hide()
vm.isLoading = false
// 弹出操作失败
/* Vue.$vux.toast.show({
text: '操作失败',
type: 'warn',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'middle',
}) */
}
}, 40000)
},
/**
* 隐藏
*/
hideLoading: function () {
Vue.$vux.loading.hide()
this.isLoading = false
},
/**
* 长时间顶部提示toast
* @param content
*/
showLongTop: function (content) {
let vm = this
let text = content || '操作失败'
Vue.$vux.toast.show({
text: text,
type: 'text',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'top',
})
},
/**
* 长时间中部提示toast
* @param content
*/
showLongCenter: function (content) {
let vm = this
let text = content || '操作失败'
Vue.$vux.toast.show({
text: text,
type: 'text',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'middle',
})
},
/**
* 长时间中部提示toast
* @param content
*/
showLongBottom: function (content) {
let vm = this
let text = content || '操作失败'
Vue.$vux.toast.show({
text: text,
time: vm.SHOW_TIMES,
type: 'text',
isShowMask: vm.IS_SHOW_MASK,
position: 'bottom',
})
},
/**
* 成功提示框
* @param content
*/
showSuccess: function (content) {
let vm = this
Vue.$vux.toast.show({
text: content || '操作成功',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
type: 'success',
position: 'middle',
})
},
/**
* 成功提示框
* @param content
*/
showError: function (content) {
let vm = this
Vue.$vux.toast.show({
text: content || '操作失败',
type: 'warn',
isShowMask: vm.IS_SHOW_MASK,
time: vm.SHOW_TIMES,
position: 'middle',
})
},
/**
* 弹出是否确认的窗口
* @param confirmObject.title 标题
* @param confirmObject.content 内容
* @param confirmObject.onConfirm 确定函数
*/
showConfirm: function (confirmObject) {
let def = {
title: confirmObject.title || '提示',
content: confirmObject.content || '',
confirmText: '确定',
cancelText: '取消',
onConfirm: () => {
confirmObject.onConfirm(1)
},
onCancel: () => {
confirmObject.onConfirm(0)
},
}
Vue.$vux.confirm.show(def)
},
/*
* 弹出确认的窗口
* @param confirmObject.title 标题
* @param confirmObject.content 内容
* @param confirmObject.onConfirm 确定函数
*
*/
showPopup: function (confirmObject) {
let def = {
title: confirmObject.title || '提示',
content: confirmObject.content || '',
confirmText: '确定',
showCancelButton: false,
onConfirm: () => {
confirmObject.onConfirm()
},
}
Vue.$vux.confirm.show(def)
},
/**
* @param actionObject.titleText 弹出框的标题可空
* @param actionObject.callback 点击按钮的回调函数 回传buttonArray数组下标
* @param actionObject.buttonArray 按钮数组支持[string,string],[object,object],
* 当为后一种是 object为{text:'拍照',type:'primary'},type支持 primary,warn,disabled
*
* {
* titleText: '照片',
* buttonArray: [{text:'拍照',type:'warn'}, {text:'从相册取',type:'primary'}],
* callback: (index) => {
* alert(index);
* }
* }
*
* {
* buttonArray: ['拍照','从相册取'],
* callback: (index) => {
* alert(index);
* }
* }
*
*/
showActionSheet: function (actionObject) {
if (typeof actionObject === 'object') {
let buttons = []
for (let i = 0; i < actionObject.buttonArray.length; i++) {
if (typeof actionObject.buttonArray[i] === 'object') {
buttons.push({
text: actionObject.buttonArray[i].text,
type: actionObject.buttonArray[i].type,
callback: actionObject.callback,
})
} else {
buttons.push({
text: actionObject.buttonArray[i],
callback: actionObject.callback,
})
}
}
ActionSheetPlugin.show({
title: actionObject.titleText || '',
buttons: buttons,
})
}
},
/**
* 时间选择函数
* @param timeObject.nowDate 当前展示的时间 可不填
* @param timeObject.format 时间格式支持不支持秒
* @param timeObject.callback 点击确定的回调函数
*
*/
showTime: function (timeObject) {
let date = new Date().format('yyyy-MM-dd')
let format = 'YYYY-MM-DD'
if (timeObject.nowDate) {
date = timeObject.nowDate
}
if (timeObject.format) {
format = timeObject.format
}
Vue.$vux.datetime.show({
cancelText: '取消',
confirmText: '确定',
minYear: '1900',
maxYear: '2200',
format: format,
value: date,
onConfirm (val) {
timeObject.callback(val)
},
})
},
/**
* 图片放大预览
* @param imgObject.imgUrl
*/
showBigPicture: function (imgObject) {
if (typeof imgObject === 'object') {
ShowPicturePlugin.show({
imgUrl: imgObject.imgUrl,
width: imgObject.width,
imgList: imgObject.imgList,
startPosition: imgObject.startPosition,
})
}
},
/**
* 下拉框 支持级联操作 需指定 parent 属性
* @param selectOption.list Array [{"code": "NP","code_name": "个人"}]
* @param selectOption.code String "bp_type"
* @param selectOption.object Object 当前数据对象
* @param selectOption.returnItem function 回调函数返回index与object
* var bp_class_list = [
* {
* "code": "NP",
* "code_name": "个人"
* },{
* "code": "NP1",
* "code_name": "个人1"
* }];
* hlsPopup.selectList({
* list: bp_class_list,
* code: 'bp_type',
* object: {},
* returnItem: function (index, obj) {
* console.log(obj)
* }
* })
*
*/
selectList: function (selectOption) {
if (typeof selectOption === 'object') {
let list = []
let length = selectOption.list.length
vum.forEach(selectOption.list, function (date, index, array) {
list.push({
value: date.code,
name: date.code_name,
parent: date.parent,
})
if (index === (length - 1)) {
SelectPlugin.show({
list: list,
callBack: selectOption.returnItem,
code: selectOption.code,
object: selectOption.object,
})
}
})
}
},
/**
* 弹出数字键盘
* @param keyboardObject.title 键盘的title
* @param keyboardObject.closeButtonText 键盘的关闭按钮文字
* @param keyboardObject.keyDown 普通按键按下去事件
* @param keyboardObject.keyDelete 删除按键按下去事件
*/
showNumberKeyborad: function (keyboardObject) {
if (typeof keyboardObject === 'object') {
NumberKeyboardPlugin.show({
title: keyboardObject.title,
closeButtonText: keyboardObject.closeButtonText,
extraKey: keyboardObject.extraKey || '.',
keyDown: function (text) {
keyboardObject.keyDown(text)
},
keyDelete: function () {
keyboardObject.keyDelete()
// console.log('delete')
},
})
}
},
/**
* 弹出Notify
* @param notifyObject.content 内容
* @param notifyObject.position 位置
* @param notifyObject.time 显示时长
* @param notifyObject.type 类型 success warning default
*/
showNotify: function (notifyObject) {
if (typeof notifyObject === 'object') {
NotifyPlugin.show({
show: true,
content: notifyObject.content,
position: notifyObject.position || 'top',
time: notifyObject.time || 3000,
type: notifyObject.type || 'default',
})
}
},
}
import axios from 'axios'
export default {
city: {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: '新疆',
71: '台湾',
81: '香港',
82: '澳门',
91: '国外',
},
// 检查号码是否符合规范,包括长度,类型
isCardNo (card) {
// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
card = card.toUpperCase()
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
return reg.test(card)
},
// 取身份证前两位,校验省份
checkProvince: function (card) {
card = card.toUpperCase()
let province = card.substr(0, 2)
if (this.city[province] === undefined) {
return false
}
return true
},
// 检查生日是否正确
checkBirthday: function (card) {
card = card.toUpperCase()
let len = card.length
let arrData
let year
let month
let day
let birthday
// 身份证15位时,次序为省(3位)市(3位)年(2位)月(2位)日(2位)校验位(3位),皆为数字
if (len === 15) {
let reFifteen = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/
arrData = card.match(reFifteen)
year = arrData[2]
month = arrData[3]
day = arrData[4]
birthday = new Date('19' + year + '/' + month + '/' + day)
return this.verifyBirthday('19' + year, month, day, birthday)
}
// 身份证18位时,次序为省(3位)市(3位)年(4位)月(2位)日(2位)校验位(4位),校验位末尾可能为X
if (len === 18) {
let reEighteen = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/
arrData = card.match(reEighteen)
year = arrData[2]
month = arrData[3]
day = arrData[4]
birthday = new Date(year + '/' + month + '/' + day)
return this.verifyBirthday(year, month, day, birthday)
}
return false
},
// 校验日期
verifyBirthday: function (year, month, day, birthday) {
// 年月日是否合理
return (birthday.getFullYear().toString() === year && ((birthday.getMonth() + 1) < 10 ? '0' + (birthday.getMonth() + 1) : (birthday.getMonth() + 1).toString()) === month &&
((birthday.getDate()) < 10 ? '0' + (birthday.getDate()).toString() : birthday.getDate().toString()) === day)
},
// 校验位的检测
checkParity (card) {
// 15位转18位
card = this.changeFivteenToEighteen(card)
var len = card.length
if (len === 18) {
let arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
let arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
let cardTemp = 0
for (let i = 0; i < 17; i++) {
cardTemp += card.substr(i, 1) * arrInt[i]
}
let valnum = arrCh[cardTemp % 11]
if (valnum === card.substr(17, 1)) {
return true
}
return false
}
return false
},
// 15位转18位身份证号
changeFivteenToEighteen (card) {
if (card.length === 15) {
let arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
let arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
let cardTemp = 0
card = card.substr(0, 6) + '19' + card.substr(6, card.length - 6)
for (let i = 0; i < 17; i++) {
cardTemp += card.substr(i, 1) * arrInt[i]
}
card += arrCh[cardTemp % 11]
return card
}
return card
},
/**
* 检验身份证号码
*/
isCardID (card) {
card = card.toUpperCase()
if (this.isCardNo(card) === false) {
return '你输入的身份证长度或格式错误'
}
// 检查省份
if (this.checkProvince(card) === false) {
return '你的身份证地区非法'
}
// 校验生日
if (this.checkBirthday(card) === false) {
return '身份证上的出生日期非法'
}
// 检验位的检测
if (this.checkParity(card) === false) {
return '你输入的身份证号非法'
}
return ''
},
// 银行卡号校验
isBankAccount: function (bankno) {
if (bankno.length < 16 || bankno.length > 19) {
/* 银行卡号长度必须在16到19之间 */
return '银行卡号长度必须在16到19之间'
}
let num = /^\d*$/// 全数字
if (!num.exec(bankno)) {
/* 银行卡号必须全为数字 */
return '银行卡号必须全为数字'
}
var strBin = '10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99'
if (strBin.indexOf(bankno.substring(0, 2)) === -1) {
/* 银行卡号开头6位不符合规范 */
return '银行卡号开头6位不符合规范'
}
// Luhn校验
if (!this.luhnCheck(bankno)) {
return '银行卡号有误,请从新输入'
}
// return true;
},
luhnCheck: function (bankno) {
let lastNum = Number(bankno.substr(bankno.length - 1, 1))// 取出最后一位(与luhn进行比较)
let first15Num = bankno.substr(0, bankno.length - 1)// 前15或18位
let newArr = []
for (let i = first15Num.length - 1; i > -1; i--) { // 前15或18位倒序存进数组
newArr.push(first15Num.substr(i, 1))
}
let arrJiShu = [] // 奇数位*2的积 <9
let arrJiShu2 = [] // 奇数位*2的积 >9
let arrOuShu = [] // 偶数位数组
for (let j = 0; j < newArr.length; j++) {
if ((j + 1) % 2 === 1) { // 奇数位
if (parseInt(newArr[j]) * 2 < 9) { arrJiShu.push(parseInt(newArr[j]) * 2) } else { arrJiShu2.push(parseInt(newArr[j]) * 2) }
} else { arrOuShu.push(newArr[j]) }
}
let jishuChild1 = []// 奇数位*2 >9 的分割之后的数组个位数
let jishuChild2 = []// 奇数位*2 >9 的分割之后的数组十位数
for (let h = 0; h < arrJiShu2.length; h++) {
jishuChild1.push(parseInt(arrJiShu2[h]) % 10)
jishuChild2.push(parseInt(arrJiShu2[h]) / 10)
}
let sumJiShu = 0 // 奇数位*2 < 9 的数组之和
let sumOuShu = 0 // 偶数位数组之和
let sumJiShuChild1 = 0 // 奇数位*2 >9 的分割之后的数组个位数之和
let sumJiShuChild2 = 0 // 奇数位*2 >9 的分割之后的数组十位数之和
for (let m = 0; m < arrJiShu.length; m++) {
sumJiShu = sumJiShu + parseInt(arrJiShu[m])
}
for (let n = 0; n < arrOuShu.length; n++) {
sumOuShu = sumOuShu + parseInt(arrOuShu[n])
}
for (let p = 0; p < jishuChild1.length; p++) {
sumJiShuChild1 = sumJiShuChild1 + parseInt(jishuChild1[p])
sumJiShuChild2 = sumJiShuChild2 + parseInt(jishuChild2[p])
}
// 计算总和
let sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2)
// 计算luhn值
let k = parseInt(sumTotal) % 10 === 0 ? 10 : parseInt(sumTotal) % 10
let luhn = 10 - k
if (lastNum === luhn) {
return true
} else {
/* 银行卡号必须符合luhn校验 */
return false
}
},
/**
* 判断输入是否为十一位电话号码
* @param str 字符串
* @returns {boolean}
*/
phoneNumber: function (str) {
// ^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$
let reg = /^((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1})|166|198|199|(147))+\d{8}$/
return reg.test(str)
},
/**
* 判断+86后11位电话号码
* @param str 字符串
* @returns {boolean}
*/
phoneNumber86: function (str) {
let reg = /^(\+86|\+86+\s)+(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1})|166|198|199|(147))+\d{8})$/
return reg.test(str)
},
/**
* 是否是邮件格式
* @param str
* @returns {boolean|*}
*/
isEmailAddress: function (str) {
let pattern = /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
return pattern.test(str)
},
/**
* 拨打电话仅仅限制于手机
* @param number
*/
callPhone: function (number) {
window.open('tel:' + number)
},
/**
* 发邮件
* @param email
*/
callEmail: function (email) {
window.open('mailto:' + email)
},
/**
* formData的文件上传
* @param file File对象
* @param params 请求额外参数
* @param url 请求url地址
*/
fileUpload: function (file,params,url) {
url = encodeURI(url)
let param = new FormData()
for (let key in params) {
param.append(key, params[key])
}
param.append('fileName', file.name)
param.append('file', file)
return axios.post(url, param, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + window.localStorage.access_token,
},
}).then(function (result) {
})
},
/**
*
* @param x 输入的数字
* @returns {Number} 返回数字
*/
toDecimal: function (x) {
// hlsPopup.showLongCenter(baseConfig.debug);
let f = parseFloat(x)
if (isNaN(f)) {
return 0
}
f = Math.round(x * 100) / 100
return f
},
formatFloat: function (f, digit) {
let m = Math.pow(100000, digit)
return parseInt(f * m, 100000) / m
},
/**
*
* @param ir interest rate per month
* @param np number of periods (months)
* @param pv present value
* @param fv future value (residual value)
* @returns {number} 计算结果;
* @constructor
*/
PMT: function (ir, np, pv, fv, type) {
/*
ir - interest rate per month
np - number of periods (months)
pv - present value
fv - future value (residual value)
type - 0 or 1 need to implement that
*/
if (!type) {
type = 0
}
if (ir === 0) {
return -pv / np
}
let r1 = 1 + ir
// let pmt = -( ir * ( pv * Math.pow((ir + 1), np) + fv ) ) / ( ( ir + 1 ) * ( Math.pow((ir + 1), np) - 1 ) );
let pmt = -(pv * Math.pow(r1, np) + fv) * ir / ((1 + ir * type) * (Math.pow(r1, np) - 1))
return this.toDecimal(pmt)
},
/**
*
* @param rate
* @param per
* @param nper
* @param pv
* @param fv
* @param type
* @returns {*}
* @constructor
*/
IPMT: function (rate, per, nper, pv, fv, type) {
let ipmt = 0
let r = rate
let R1 = 1 + r
let t = per
let n = nper
let ct
if (rate === 0) {
return 0
}
if (fv) {
fv = -fv
} else {
fv = 0
}
if (type) {
ct = type
} else {
ct = 0
}
if (type === 1 && per === 1) {
return ipmt
} else {
ipmt = -(pv * Math.pow(R1, n) + fv) * r /
((1 + r * ct) * (Math.pow(R1, n) - 1)) -
(pv / (1 + r * ct) - (pv * Math.pow(R1, n) + fv) /
((1 + r * ct) * (Math.pow(R1, n) - 1))) *
(Math.pow(R1, t) - Math.pow(R1, (t - 1)))
return this.toDecimal(ipmt)
}
},
/**
*
* @param p_rate
* @param p_nper
* @param p_pmt
* @param p_fv
* @param p_type
* @returns {number|*}
* @constructor
*/
PV: function (pRate, pNper, pPmt, pFv, pType) {
let pv
let r
let R1
let n
let pmt
let fv
let ct
r = pRate
R1 = 1 + r
n = pNper
if (pPmt) {
pmt = pPmt
} else {
pmt = 0
}
if (pFv) {
fv = pFv
} else {
fv = 0
}
if (pType) {
ct = pType
} else {
ct = 0
}
pv = -(fv + pmt * (1 + r * ct) * (Math.pow(R1, n) - 1) / r) /
Math.pow(R1, n)
return this.toDecimal(pv)
},
/**
*
* @param p_rate
* @param p_nper
* @param p_pmt
* @param p_pv
* @param p_type
* @returns {number|*}
* @constructor
*/
FV: function (pRate, pNper, pPmt, pPv, pType) {
let fv
let r
let R1
let n
let pmt
let pv
let ct
r = pRate
R1 = 1 + r
n = pNper
if (pPmt) {
pmt = pPmt
} else {
pmt = 0
}
if (pPv) {
pv = pPv
} else {
pv = 0
}
if (pType) {
ct = pType
} else {
ct = 0
}
fv = -pv * Math.pow(R1, n) - pmt * (1 + r * ct) * (Math.pow(R1, n) - 1) / r
return this.toDecimal(fv)
},
/**
*
* @param args
* @param rate
* @returns {*}
* @constructor
*/
NPV: function (args, rate) {
let rrate = (1 + rate / 100)
let npv = args[0]
for (let i = 1; i < args.length; i++) {
npv += (args[i] / Math.pow(rrate, i))
}
return npv
},
/**
*
* @param fn
* @returns {number}
*/
seekZero: function (fn) {
let x = 1
while (fn(x) > 0) {
x += 1
}
while (fn(x) < 0) {
x -= 0.01
}
return x + 0.01
},
/**
*
* @param array
* @returns {number}
* @constructor
*/
IRR: function (array) {
let args = array
let numberOfTries = 1
// Cash flow values must contain at least one positive value and one negative value
let positive, negative
Array.prototype.slice.call(args).forEach(function (value) {
if (value > 0) positive = true
if (value < 0) negative = true
})
if (!positive || !negative) throw new Error('IRR requires at least one positive value and one negative value')
function npv (rate) {
numberOfTries++
if (numberOfTries > 1000) {
throw new Error('IRR can\'t find a result')
}
let rrate = (1 + rate / 100)
let npv = args[0]
for (let i = 1; i < args.length; i++) {
npv += (args[i] / Math.pow(rrate, i))
}
return npv
}
return this.seekZero(npv)
},
// Returns Sum of f(x)/f'(x)
sumEq: function (cfs, durs, guess) {
let sumFx = 0
let sumFdx = 0
for (let i = 0; i < cfs.length; i++) {
sumFx = sumFx + (cfs[i] / Math.pow(1 + guess, durs[i]))
}
for (let i = 0; i < cfs.length; i++) {
sumFdx = sumFdx + (-cfs[i] * durs[i] * Math.pow(1 + guess, -1 - durs[i]))
}
return sumFx / sumFdx
},
durYear: function (first, last) {
return (Math.abs(last.getTime() - first.getTime()) / (1000 * 3600 * 24 * 365))
},
/**
*
* @param cfs
* @param dts
* @param guess
* @returns {number}
* @constructor
*/
XIRR: function (cfs, dts, guess) {
if (cfs.length !== dts.length) throw new Error('Number of cash flows and dates should match')
let positive, negative
Array.prototype.slice.call(cfs).forEach(function (value) {
if (value > 0) positive = true
if (value < 0) negative = true
})
if (!positive || !negative) throw new Error('XIRR requires at least one positive value and one negative value')
guess = guess || 0
let limit = 100 // loop limit
let guessLast
let durs = []
durs.push(0)
// Create Array of durations from First date
for (let i = 1; i < dts.length; i++) {
durs.push(this.durYear(dts[0], dts[i]))
}
do {
guessLast = guess
guess = guessLast - this.sumEq(cfs, durs, guessLast)
limit--
} while (guessLast.toFixed(5) !== guess.toFixed(5) && limit > 0)
let xirr = guessLast.toFixed(5) !== guess.toFixed(5) ? null : guess * 100
return Math.round(xirr * 100) / 100
},
/**
* 判断平台
* @return {String} 平台
*/
detectOS: function () {
const ua = navigator.userAgent.toLowerCase()
if (/MicroMessenger/i.test(ua)) {
return 'weixin'
} else if (/iPhone|iPad|iPod|iOS/i.test(ua)) {
return 'ios'
} else if (/Android/i.test(ua)) {
return 'android'
} else {
return 'other'
}
},
}
/**
* hmap子应用登录逻辑
* @author momoko 2018/05/08
*/
import axios from 'axios'
import { getUrlParam } from './utils'
// 模拟登录
export function analogLogin () {
return new Promise((resolve, reject) => {
const url = `${$config.hmapUrl}/oauth/token?client_id=18f58010-2831-11e8-b467-0ed5f89f718b&client_secret=2fe58f36-2831-11e8-b467-0ed5f89f718b&grant_type=password&username=%2B8618325379820&password=jingchaowu520&authType=TEL`
axios.post(url).then(res => {
window.localStorage.setItem('token', res.access_token)
resolve({
token: res.access_token,
tokenType: res.token_type,
expires: res.expires_in,
userId: res.userId,
organizationId: res.organizationId,
})
})
})
}
// 授权码登录
export async function authorizedLogin () {
return new Promise((resolve, reject) => {
const code = getUrlParam('code')
const url = `${$config.hmapUrl}/oauth/token?client_id=18f58010-2831-11e8-b467-0ed5f89f718b&client_secret=2fe58f36-2831-11e8-b467-0ed5f89f718b&grant_type=authorization_code&code=${encodeURIComponent(code)}`
axios.post(url).then(res => {
window.localStorage.setItem('token', res.access_token)
resolve({
token: res.access_token,
tokenType: res.token_type,
expires: res.expires_in,
userId: res.userId,
organizationId: res.organizationId,
account: res.account,
mobile: res.phoneNumber,
})
})
})
}
// 桥登录
export function bridgeLogin () {
return new Promise((resolve, reject) => {
// 登录成功回调
window.bridgeLoginSuccess = function (str) {
const res = JSON.parse(str)
window.localStorage.setItem('token', res.token)
const data = {
token: res.token,
tokenType: res.tokenType,
expires: res.expiresIn,
userId: res.userId,
organizationId: res.organizationId,
account: res.account,
mobile: res.phoneNumber,
}
resolve(data)
}
// 登录失败回调
window.bridgeLoginFailure = function (res) {
console.error(res)
reject(res)
}
const dict = {
'className': 'BaseBridge',
'function': 'getBaseInfo',
'successCallBack': 'bridgeLoginSuccess',
'failureCallBack': 'bridgeLoginFailure',
}
HandBridge.postMessage(JSON.stringify(dict))
})
}
// 获取用户详细信息
export function getUserInfo (userId) {
const url = `${$config.hmapUrl}/i/api/staff/customDetail`
const data = {
userId,
}
const options = {
headers: {
Authorization: `Bearer ${window.localStorage.token}`,
},
}
return new Promise((resolve, reject) => {
axios.post(url, data, options).then(res => {
resolve({
account: res.accountNumber,
mobile: res.mobile,
userId: res.userId,
organizationId: res.organizationId,
email: res.email,
})
})
})
}
/**
* 获取中台的token
* @returns {Promise<*>}
*/
export async function getSupportToken () {
const url = `${$config.loginPath}appadmin`
const res = await axios.post(url)
return res
}
/**
* 获取业务系统个人信息
* @returns {Promise<*>}
*/
export async function getLeasingUserInfo (account, mobile) {
window.localStorage.setItem('account', account)
const url = `${$config.basePath}hmap_app_login`
const data = {
'user_name': account,
'mobile': mobile,
}
const options = {
headers: {
Authorization: `Bearer ${window.localStorage.access_token}`,
},
}
return new Promise((resolve, reject) => {
axios.post(url, data, options).then(res => {
// console.log('leasingInfo:' + JSON.stringify(res))
if (res.result === 'S') {
resolve(res.user_info[0])
}
})
})
}
/**
* 登录总成
* @param {String} [type] 可选:'online''local'
* @param {Boolean} [needInfo] 是否需要获取用户详细信息
* @return {Object.Promise} 若登录成功PromiseValue为数据对象/登录失败PromiseValue 为 false
*/
export async function login (type = 'online', needInfo = true) { // 登录
const env = process.env.CONFIG_ENV // 环境
try {
let result = {}
let tokenInfo = {}
tokenInfo = await getSupportToken()
window.localStorage.setItem('access_token', tokenInfo.access_token)
if (env === 'prod' || env === 'uat') { // 真机
if (type === 'online') result = await authorizedLogin() // 在线子应用
if (type === 'local') result = await bridgeLogin() // 本地子应用
window.localStorage.setItem('mobile', result.mobile)
result.userInfo = await getLeasingUserInfo(result.account, result.mobile)
} else {
result = await analogLogin()
result.hmapUserInfo = await getUserInfo(result.userId)
window.localStorage.setItem('mobile', result.hmapUserInfo.mobile)
result.userInfo = await getLeasingUserInfo(result.hmapUserInfo.account, result.hmapUserInfo.mobile)
}
window.localStorage.setItem('user_id', result.userInfo.user_id)
return result
} catch (e) {
// console.error(e)
return false
}
}
/**
* 海马汇业务系统集成登录
* @param type
* @param needInfo
* @returns {Promise<any>}
*/
export default function hmapLogin (type = 'local', needInfo = true) {
const env = process.env.CONFIG_ENV // 环境
return new Promise((resolve, reject) => {
try {
let result = {}
if (env === 'prod' || env === 'uat') { // 真机
if (type === 'online') {
authorizedLogin().then(res => {
result = res
window.localStorage.setItem('mobile', res.mobile)
})
}// 在线子应用
if (type === 'local') {
result = bridgeLogin().then(res => {
result = res
window.localStorage.setItem('mobile', res.mobile)
})
}
getSupportToken().then(res => {
window.localStorage.setItem('access_token', res.access_token)
getLeasingUserInfo(result.account, result.mobile).then(res => {
result.userInfo = res
window.localStorage.setItem('user_id', res.user_id)
resolve(result)
})
})
} else {
analogLogin().then(res => {
result = res
getUserInfo(res.userId).then(info => {
result.hmapUserInfo = info
window.localStorage.setItem('mobile', info.mobile)
getSupportToken().then(support => {
window.localStorage.setItem('access_token', support.access_token)
getLeasingUserInfo(info.account, info.mobile).then(res => {
result.userInfo = res
window.localStorage.setItem('user_id', res.user_id)
resolve(result)
})
})
})
})
}
} catch (e) {
reject(e)
}
})
}
/**
* 一些帮助函数
* @author momoko
*/
/**
* 取URL上的参数
* @param {String} param 参数名
* @return {String}
*/
export function getUrlParam (param) {
const result = window.location.href.match(new RegExp('(\\?|&)' + param + '(\\[\\])?=([^&#]*)'))
return result ? result[3] : undefined
}
/**
* 动态插入 script to html
* @param url
* @param callback
*/
export function createScript (url, callback) {
const oScript = document.createElement('script')
oScript.type = 'text/javascript'
oScript.async = true
oScript.src = url
/**
* IE6/7/8 -- onreadystatechange
* IE9/10 -- onreadystatechange, onload
* Firefox/Chrome/Opera -- onload
*/
const isIE = !-[1,] // eslint-disable-line
if (isIE) {
// 判断IE8及以下浏览器
oScript.onreadystatechange = function () {
if (this.readyState === 'loaded' || this.readyState === 'complete') {
callback && callback()
}
}
} else {
// IE9及以上浏览器,Firefox,Chrome,Opera
oScript.onload = function () {
callback && callback()
}
}
document.body.appendChild(oScript)
}
/**
* 判断平台
* @return {String} 平台
*/
export function detectOS () {
const ua = navigator.userAgent.toLowerCase()
if (/MicroMessenger/i.test(ua)) {
return 'weixin'
} else if (/iPhone|iPad|iPod|iOS/i.test(ua)) {
return 'ios'
} else if (/Android/i.test(ua)) {
return 'android'
} else {
return 'other'
}
}
//字体大小颜色
/*.fc(@a:14px,@b:red) {
font-size: @a;
color: @b;
}*/
/**
* 基础字体大小
*/
@font-size-big: 16px;
@font-size-middle: 14px;
@font-size-small: 12px;
@opacity-disabled: 0.4;
/**
* 颜色
*/
@theme-color:#5D98F6;
@font-color:#666666;
@mainColor: #000;
@baseColor: white;
@hintColor:rgb(181,181,181);
@headerColor: #5D98F6;
@background-color-gray: #fafafa;
@activated-color: #5D98F6;
@divider-color:#fafafa;
@check-box-bg:#48D2A0;
/**
* headbar的高度配置
*/
@headerHeight:44px;
@iosPaddingTop:20px;
@iosxPaddingTop:40px;
@hasHeader:44px;
@iosHasHeader:64px;
@iosxHasHeader:84px;
@paddingLength:15px;
@bottomSafeArea:34px;
/**
* Notify颜色
*/
@notifyFontColor:#fff;
@dialogWrapBackgroundColor:rgba(0,0,0,.7);
@dialogWrapWarningBackgroundColor:#f96f68;
@dialogWrapSuccessBackgroundColor:#48d2a0;
/**
* 覆盖vux自带的颜色
*/
@header-background-color:@theme-color;
@header-title-color:@baseColor;
@header-arrow-color:@baseColor;
@tabbar-text-active-color: #f96268;
@datetime-header-item-font-color:@theme-color;
@datetime-header-item-confirm-font-color:@theme-color;
@dialog-button-text-default-color:@font-color;
@dialog-button-text-primary-color:@theme-color;
/**
* popup-header
*/
@popup-header-height:44px;
@popup-header-bg-color:#fff;
@popup-header-font-size:16px;
@popup-header-right-text-color:@theme-color;
@popup-header-left-text-padding: 15px;
@popup-header-right-text-padding: 15px;
/**
* actionsheet
*/
/**
* en: primary type text color of menu item
* zh-CN: 菜单项primary类型的文本颜色
*/
@actionsheet-label-primary-color: @theme-color;
/**
* en: warn type text color of menu item
* zh-CN: 菜单项warn类型的文本颜色
*/
@actionsheet-label-warn-color: #f96268;
/**
* en: default type text color of menu item
* zh-CN: 菜单项default类型的文本颜色
*/
@actionsheet-label-default-color: #444;
/**
* en: disabled type text color of menu item
* zh-CN: 菜单项disabled类型的文本颜色
*/
@actionsheet-label-disabled-color: #ccc;
@swiper-indicator-active-color:@headerColor;
//swipout按钮的颜色定义
@swipeout-button-primary-bg-color:@headerColor;
@swipeout-button-warn-bg-color:#f96268;
@swipeout-button-default-bg-color:#c8c7cd;
.setTopLine(@c: rgba(0,0,0,.1)) {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px; /*no*/
border-top: 1px solid @c; /*no*/
color: @c;
transform-origin: 0 0;
transform: scaleY(0.5);
}
.setBottomLine(@c: rgba(0,0,0,.1)) {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px; /*no*/
border-bottom: 1px solid @c; /*no*/
color: @c;
transform-origin: 0 100%;
transform: scaleY(0.5);
}
.setLeftLine(@c: rgba(0,0,0,.1)) {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 1px; /*no*/
bottom: 0;
border-left: 1px solid @c; /*no*/
color: @c;
transform-origin: 0 0;
transform: scaleX(0.5);
}
.setRightLine(@c: rgba(0,0,0,.1)) {
content: " ";
position: absolute;
right: 0;
top: 0;
width: 1px; /*no*/
bottom: 0;
border-right: 1px solid @c; /*no*/
color: @c;
transform-origin: 100% 0;
transform: scaleX(0.5);
}
.setLine(@c: rgba(0,0,0,.1)) {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 200%;
border: 1px solid @c; /*no*/
color: @c;
height: 200%;
transform-origin: left top;
transform: scale(0.5);
}
/**
*
* @param fmt
* @returns {*}
* @constructor
*/
Date.prototype.format = function (fmt) { // eslint-disable-line
var o = {
'M+': this.getMonth() + 1, // 月份
'd+': this.getDate(), // 日
'h+': this.getHours(), // 小时
'm+': this.getMinutes(), // 分
's+': this.getSeconds(), // 秒
'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
'S': this.getMilliseconds(), // 毫秒
}
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
for (var k in o) { if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) }
return fmt
}
/**
* 移除数组的某个元素
* @param dx 下标
* @returns {boolean}
*/
Array.prototype.remove = function (dx) { // eslint-disable-line
if (isNaN(dx) || dx > this.length) {
return false
}
for (var i = 0, n = 0; i < this.length; i++) {
if (this[i] !== this[dx]) {
this[n++] = this[i]
}
}
this.length -= 1
}
/*!
* vum.bundle.js is a concatenation of:
* vum.js, angular.js, angular-animate.js,
* angular-sanitize.js, angular-ui-router.js,
* and vum-angular.js
*/
/*!
* Copyright 2015 Drifty Co.
* http://drifty.com/
*
* vum, v1.3.0
* A powerful HTML5 mobile app framework.
* http://vumframework.com/
*
* By @maxlynch, @benjsperry, @adamdbradley <3
*
* Licensed under the MIT license. Please see LICENSE for more information.
*
*/
/* eslint-disable */
(function () {
// Create global vum obj and its namespaces
// build processes may have already created an vum obj
window.vum = window.vum || {}
window.vum.version = '1.3.0';
(function (window, document, vum) {
var readyCallbacks = []
var isDomReady = document.readyState === 'complete' || document.readyState === 'interactive'
function domReady () {
isDomReady = true
for (var x = 0; x < readyCallbacks.length; x++) {
vum.requestAnimationFrame(readyCallbacks[x])
}
readyCallbacks = []
document.removeEventListener('DOMContentLoaded', domReady)
}
if (!isDomReady) {
document.addEventListener('DOMContentLoaded', domReady)
}
})(window, document, vum);
(function (window, document, vum) {
function getParameterByName (name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]')
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'),
results = regex.exec(location.search)
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '))
}
var IOS = 'ios'
var ANDROID = 'android'
var WINDOWS_PHONE = 'windowsphone'
var EDGE = 'edge'
var CROSSWALK = 'crosswalk'
var requestAnimationFrame = requestAnimationFrame // eslint-disable-line
// From the man himself, Mr. Paul Irish.
// The requestAnimationFrame polyfill
// Put it on window just to preserve its context
// without having to use .call
window._rAF = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 16)
}
})()
function requestAnimationFrame (cb) {
return window._rAF(cb)
}
/**
* @ngdoc utility
* @name vum.Platform
* @module vum
* @description
* A set of utility methods that can be used to retrieve the device ready state and
* various other information such as what kind of platform the app is currently installed on.
*
* @usage
* ```js
* angular.module('PlatformApp', ['vum'])
* .controller('PlatformCtrl', function($scope) {
*
* vum.Platform.ready(function(){
* // will execute when device is ready, or immediately if the device is already ready.
* });
*
* var deviceInformation = vum.Platform.device();
*
* var isWebView = vum.Platform.isWebView();
* var isIPad = vum.Platform.isIPad();
* var isIOS = vum.Platform.isIOS();
* var isAndroid = vum.Platform.isAndroid();
* var isWindowsPhone = vum.Platform.isWindowsPhone();
*
* var currentPlatform = vum.Platform.platform();
* var currentPlatformVersion = vum.Platform.version();
*
* vum.Platform.exitApp(); // stops the app
* });
* ```
*/
var self = vum.Platform = {
// Put navigator on platform so it can be mocked and set
// the browser does not allow window.navigator to be set
navigator: window.navigator,
/**
* @ngdoc property
* @name vum.Platform#isReady
* @returns {boolean} Whether the device is ready.
*/
isReady: false,
/**
* @ngdoc property
* @name vum.Platform#isFullScreen
* @returns {boolean} Whether the device is fullscreen.
*/
isFullScreen: false,
/**
* @ngdoc property
* @name vum.Platform#platforms
* @returns {Array(string)} An array of all platforms found.
*/
platforms: null,
/**
* @ngdoc property
* @name vum.Platform#grade
* @returns {string} What grade the current platform is.
*/
grade: null,
/**
* @ngdoc property
* @name vum.Platform#ua
* @returns {string} What User Agent is.
*/
ua: navigator.userAgent,
/**
* @ngdoc method
* @name vum.Platform#ready
* @description
* Trigger a callback once the device is ready, or immediately
* if the device is already ready. This method can be run from
* anywhere and does not need to be wrapped by any additonal methods.
* When the app is within a WebView (Cordova), it'll fire
* the callback once the device is ready. If the app is within
* a web browser, it'll fire the callback after `window.load`.
* Please remember that Cordova features (Camera, FileSystem, etc) still
* will not work in a web browser.
* @param {function} callback The function to call.
*/
ready: function (cb) {
// run through tasks to complete now that the device is ready
if (self.isReady) {
cb()
} else {
// the platform isn't ready yet, add it to this array
// which will be called once the platform is ready
readyCallbacks.push(cb)
}
},
/**
* @private
*/
detect: function () {
self._checkPlatforms()
requestAnimationFrame(function () {
// only add to the body class if we got platform info
for (var i = 0; i < self.platforms.length; i++) {
document.body.classList.add('platform-' + self.platforms[i])
}
})
},
/**
* @ngdoc method
* @name vum.Platform#setGrade
* @description Set the grade of the device: 'a', 'b', or 'c'. 'a' is the best
* (most css features enabled), 'c' is the worst. By default, sets the grade
* depending on the current device.
* @param {string} grade The new grade to set.
*/
setGrade: function (grade) {
var oldGrade = self.grade
self.grade = grade
requestAnimationFrame(function () {
if (oldGrade) {
document.body.classList.remove('grade-' + oldGrade)
}
document.body.classList.add('grade-' + grade)
})
},
/**
* @ngdoc method
* @name vum.Platform#device
* @description Return the current device (given by cordova).
* @returns {object} The device object.
*/
device: function () {
return window.device || {}
},
_checkPlatforms: function () {
self.platforms = []
var grade = 'a'
/*if (self.isWebView()) {
self.platforms.push('webview')
if (!(!window.cordova && !window.PhoneGap && !window.phonegap)) {
self.platforms.push('cordova')
} else if (typeof window.forge === 'object') {
self.platforms.push('trigger')
}
} else {
self.platforms.push('browser')
}
if (self.isIPad()) self.platforms.push('ipad')*/
var platform = self.platform()
if (platform) {
self.platforms.push(platform)
/*var version = self.version()
if (version) {
var v = version.toString()
if (v.indexOf('.') > 0) {
v = v.replace('.', '_')
} else {
v += '_0'
}
self.platforms.push(platform + v.split('_')[0])
self.platforms.push(platform + v)
if (self.isAndroid() && version < 4.4) {
grade = (version < 4 ? 'c' : 'b')
} else if (self.isWindowsPhone()) {
grade = 'b'
}
}*/
}
// self.setGrade(grade)
},
/**
* @ngdoc method
* @name vum.Platform#isWebView
* @returns {boolean} Check if we are running within a WebView (such as Cordova).
*/
isWebView: function () {
return !(!window.cordova && !window.PhoneGap && !window.phonegap && window.forge !== 'object')
},
/**
* @ngdoc method
* @name vum.Platform#isIPad
* @returns {boolean} Whether we are running on iPad.
*/
isIPad: function () {
if (/iPad/i.test(self.navigator.platform)) {
return true
}
return /iPad/i.test(self.ua)
},
/**
* @ngdoc method
* @name vum.Platform#isIOS
* @returns {boolean} Whether we are running on iOS.
*/
isIOS: function () {
return self.is(IOS)
},
/**
* @ngdoc method
* @name vum.Platform#isAndroid
* @returns {boolean} Whether we are running on Android.
*/
isAndroid: function () {
return self.is(ANDROID)
},
/**
* @ngdoc method
* @name vum.Platform#isWindowsPhone
* @returns {boolean} Whether we are running on Windows Phone.
*/
isWindowsPhone: function () {
return self.is(WINDOWS_PHONE)
},
/**
* @ngdoc method
* @name vum.Platform#isEdge
* @returns {boolean} Whether we are running on MS Edge/Windows 10 (inc. Phone)
*/
isEdge: function () {
return self.is(EDGE)
},
isCrosswalk: function () {
return self.is(CROSSWALK)
},
/**
* @ngdoc method
* @name vum.Platform#platform
* @returns {string} The name of the current platform.
*/
platform: function () {
// singleton to get the platform name
if (platformName === null) self.setPlatform(self.device().platform)
return platformName
},
/**
* @private
*/
setPlatform: function (n) {
if (typeof n !== 'undefined' && n !== null && n.length) {
platformName = n.toLowerCase()
} else if (getParameterByName('vumplatform')) {
platformName = getParameterByName('vumplatform')
} else if (self.ua.indexOf('Edge') > -1) {
platformName = EDGE
} else if (self.ua.indexOf('Windows Phone') > -1) {
platformName = WINDOWS_PHONE
} else if (self.ua.indexOf('Android') > 0) {
platformName = ANDROID
} else if (/iPhone|iPad|iPod/.test(self.ua)) {
platformName = IOS
} else {
platformName = self.navigator.platform && navigator.platform.toLowerCase().split(' ')[0] || ''
}
},
/**
* @ngdoc method
* @name vum.Platform#version
* @returns {number} The version of the current device platform.
*/
version: function () {
// singleton to get the platform version
if (platformVersion === null) self.setVersion(self.device().version)
return platformVersion
},
/**
* @private
*/
setVersion: function (v) {
if (typeof v !== 'undefined' && v !== null) {
v = v.split('.')
v = parseFloat(v[0] + '.' + (v.length > 1 ? v[1] : 0))
if (!isNaN(v)) {
platformVersion = v
return
}
}
platformVersion = 0
// fallback to user-agent checking
var pName = self.platform()
var versionMatch = {
'android': /Android (\d+).(\d+)?/,
'ios': /OS (\d+)_(\d+)?/,
'windowsphone': /Windows Phone (\d+).(\d+)?/,
}
if (versionMatch[pName]) {
v = self.ua.match(versionMatch[pName])
if (v && v.length > 2) {
platformVersion = parseFloat(v[1] + '.' + v[2])
}
}
},
/**
* @ngdoc method
* @name vum.Platform#is
* @param {string} Platform name.
* @returns {boolean} Whether the platform name provided is detected.
*/
is: function (type) {
type = type.toLowerCase()
// check if it has an array of platforms
if (self.platforms) {
for (var x = 0; x < self.platforms.length; x++) {
if (self.platforms[x] === type) return true
}
}
// exact match
var pName = self.platform()
if (pName) {
return pName === type.toLowerCase()
}
// A quick hack for to check userAgent
return self.ua.toLowerCase().indexOf(type) >= 0
},
/**
* @ngdoc method
* @name vum.Platform#exitApp
* @description Exit the app.
*/
exitApp: function () {
self.ready(function () {
navigator.app && navigator.app.exitApp && navigator.app.exitApp()
})
},
/**
* @ngdoc method
* @name vum.Platform#showStatusBar
* @description Shows or hides the device status bar (in Cordova). Requires `cordova plugin add org.apache.cordova.statusbar`
* @param {boolean} shouldShow Whether or not to show the status bar.
*/
showStatusBar: function (val) {
// Only useful when run within cordova
self._showStatusBar = val
self.ready(function () {
// run this only when or if the platform (cordova) is ready
requestAnimationFrame(function () {
if (self._showStatusBar) {
// they do not want it to be full screen
window.StatusBar && window.StatusBar.show()
document.body.classList.remove('status-bar-hide')
} else {
// it should be full screen
window.StatusBar && window.StatusBar.hide()
document.body.classList.add('status-bar-hide')
}
})
})
},
/**
* @ngdoc method
* @name vum.Platform#fullScreen
* @description
* Sets whether the app is fullscreen or not (in Cordova).
* @param {boolean=} showFullScreen Whether or not to set the app to fullscreen. Defaults to true. Requires `cordova plugin add org.apache.cordova.statusbar`
* @param {boolean=} showStatusBar Whether or not to show the device's status bar. Defaults to false.
*/
fullScreen: function (showFullScreen, showStatusBar) {
// showFullScreen: default is true if no param provided
self.isFullScreen = (showFullScreen !== false)
// add/remove the fullscreen classname to the body
vum.DomUtil.ready(function () {
// run this only when or if the DOM is ready
requestAnimationFrame(function () {
if (self.isFullScreen) {
document.body.classList.add('fullscreen')
} else {
document.body.classList.remove('fullscreen')
}
})
// showStatusBar: default is false if no param provided
self.showStatusBar((showStatusBar === true))
})
},
}
var platformName = null, // just the name, like iOS or Android
platformVersion = null, // a float of the major and minor, like 7.1
readyCallbacks = [],
windowLoadListenderAttached,
platformReadyTimer = 2000 // How long to wait for platform ready before emitting a warning
verifyPlatformReady()
// Warn the user if deviceready did not fire in a reasonable amount of time, and how to fix it.
function verifyPlatformReady () {
setTimeout(function () {
if (!self.isReady && self.isWebView()) {
void 0
}
}, platformReadyTimer)
}
// setup listeners to know when the device is ready to go
function onWindowLoad () {
if (self.isWebView()) {
// the window and scripts are fully loaded, and a cordova/phonegap
// object exists then let's listen for the deviceready
document.addEventListener('deviceready', onPlatformReady, false)
} else {
// the window and scripts are fully loaded, but the window object doesn't have the
// cordova/phonegap object, so its just a browser, not a webview wrapped w/ cordova
onPlatformReady()
}
if (windowLoadListenderAttached) {
window.removeEventListener('load', onWindowLoad, false)
}
}
if (document.readyState === 'complete') {
onWindowLoad()
} else {
windowLoadListenderAttached = true
window.addEventListener('load', onWindowLoad, false)
}
function onPlatformReady () {
// the device is all set to go, init our own stuff then fire off our event
self.isReady = true
self.detect()
for (var x = 0; x < readyCallbacks.length; x++) {
// fire off all the callbacks that were added before the platform was ready
readyCallbacks[x]()
}
readyCallbacks = []
vum.trigger('platformready', {target: document})
requestAnimationFrame(function () {
document.body.classList.add('platform-ready')
})
}
// document.addEventListener('')
})(window, document, vum);
/**
* ion-events.js
*
* Author: Max Lynch <max@drifty.com>
*
* Framework events handles various mobile browser events, and
* detects special events like tap/swipe/etc. and emits them
* as custom events that can be used in an app.
*
* Portions lovingly adapted from github.com/maker/ratchet and github.com/alexgibson/tap.js - thanks guys!
*/
(function (vum) {
// Custom event polyfill
vum.CustomEvent = (function () {
if (typeof window.CustomEvent === 'function') return CustomEvent
var customEvent = function (event, params) {
var evt
params = params || {
bubbles: false,
cancelable: false,
detail: undefined,
}
try {
evt = document.createEvent('CustomEvent')
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
} catch (error) {
// fallback for browsers that don't support createEvent('CustomEvent')
evt = document.createEvent('Event')
for (var param in params) {
evt[param] = params[param]
}
evt.initEvent(event, params.bubbles, params.cancelable)
}
return evt
}
customEvent.prototype = window.Event.prototype
return customEvent
})()
/**
* @ngdoc utility
* @name vum.EventController
* @module vum
*/
vum.EventController = {
VIRTUALIZED_EVENTS: ['tap', 'swipe', 'swiperight', 'swipeleft', 'drag', 'hold', 'release'],
/**
* @ngdoc method
* @name vum.EventController#trigger
* @alias vum.trigger
* @param {string} eventType The event to trigger.
* @param {object} data The data for the event. Hint: pass in
* `{target: targetElement}`
* @param {boolean=} bubbles Whether the event should bubble up the DOM.
* @param {boolean=} cancelable Whether the event should be cancelable.
*/
// Trigger a new event
trigger: function (eventType, data, bubbles, cancelable) {
var event = new vum.CustomEvent(eventType, {
detail: data,
bubbles: !!bubbles,
cancelable: !!cancelable,
})
// Make sure to trigger the event on the given target, or dispatch it from
// the window if we don't have an event target
data && data.target && data.target.dispatchEvent && data.target.dispatchEvent(event) || window.dispatchEvent(event)
},
/**
* @ngdoc method
* @name vum.EventController#on
* @alias vum.on
* @description Listen to an event on an element.
* @param {string} type The event to listen for.
* @param {function} callback The listener to be called.
* @param {DOMElement} element The element to listen for the event on.
*/
on: function (type, callback, element) {
var e = element || window
// Bind a gesture if it's a virtual event
for (var i = 0, j = this.VIRTUALIZED_EVENTS.length; i < j; i++) {
if (type == this.VIRTUALIZED_EVENTS[i]) {
var gesture = new vum.Gesture(element)
gesture.on(type, callback)
return gesture
}
}
// Otherwise bind a normal event
e.addEventListener(type, callback)
},
/**
* @ngdoc method
* @name vum.EventController#off
* @alias vum.off
* @description Remove an event listener.
* @param {string} type
* @param {function} callback
* @param {DOMElement} element
*/
off: function (type, callback, element) {
element.removeEventListener(type, callback)
},
/**
* @ngdoc method
* @name vum.EventController#onGesture
* @alias vum.onGesture
* @description Add an event listener for a gesture on an element.
*
* Available eventTypes (from [hammer.js](http://eightmedia.github.io/hammer.js/)):
*
* `hold`, `tap`, `doubletap`, `drag`, `dragstart`, `dragend`, `dragup`, `dragdown`, <br/>
* `dragleft`, `dragright`, `swipe`, `swipeup`, `swipedown`, `swipeleft`, `swiperight`, <br/>
* `transform`, `transformstart`, `transformend`, `rotate`, `pinch`, `pinchin`, `pinchout`, <br/>
* `touch`, `release`
*
* @param {string} eventType The gesture event to listen for.
* @param {function(e)} callback The function to call when the gesture
* happens.
* @param {DOMElement} element The angular element to listen for the event on.
* @param {object} options object.
* @returns {vum.Gesture} The gesture object (use this to remove the gesture later on).
*/
onGesture: function (type, callback, element, options) {
var gesture = new vum.Gesture(element, options)
gesture.on(type, callback)
return gesture
},
/**
* @ngdoc method
* @name vum.EventController#offGesture
* @alias vum.offGesture
* @description Remove an event listener for a gesture created on an element.
* @param {vum.Gesture} gesture The gesture that should be removed.
* @param {string} eventType The gesture event to remove the listener for.
* @param {function(e)} callback The listener to remove.
*/
offGesture: function (gesture, type, callback) {
gesture && gesture.off(type, callback)
},
handlePopState: function () {
},
}
// Map some convenient top-level functions for event handling
vum.on = function () {
vum.EventController.on.apply(vum.EventController, arguments)
}
vum.off = function () {
vum.EventController.off.apply(vum.EventController, arguments)
}
vum.trigger = vum.EventController.trigger// function() { vum.EventController.trigger.apply(vum.EventController.trigger, arguments); };
vum.onGesture = function () {
return vum.EventController.onGesture.apply(vum.EventController.onGesture, arguments)
}
vum.offGesture = function () {
return vum.EventController.offGesture.apply(vum.EventController.offGesture, arguments)
}
})(window.vum);
(function (vum) {
vum.$vumPlatform = {
/**
* @ngdoc method
* @name $vumPlatform#onHardwareBackButton
* @description
* Some platforms have a hardware back button, so this is one way to
* bind to it.
* @param {function} callback the callback to trigger when this event occurs
*/
onHardwareBackButton: function (cb) {
vum.Platform.ready(function () {
document.addEventListener('backbutton', cb, false)
})
},
/**
* @ngdoc method
* @name $vumPlatform#offHardwareBackButton
* @description
* Remove an event listener for the backbutton.
* @param {function} callback The listener function that was
* originally bound.
*/
offHardwareBackButton: function (fn) {
vum.Platform.ready(function () {
document.removeEventListener('backbutton', fn)
})
},
/**
* @ngdoc method
* @name $vumPlatform#registerBackButtonAction
* @description
* Register a hardware back button action. Only one action will execute
* when the back button is clicked, so this method decides which of
* the registered back button actions has the highest priority.
*
* For example, if an actionsheet is showing, the back button should
* close the actionsheet, but it should not also go back a page view
* or close a modal which may be open.
*
* The priorities for the existing back button hooks are as follows:
* Return to previous view = 100
* Close side menu = 150
* Dismiss modal = 200
* Close action sheet = 300
* Dismiss popup = 400
* Dismiss loading overlay = 500
*
* Your back button action will override each of the above actions
* whose priority is less than the priority you provide. For example,
* an action assigned a priority of 101 will override the 'return to
* previous view' action, but not any of the other actions.
*
* @param {function} callback Called when the back button is pressed,
* if this listener is the highest priority.
* @param {number} priority Only the highest priority will execute.
* @param {*=} actionId The id to assign this action. Default: a
* random unique id.
* @returns {function} A function that, when called, will deregister
* this backButtonAction.
*/
$backButtonActions: {},
registerBackButtonAction: function (fn, priority, actionId) {
if (!vum.$vumPlatform._hasBackButtonHandler) {
// add a back button listener if one hasn't been setup yet
vum.$vumPlatform.$backButtonActions = {}
vum.$vumPlatform.onHardwareBackButton(vum.$vumPlatform.hardwareBackButtonClick)
vum.$vumPlatform._hasBackButtonHandler = true
}
var action = {
id: (actionId || vum.Utils.nextUid()),
priority: (priority || 0),
fn: fn,
}
vum.$vumPlatform.$backButtonActions[action.id] = action
// return a function to de-register this back button action
return function () {
delete vum.$vumPlatform.$backButtonActions[action.id]
}
},
/**
* @private
*/
hardwareBackButtonClick: function (e) {
// loop through all the registered back button actions
// and only run the last one of the highest priority
var priorityAction, actionId
for (actionId in vum.$vumPlatform.$backButtonActions) {
if (!priorityAction || vum.$vumPlatform.$backButtonActions[actionId].priority >= priorityAction.priority) {
priorityAction = vum.$vumPlatform.$backButtonActions[actionId]
}
}
if (priorityAction) {
priorityAction.fn(e)
return priorityAction
}
},
is: function (type) {
return vum.Platform.is(type)
},
/**
* @ngdoc method
* @name $vumPlatform#on
* @description
* Add Cordova event listeners, such as `pause`, `resume`, `volumedownbutton`, `batterylow`,
* `offline`, etc. More information about available event types can be found in
* [Cordova's event documentation](https://cordova.apache.org/docs/en/edge/cordova_events_events.md.html#Events).
* @param {string} type Cordova [event type](https://cordova.apache.org/docs/en/edge/cordova_events_events.md.html#Events).
* @param {function} callback Called when the Cordova event is fired.
* @returns {function} Returns a deregistration function to remove the event listener.
*/
on: function (type, cb) {
vum.Platform.ready(function () {
document.addEventListener(type, cb, false)
})
return function () {
vum.Platform.ready(function () {
document.removeEventListener(type, cb)
})
}
},
/**
* @ngdoc method
* @name $vumPlatform#ready
* @description
* Trigger a callback once the device is ready,
* or immediately if the device is already ready.
* @param {function=} callback The function to call.
*/
ready: function (cb) {
vum.Platform.ready(function () {
cb()
})
},
getWinSize: function () {
let winWidth
let winHeight
// 获取窗口宽度
if (window.innerWidth) { winWidth = window.innerWidth } else if ((document.body) && (document.body.clientWidth))
// 获取窗口高度
{ winWidth = document.body.clientWidth }
if (window.innerHeight) { winHeight = window.innerHeight } else if ((document.body) && (document.body.clientHeight)) { winHeight = document.body.clientHeight }
// 通过深入Document内部对body进行检测,获取窗口大小
if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {
winHeight = document.documentElement.clientHeight
winWidth = document.documentElement.clientWidth
}
return {'width': winWidth, 'height': winHeight}
},
}
return vum.$vumPlatform
})(window.vum);
(function () {
var nextId = 0
vum.Utils = {
nextUid: function () {
return 'vue' + (nextId++)
},
}
var jqLite // delay binding since jQuery could be loaded after us.
var hasOwnProperty = Object.prototype.hasOwnProperty
/**
* @ngdoc function
* @name angular.isUndefined
* @module ng
* @kind function
*
* @description
* Determines if a reference is undefined.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is undefined.
*/
vum.isUndefined = function (value) {
return typeof value === 'undefined'
}
/**
* @ngdoc function
* @name angular.isDefined
* @module ng
* @kind function
*
* @description
* Determines if a reference is defined.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is defined.
*/
vum.isDefined = function (value) {
return typeof value !== 'undefined'
}
/**
* @ngdoc function
* @name angular.isObject
* @module ng
* @kind function
*
* @description
* Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
* considered to be objects. Note that JavaScript arrays are objects.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is an `Object` but not `null`.
*/
vum.isObject = function (value) {
// http://jsperf.com/isobject4
return value !== null && typeof value === 'object'
}
/**
* Determine if a value is an object with a null prototype
*
* @returns {boolean} True if `value` is an `Object` with a null prototype
*/
vum.isBlankObject = function (value) {
return value !== null && typeof value === 'object' && !getPrototypeOf(value)
}
/**
* @ngdoc function
* @name angular.isString
* @module ng
* @kind function
*
* @description
* Determines if a reference is a `String`.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `String`.
*/
vum.isString = function (value) {
return typeof value === 'string'
}
/**
* @ngdoc function
* @name angular.isNumber
* @module ng
* @kind function
*
* @description
* Determines if a reference is a `Number`.
*
* This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
*
* If you wish to exclude these then you can use the native
* [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
* method.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `Number`.
*/
vum.isNumber = function (value) {
return typeof value === 'number'
}
/**
* @ngdoc function
* @name angular.isDate
* @module ng
* @kind function
*
* @description
* Determines if a value is a date.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `Date`.
*/
vum.isDate = function (value) {
return toString.call(value) === '[object Date]'
}
/**
* @ngdoc function
* @name angular.isArray
* @module ng
* @kind function
*
* @description
* Determines if a reference is an `Array`.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is an `Array`.
*/
var isArray = Array.isArray
/**
* @ngdoc function
* @name angular.isFunction
* @module ng
* @kind function
*
* @description
* Determines if a reference is a `Function`.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `Function`.
*/
vum.isFunction = function (value) {
return typeof value === 'function'
}
/**
* Determines if a value is a regular expression object.
*
* @private
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `RegExp`.
*/
vum.isRegExp = function (value) {
return toString.call(value) === '[object RegExp]'
}
/**
* Checks if `obj` is a window object.
*
* @private
* @param {*} obj Object to check
* @returns {boolean} True if `obj` is a window obj.
*/
vum.isWindow = function (obj) {
return obj && obj.window === obj
}
vum.isScope = function (obj) {
return obj && obj.$evalAsync && obj.$watch
}
vum.isFile = function (obj) {
return toString.call(obj) === '[object File]'
}
vum.isFormData = function (obj) {
return toString.call(obj) === '[object FormData]'
}
vum.isBlob = function (obj) {
return toString.call(obj) === '[object Blob]'
}
vum.isBoolean = function (value) {
return typeof value === 'boolean'
}
vum.isPromiseLike = function (obj) {
return obj && isFunction(obj.then)
}
var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/
vum.isTypedArray = function (value) {
return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value))
}
vum.isArrayBuffer = function (obj) {
return toString.call(obj) === '[object ArrayBuffer]'
}
vum.toJsonReplacer = function (key, value) {
var val = value
if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
val = undefined
} else if (vum.isWindow(value)) {
val = '$WINDOW'
} else if (value && document === value) {
val = '$DOCUMENT'
} else if (vum.isScope(value)) {
val = '$SCOPE'
}
return val
}
/**
* @ngdoc function
* @name angular.toJson
* @module ng
* @kind function
*
* @description
* Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
* stripped since angular uses this notation internally.
*
* @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
* @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
* If set to an integer, the JSON output will contain that many spaces per indentation.
* @returns {string|undefined} JSON-ified string representing `obj`.
*/
vum.toJson = function (obj, pretty) {
if (vum.isUndefined(obj)) return undefined
if (!vum.isNumber(pretty)) {
pretty = pretty ? 2 : null
}
return JSON.stringify(obj, vum.toJsonReplacer, pretty)
}
function isArrayLike (obj) {
// `null`, `undefined` and `window` are not array-like
if (obj == null || isWindow(obj)) return false
// arrays, strings and jQuery/jqLite objects are array like
// * jqLite is either the jQuery or jqLite constructor function
// * we have to check the existence of jqLite first as this method is called
// via the forEach method when constructing the jqLite object in the first place
if (isArray(obj) || vum.isString(obj) || (jqLite && obj instanceof jqLite)) return true
// Support: iOS 8.2 (not reproducible in simulator)
// "length" in obj used to prevent JIT error (gh-11508)
var length = 'length' in Object(obj) && obj.length
// NodeList objects (with `item` method) and
// other objects with suitable length characteristics are array-like
return vum.isNumber(length) &&
(length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function')
}
/**
* @ngdoc function
* @name angular.forEach
* @module ng
* @kind function
*
* @description
* Invokes the `iterator` function once for each item in `obj` collection, which can be either an
* object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
* is the value of an object property or an array element, `key` is the object property key or
* array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
*
* It is worth noting that `.forEach` does not iterate over inherited properties because it filters
* using the `hasOwnProperty` method.
*
* Unlike ES262's
* [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
* providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
* return the value provided.
*
```js
var values = {name: 'misko', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key) {
this.push(key + ': ' + value);
}, log);
expect(log).toEqual(['name: misko', 'gender: male']);
```
*
* @param {Object|Array} obj Object to iterate over.
* @param {Function} iterator Iterator function.
* @param {Object=} context Object to become context (`this`) for the iterator function.
* @returns {Object|Array} Reference to `obj`.
*/
vum.forEach = function (obj, iterator, context) {
var key, length
if (obj) {
if (vum.isFunction(obj)) {
for (key in obj) {
// Need to check if hasOwnProperty exists,
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
iterator.call(context, obj[key], key, obj)
}
}
} else if (isArray(obj) || isArrayLike(obj)) {
var isPrimitive = typeof obj !== 'object'
for (key = 0, length = obj.length; key < length; key++) {
if (isPrimitive || key in obj) {
iterator.call(context, obj[key], key, obj)
}
}
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context, obj)
} else if (vum.isBlankObject(obj)) {
// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
for (key in obj) {
iterator.call(context, obj[key], key, obj)
}
} else if (typeof obj.hasOwnProperty === 'function') {
// Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key, obj)
}
}
} else {
// Slow path for objects which do not have a method `hasOwnProperty`
for (key in obj) {
if (hasOwnProperty.call(obj, key)) {
iterator.call(context, obj[key], key, obj)
}
}
}
}
return obj
}
vum.forEachSorted = function (obj, iterator, context) {
var keys = Object.keys(obj).sort()
for (var i = 0; i < keys.length; i++) {
iterator.call(context, obj[keys[i]], keys[i])
}
return keys
}
})(window.vum)
})()
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment