├── .gitignore ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── App.vue ├── base │ ├── login.vue │ ├── nav.vue │ └── sidebar.vue ├── components │ └── harmony.vue ├── main.js └── router │ └── index.js ├── static ├── .gitkeep ├── css │ ├── fonts │ │ ├── Gotham-Book.otf │ │ ├── Gotham-Light.otf │ │ └── Gotham-Medium.otf │ └── index.css ├── img │ ├── chain │ │ ├── harmony_banner.jpg │ │ └── harmony_icon@2x.png │ ├── favicon.ico │ └── icons │ │ ├── MathWallet_Logo_Horizontal_White.png │ │ ├── dropdown_black@2x.png │ │ ├── dropdown_white@2x.png │ │ ├── first@2x.png │ │ ├── first_disabled@2x.png │ │ ├── last@2x.png │ │ ├── last_disabled@2x.png │ │ ├── logout_blue@2x.png │ │ ├── logout_grey@2x.png │ │ ├── mathwallet_webwallet@2x.png │ │ ├── next@2x.png │ │ ├── next_disabled@2x.png │ │ ├── phone_blue@2x.png │ │ ├── previous.png │ │ ├── previous_disabled.png │ │ ├── refresh_blue@2x.png │ │ ├── refresh_grey@2x.png │ │ └── slider@2x.png ├── js │ ├── bignumber.mjs │ ├── coinUnit.js │ ├── common.js │ ├── config.js │ ├── i18n.js │ └── util.js └── lang │ ├── cn.js │ ├── en.js │ └── ko.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # math-harmony-web-wallet 2 | 3 | ## Build Setup 4 | 5 | ``` bash 6 | # install dependencies 7 | npm install 8 | 9 | # serve with hot reload at localhost:8080 10 | npm run dev 11 | 12 | # build for production with minification 13 | npm run build 14 | 15 | # build for production and view the bundle analyzer report 16 | npm run build --report 17 | ``` 18 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/build/logo.png -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function(_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' ? 9 | config.build.assetsSubDirectory : 10 | config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function(options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders(loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader', 51 | publicPath: '../../' 52 | }) 53 | } else { 54 | return ['vue-style-loader'].concat(loaders) 55 | } 56 | } 57 | 58 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 59 | return { 60 | css: generateLoaders(), 61 | postcss: generateLoaders(), 62 | less: generateLoaders('less'), 63 | sass: generateLoaders('sass', { indentedSyntax: true }), 64 | scss: generateLoaders('sass'), 65 | stylus: generateLoaders('stylus'), 66 | styl: generateLoaders('stylus') 67 | } 68 | } 69 | 70 | // Generate loaders for standalone style files (outside of .vue) 71 | exports.styleLoaders = function(options) { 72 | const output = [] 73 | const loaders = exports.cssLoaders(options) 74 | 75 | for (const extension in loaders) { 76 | const loader = loaders[extension] 77 | output.push({ 78 | test: new RegExp('\\.' + extension + '$'), 79 | use: loader 80 | }) 81 | } 82 | 83 | return output 84 | } 85 | 86 | exports.createNotifierCallback = () => { 87 | const notifier = require('node-notifier') 88 | 89 | return (severity, errors) => { 90 | if (severity !== 'error') return 91 | 92 | const error = errors[0] 93 | const filename = error.file && error.file.split('!').pop() 94 | 95 | notifier.notify({ 96 | title: packageConfig.name, 97 | message: severity + ': ' + error.name, 98 | subtitle: filename || '', 99 | icon: path.join(__dirname, 'logo.png') 100 | }) 101 | } 102 | } -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | const webpack = require("webpack") 7 | 8 | function resolve(dir) { 9 | return path.join(__dirname, '..', dir) 10 | } 11 | 12 | 13 | 14 | module.exports = { 15 | context: path.resolve(__dirname, '../'), 16 | entry: { 17 | app: './src/main.js' 18 | }, 19 | output: { 20 | path: config.build.assetsRoot, 21 | filename: '[name].js', 22 | publicPath: process.env.NODE_ENV === 'production' ? 23 | config.build.assetsPublicPath : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | 'static': resolve('static'), 31 | 'base': resolve('src/base'), 32 | 'jquery': 'jquery' 33 | } 34 | }, 35 | plugins: [ 36 | new webpack.ProvidePlugin({ 37 | $: "jquery", 38 | jQuery: "jquery", 39 | 'window.jQuery': "jquery" 40 | }) 41 | ], 42 | module: { 43 | rules: [{ 44 | test: /\.vue$/, 45 | loader: 'vue-loader', 46 | options: vueLoaderConfig 47 | }, 48 | { 49 | test: /\.js$/, 50 | loader: 'babel-loader', 51 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 52 | }, 53 | { 54 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 55 | loader: 'url-loader', 56 | options: { 57 | limit: 10000, 58 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 59 | } 60 | }, 61 | { 62 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 63 | loader: 'url-loader', 64 | options: { 65 | limit: 10000, 66 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 67 | } 68 | }, 69 | { 70 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 71 | loader: 'url-loader', 72 | options: { 73 | limit: 10000, 74 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 75 | } 76 | } 77 | ] 78 | }, 79 | node: { 80 | // prevent webpack from injecting useless setImmediate polyfill because Vue 81 | // source contains it (although only uses it if it's native). 82 | setImmediate: false, 83 | // prevent webpack from injecting mocks to Node native modules 84 | // that does not make sense for the client 85 | dgram: 'empty', 86 | fs: 'empty', 87 | net: 'empty', 88 | tls: 'empty', 89 | child_process: 'empty' 90 | } 91 | } -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 19 | }, 20 | // cheap-module-eval-source-map is faster for development 21 | devtool: config.dev.devtool, 22 | 23 | // these devServer options should be customized in /config/index.js 24 | devServer: { 25 | clientLogLevel: 'warning', 26 | historyApiFallback: { 27 | rewrites: [ 28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 29 | ], 30 | }, 31 | hot: true, 32 | contentBase: false, // since we use CopyWebpackPlugin. 33 | compress: true, 34 | host: HOST || config.dev.host, 35 | port: PORT || config.dev.port, 36 | open: config.dev.autoOpenBrowser, 37 | overlay: config.dev.errorOverlay 38 | ? { warnings: false, errors: true } 39 | : false, 40 | publicPath: config.dev.assetsPublicPath, 41 | proxy: config.dev.proxyTable, 42 | quiet: true, // necessary for FriendlyErrorsPlugin 43 | watchOptions: { 44 | poll: config.dev.poll, 45 | } 46 | }, 47 | plugins: [ 48 | new webpack.DefinePlugin({ 49 | 'process.env': require('../config/dev.env') 50 | }), 51 | new webpack.HotModuleReplacementPlugin(), 52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 53 | new webpack.NoEmitOnErrorsPlugin(), 54 | // https://github.com/ampedandwired/html-webpack-plugin 55 | new HtmlWebpackPlugin({ 56 | filename: 'index.html', 57 | template: 'index.html', 58 | inject: true 59 | }), 60 | // copy custom static assets 61 | new CopyWebpackPlugin([ 62 | { 63 | from: path.resolve(__dirname, '../static'), 64 | to: config.dev.assetsSubDirectory, 65 | ignore: ['.*'] 66 | } 67 | ]) 68 | ] 69 | }) 70 | 71 | module.exports = new Promise((resolve, reject) => { 72 | portfinder.basePort = process.env.PORT || config.dev.port 73 | portfinder.getPort((err, port) => { 74 | if (err) { 75 | reject(err) 76 | } else { 77 | // publish the new Port, necessary for e2e tests 78 | process.env.PORT = port 79 | // add port to devServer config 80 | devWebpackConfig.devServer.port = port 81 | 82 | // Add FriendlyErrorsPlugin 83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 84 | compilationSuccessInfo: { 85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 86 | }, 87 | onErrors: config.dev.notifyOnErrors 88 | ? utils.createNotifierCallback() 89 | : undefined 90 | })) 91 | 92 | resolve(devWebpackConfig) 93 | } 94 | }) 95 | }) 96 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = require('../config/prod.env') 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | 'process.env': env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath('css/[name].[contenthash].css'), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true, 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | new OptimizeCSSPlugin({ 56 | cssProcessorOptions: config.build.productionSourceMap 57 | ? { safe: true, map: { inline: false } } 58 | : { safe: true } 59 | }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: 'index.html', 66 | inject: true, 67 | minify: { 68 | removeComments: true, 69 | collapseWhitespace: true, 70 | removeAttributeQuotes: true 71 | // more options: 72 | // https://github.com/kangax/html-minifier#options-quick-reference 73 | }, 74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 75 | chunksSortMode: 'dependency' 76 | }), 77 | // keep module.id stable when vendor modules does not change 78 | new webpack.HashedModuleIdsPlugin(), 79 | // enable scope hoisting 80 | new webpack.optimize.ModuleConcatenationPlugin(), 81 | // split vendor js into its own file 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'vendor', 84 | minChunks (module) { 85 | // any required modules inside node_modules are extracted to vendor 86 | return ( 87 | module.resource && 88 | /\.js$/.test(module.resource) && 89 | module.resource.indexOf( 90 | path.join(__dirname, '../node_modules') 91 | ) === 0 92 | ) 93 | } 94 | }), 95 | // extract webpack runtime and module manifest to its own file in order to 96 | // prevent vendor hash from being updated whenever app bundle is updated 97 | new webpack.optimize.CommonsChunkPlugin({ 98 | name: 'manifest', 99 | minChunks: Infinity 100 | }), 101 | // This instance extracts shared chunks from code splitted chunks and bundles them 102 | // in a separate chunk, similar to the vendor chunk 103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 104 | new webpack.optimize.CommonsChunkPlugin({ 105 | name: 'app', 106 | async: 'vendor-async', 107 | children: true, 108 | minChunks: 3 109 | }), 110 | 111 | // copy custom static assets 112 | new CopyWebpackPlugin([ 113 | { 114 | from: path.resolve(__dirname, '../static'), 115 | to: config.build.assetsSubDirectory, 116 | ignore: ['.*'] 117 | } 118 | ]) 119 | ] 120 | }) 121 | 122 | if (config.build.productionGzip) { 123 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 124 | 125 | webpackConfig.plugins.push( 126 | new CompressionWebpackPlugin({ 127 | asset: '[path].gz[query]', 128 | algorithm: 'gzip', 129 | test: new RegExp( 130 | '\\.(' + 131 | config.build.productionGzipExtensions.join('|') + 132 | ')$' 133 | ), 134 | threshold: 10240, 135 | minRatio: 0.8 136 | }) 137 | ) 138 | } 139 | 140 | if (config.build.bundleAnalyzerReport) { 141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8081, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist/'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: './', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Math Wallet 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "math-harmony-web-wallet", 3 | "version": "1.0.0", 4 | "description": "math-harmony-web-wallet", 5 | "author": "math", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "@harmony-js/core": "^0.1.28", 14 | "bignumber.js": "^9.0.0", 15 | "bootstrap": "^4.3.1", 16 | "clipboard": "^2.0.4", 17 | "jquery": "^3.4.1", 18 | "popper.js": "^1.15.0", 19 | "tslib": "^1.10.0", 20 | "vue": "^2.5.2", 21 | "vue-i18n": "^8.11.2", 22 | "vue-resource": "^1.5.1", 23 | "vue-router": "^3.0.1", 24 | "wc-messagebox": "^1.10.1" 25 | }, 26 | "devDependencies": { 27 | "autoprefixer": "^7.1.2", 28 | "babel-core": "^6.22.1", 29 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 30 | "babel-loader": "^7.1.1", 31 | "babel-plugin-syntax-jsx": "^6.18.0", 32 | "babel-plugin-transform-runtime": "^6.22.0", 33 | "babel-plugin-transform-vue-jsx": "^3.5.0", 34 | "babel-preset-env": "^1.3.2", 35 | "babel-preset-stage-2": "^6.22.0", 36 | "chalk": "^2.0.1", 37 | "copy-webpack-plugin": "^4.0.1", 38 | "css-loader": "^0.28.0", 39 | "extract-text-webpack-plugin": "^3.0.0", 40 | "file-loader": "^1.1.4", 41 | "friendly-errors-webpack-plugin": "^1.6.1", 42 | "html-webpack-plugin": "^2.30.1", 43 | "node-notifier": "^5.1.2", 44 | "optimize-css-assets-webpack-plugin": "^3.2.0", 45 | "ora": "^1.2.0", 46 | "portfinder": "^1.0.13", 47 | "postcss-import": "^11.0.0", 48 | "postcss-loader": "^2.0.8", 49 | "postcss-url": "^7.2.1", 50 | "rimraf": "^2.6.0", 51 | "semver": "^5.3.0", 52 | "shelljs": "^0.7.6", 53 | "uglifyjs-webpack-plugin": "^1.1.1", 54 | "url-loader": "^0.5.8", 55 | "vue-loader": "^13.3.0", 56 | "vue-style-loader": "^3.0.1", 57 | "vue-template-compiler": "^2.5.2", 58 | "webpack": "^3.6.0", 59 | "webpack-bundle-analyzer": "^2.9.0", 60 | "webpack-dev-server": "^2.9.1", 61 | "webpack-merge": "^4.1.0" 62 | }, 63 | "engines": { 64 | "node": ">= 6.0.0", 65 | "npm": ">= 3.0.0" 66 | }, 67 | "browserslist": [ 68 | "> 1%", 69 | "last 2 versions", 70 | "not ie <= 8" 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'autoprefixer': { browsers: 'last 5 version' } 4 | } 5 | } -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /src/base/login.vue: -------------------------------------------------------------------------------- 1 | 11 | 55 | -------------------------------------------------------------------------------- /src/base/nav.vue: -------------------------------------------------------------------------------- 1 | 55 | 111 | 121 | -------------------------------------------------------------------------------- /src/base/sidebar.vue: -------------------------------------------------------------------------------- 1 | 47 | 65 | 156 | -------------------------------------------------------------------------------- /src/components/harmony.vue: -------------------------------------------------------------------------------- 1 | 130 | 799 | 800 | 801 | 802 | 811 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import vueResource from 'vue-resource' 7 | import i18n from 'static/js/i18n' 8 | import webUtil from 'static/js/util' 9 | import globalData from 'static/js/config.js' 10 | import webCoin from 'static/js/coinUnit.js' 11 | import 'bootstrap' 12 | import 'bootstrap/dist/css/bootstrap.min.css' 13 | import 'static/css/index.css' 14 | import clipboard from 'clipboard' 15 | import { Alert, Confirm, Toast, Loading } from "wc-messagebox"; 16 | import "wc-messagebox/style.css"; 17 | 18 | Vue.config.productionTip = false 19 | Vue.use(vueResource) 20 | 21 | /*注册到vue原型上*/ 22 | Vue.prototype.globalData = globalData; 23 | Vue.prototype.clipboard = clipboard; 24 | Vue.prototype.webUtil = webUtil; 25 | Vue.prototype.webCoin = webCoin; 26 | 27 | 28 | /* eslint-disable no-new */ 29 | var vue1 = new Vue({ 30 | el: '#app', 31 | i18n, 32 | router, 33 | components: { App }, 34 | template: '' 35 | }); 36 | 37 | Vue.use(Alert, { 38 | title: vue1.$t('prompt'), 39 | btnText: 'OK' 40 | }); 41 | Vue.use(Confirm, { 42 | title: vue1.$t('Confirm'), 43 | }); 44 | Vue.use(Toast, { 45 | location: 'bottom', 46 | toastStyle: { 47 | height: '60px', 48 | width: '160px', 49 | fontSize: '16px' 50 | }, 51 | }); 52 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | Vue.use(Router) 4 | 5 | export default new Router({ 6 | routes: [{ 7 | path: '/', 8 | name: 'harmony', 9 | component: resolve => require(['@/components/harmony'], resolve) 10 | }] 11 | }) 12 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/.gitkeep -------------------------------------------------------------------------------- /static/css/fonts/Gotham-Book.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/css/fonts/Gotham-Book.otf -------------------------------------------------------------------------------- /static/css/fonts/Gotham-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/css/fonts/Gotham-Light.otf -------------------------------------------------------------------------------- /static/css/fonts/Gotham-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/css/fonts/Gotham-Medium.otf -------------------------------------------------------------------------------- /static/css/index.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | :root { 3 | --darkbg: #2c363f; 4 | --blueColor: #007aff; 5 | --greenColor: #4cd964; 6 | --greyColor: #8a8a8f; 7 | --pale-grey: #efeff4; 8 | } 9 | 10 | @font-face { 11 | font-family: Gotham-Book; 12 | src: url("fonts/Gotham-Book.otf") 13 | } 14 | 15 | @font-face { 16 | font-family: Gotham-Light; 17 | src: url("fonts/Gotham-Light.otf") 18 | } 19 | 20 | @font-face { 21 | font-family: Gotham-Medium; 22 | src: url("fonts/Gotham-Medium.otf") 23 | } 24 | 25 | 26 | /* 禁用iPhone中Safari的字号自动调整 */ 27 | 28 | html { 29 | -webkit-text-size-adjust: 100%; 30 | -ms-text-size-adjust: 100%; 31 | /* 解决IOS默认滑动很卡的情况 */ 32 | -webkit-overflow-scrolling: touch; 33 | font-size: 14px; 34 | } 35 | 36 | p, 37 | div, 38 | ul, 39 | li, 40 | h1, 41 | h2, 42 | h3, 43 | h4, 44 | h5, 45 | h6 { 46 | margin: 0; 47 | } 48 | 49 | body { 50 | font-family: Gotham-Book; 51 | color: #000; 52 | background-color: var(--pale-grey); 53 | min-width: 1272px; 54 | overflow: scroll; 55 | } 56 | 57 | ul, 58 | li { 59 | list-style: none; 60 | padding-left: 0; 61 | } 62 | 63 | a, 64 | a:hover, 65 | a:active, 66 | a:focus { 67 | text-decoration: none; 68 | cursor: pointer; 69 | } 70 | 71 | button, 72 | textarea, 73 | input, 74 | select { 75 | outline: none; 76 | resize: none; 77 | box-shadow: none; 78 | /*去掉ios阴影*/ 79 | -webkit-appearance: none; 80 | -webkit-tap-highlight-color: transparent; 81 | box-sizing: border-box; 82 | -webkit-box-sizing: border-box; 83 | background: transparent; 84 | } 85 | 86 | img+span { 87 | vertical-align: middle; 88 | } 89 | 90 | i { 91 | font-style: normal; 92 | } 93 | 94 | [v-cloak] { 95 | display: none; 96 | } 97 | .wc-mask{ 98 | user-select: text!important; 99 | } 100 | .wc-popup-text{ 101 | word-break:break-all; 102 | } 103 | .wc-popup { 104 | top: 40%!important; 105 | } 106 | .caret { 107 | width: 12px; 108 | height: 12px; 109 | border: none; 110 | background: url(../img/icons/dropdown_white@2x.png) no-repeat center /12px; 111 | } 112 | 113 | .btn { 114 | color: #fff !important; 115 | background: var(--blueColor); 116 | padding: 12px 24px; 117 | font-family: Gotham-Medium; 118 | font-weight: 500; 119 | } 120 | 121 | .grey-fsz { 122 | font-size: 12px; 123 | line-height: 16px; 124 | color: var(--greyColor) !important; 125 | } 126 | 127 | .null { 128 | padding: 32px; 129 | text-align: center; 130 | } 131 | 132 | 133 | /*nav*/ 134 | 135 | .math-nav { 136 | background: var(--darkbg); 137 | padding: 16px 24px; 138 | position: fixed; 139 | left: 0; 140 | right: 0; 141 | top: 0; 142 | z-index: 500; 143 | } 144 | 145 | .math-nav a, 146 | .math-nav a:hover { 147 | color: #fff; 148 | } 149 | 150 | .math-nav .dropdown { 151 | display: inline-block; 152 | padding-left: 24px; 153 | } 154 | 155 | .dropdown-menu { 156 | min-width: 0; 157 | margin-top: 10px; 158 | overflow: hidden; 159 | } 160 | 161 | .math-nav .dropdown li { 162 | cursor: pointer; 163 | padding: 6px 20px; 164 | } 165 | 166 | .math-nav .float-right .mobile { 167 | color: #5ac8fa; 168 | padding-right: 24px; 169 | border-right: 1px solid rgba(255, 255, 255, 0.2); 170 | } 171 | 172 | .math-nav .float-right { 173 | padding: 8px; 174 | line-height: 16px; 175 | } 176 | 177 | .math-nav img+span { 178 | vertical-align: text-top; 179 | } 180 | 181 | 182 | /*首页登录*/ 183 | 184 | .main-container { 185 | overflow: hidden; 186 | margin: 96px auto 32px; 187 | width: 824px; 188 | background: #fff; 189 | } 190 | 191 | .login-container { 192 | text-align: center; 193 | margin-bottom: 96px; 194 | font-size: 16px; 195 | line-height: 1.5; 196 | color: var(--greyColor); 197 | } 198 | 199 | .login-container .info { 200 | padding: 64px 24px 48px; 201 | } 202 | 203 | .login-container h1 { 204 | font-size: 24px; 205 | font-family: Gotham-Medium; 206 | font-weight: 500; 207 | line-height: 1.33; 208 | margin-bottom: 8px; 209 | color: #000; 210 | } 211 | 212 | .login-container .btn { 213 | display: inline-block; 214 | margin-top: 48px; 215 | } 216 | 217 | 218 | /*copyright*/ 219 | 220 | .copyright { 221 | text-align: center; 222 | font-size: 12px; 223 | line-height: 16px; 224 | padding: 16px; 225 | color: var(--greyColor); 226 | } 227 | 228 | .webwallet+.copyright { 229 | padding-left: 400px; 230 | } 231 | 232 | 233 | /*左边列表*/ 234 | 235 | .user-info { 236 | position: fixed; 237 | left: 0; 238 | top: 64px; 239 | bottom: 48px; 240 | width: 400px; 241 | background: #fff; 242 | z-index: 100; 243 | padding: 32px 24px 0; 244 | font-size: 12px; 245 | line-height: 16px; 246 | overflow-y: scroll; 247 | } 248 | 249 | .user-info .avator { 250 | width: 96px; 251 | height: 96px; 252 | display: inline-block; 253 | border-radius: 50%; 254 | box-shadow: 0 0 1px 1px var(--pale-grey); 255 | border: 8px solid #fff; 256 | overflow: hidden; 257 | margin-bottom: 12px; 258 | } 259 | 260 | .user-info h4 { 261 | font-size: 20px; 262 | font-weight: 500; 263 | font-family: Gotham-Medium; 264 | line-height: 1.2; 265 | margin: 4px 0; 266 | } 267 | 268 | .user-info .operation-list { 269 | margin-top: 34px; 270 | cursor: pointer; 271 | } 272 | 273 | .user-info .token-info { 274 | margin-top: 32px; 275 | padding: 32px 0; 276 | border-top: 1px solid var(--pale-grey); 277 | } 278 | 279 | .user-info .token-list { 280 | margin-top: 32px; 281 | padding-left: 0; 282 | } 283 | 284 | .user-info .token-list li { 285 | display: flex; 286 | justify-content: space-between; 287 | padding: 4px 0; 288 | } 289 | 290 | .refresh-logout { 291 | position: fixed; 292 | bottom: 0; 293 | left: 0; 294 | width: 400px; 295 | padding: 16px 24px; 296 | background: #fff; 297 | text-align: left; 298 | } 299 | 300 | .refresh-logout a { 301 | padding-left: 20px; 302 | } 303 | 304 | .refresh-logout a:first-child { 305 | background: url(../img/icons/refresh_grey@2x.png) no-repeat left center/16px; 306 | } 307 | 308 | .refresh-logout a:last-child { 309 | background: url(../img/icons/logout_grey@2x.png) no-repeat left center/16px; 310 | } 311 | 312 | .refresh-logout a:hover:first-child { 313 | background: url(../img/icons/refresh_blue@2x.png) no-repeat left center/16px; 314 | } 315 | 316 | .refresh-logout a:hover:last-child { 317 | background: url(../img/icons/logout_blue@2x.png) no-repeat left center/16px; 318 | } 319 | 320 | .operation-list a:nth-child(2) { 321 | border-left: 1px solid var(--pale-grey); 322 | margin-left: 12px; 323 | padding-left: 12px; 324 | } 325 | 326 | .refresh-logout a:first-child { 327 | border-right: 1px solid var(--pale-grey); 328 | margin-right: 12px; 329 | padding-right: 12px; 330 | } 331 | 332 | .user-info a:hover, 333 | .refresh-logout a:hover { 334 | color: var(--blueColor) !important; 335 | cursor: pointer; 336 | } 337 | 338 | 339 | /*中间内容*/ 340 | 341 | .main-info { 342 | margin-left: 400px; 343 | padding: 0 24px; 344 | } 345 | 346 | .transfer-container { 347 | padding: 16px 24px 32px; 348 | } 349 | 350 | .transfer-container .btn { 351 | display: block; 352 | } 353 | 354 | .tabs { 355 | border-bottom: 1px solid var(--pale-grey); 356 | display: flex; 357 | justify-content: flex-start; 358 | } 359 | 360 | .tabs .tab { 361 | margin-right: 24px; 362 | padding-bottom: 16px; 363 | color: var(--geryColor); 364 | font-size: 16px; 365 | line-height: 1.5; 366 | } 367 | 368 | .tabs .tab.active { 369 | font-weight: 500; 370 | font-family: Gotham-Medium; 371 | color: var(--blueColor); 372 | border-bottom: 2px solid var(--blueColor); 373 | } 374 | 375 | .basic-form label { 376 | font-size: 12px; 377 | line-height: 16px; 378 | margin: 32px 0 8px; 379 | font-weight: 400; 380 | } 381 | 382 | .basic-form input, 383 | .basic-form select, 384 | .basic-form .input { 385 | display: block; 386 | padding: 12px; 387 | line-height: 1.5; 388 | font-size: 16px; 389 | border: 1px solid var(--pale-grey); 390 | width: 100%; 391 | word-wrap: break-word; 392 | } 393 | 394 | .basic-form .btn { 395 | margin-top: 32px; 396 | width: 100%; 397 | } 398 | 399 | .basic-group li { 400 | float: left; 401 | } 402 | 403 | .basic-group .amount { 404 | width: calc(100% - 190px); 405 | } 406 | 407 | .basic-group .token { 408 | width: 164px; 409 | margin-left: 24px; 410 | float: right; 411 | } 412 | 413 | .basic-group select { 414 | background: url(../img/icons/dropdown_black@2x.png)no-repeat 140px center/12px; 415 | border-radius: 0; 416 | } 417 | 418 | 419 | /*table*/ 420 | 421 | .transactions { 422 | font-size: 12px; 423 | line-height: 16px; 424 | } 425 | 426 | .transactions thead th { 427 | padding: 12px 0; 428 | } 429 | 430 | .transactions td { 431 | padding: 8px 0; 432 | padding-right: 24px; 433 | width: 160px; 434 | max-width: 160px; 435 | overflow: hidden; 436 | white-space: nowrap; 437 | text-overflow: ellipsis; 438 | } 439 | 440 | .transactions tr td a { 441 | color: #000; 442 | padding: 4px 0; 443 | font-size: 12px; 444 | } 445 | 446 | .transactions tr td:first-child a { 447 | color: var(--blueColor)!important; 448 | } 449 | 450 | .transactions tr td:nth-child(2) a { 451 | padding: 4px 8px; 452 | background: #f7f7fa; 453 | } 454 | 455 | .transactions tr td:nth-child(3) { 456 | width: 216px; 457 | max-width: 216px; 458 | } 459 | 460 | .transactions tr td:nth-child(4) { 461 | width: 104px; 462 | max-width: 104px; 463 | } 464 | 465 | .transactions tr td:nth-child(4) a { 466 | color: var(--greenColor); 467 | } 468 | 469 | .transactions tr td:last-child, 470 | .transactions tr th:last-child { 471 | text-align: right; 472 | padding-right: 0; 473 | } 474 | 475 | .page-pagination { 476 | text-align: right; 477 | margin-top: 15px; 478 | padding-top: 20px; 479 | border-top: 1px solid var(--pale-grey); 480 | } 481 | 482 | .page-pagination img, 483 | .page-pagination span { 484 | margin-left: 16px; 485 | vertical-align: middle; 486 | } 487 | 488 | .page-pagination .clickable { 489 | cursor: pointer; 490 | } 491 | 492 | .page-pagination i { 493 | color: var(--greyColor); 494 | } 495 | 496 | .transfer-container h5 { 497 | font-size: 16px; 498 | font-weight: 500; 499 | font-family: Gotham-Medium; 500 | line-height: 1.5; 501 | padding-bottom: 15px; 502 | } 503 | 504 | .trans_detail { 505 | font-size: 12px; 506 | line-height: 16px; 507 | padding-top: 32px; 508 | border-top: 1px solid var(--pale-grey); 509 | } 510 | 511 | .trans_detail h4 { 512 | font-size: 20px; 513 | font-weight: 500; 514 | font-family: Gotham-Medium; 515 | line-height: 1.2; 516 | margin: 4px 0; 517 | } 518 | 519 | .trans_detail ul { 520 | padding: 16px 0 0; 521 | } 522 | 523 | .trans_detail li { 524 | padding: 12px 0; 525 | display: flex; 526 | justify-content: flex-start; 527 | } 528 | 529 | .trans_detail li span { 530 | width: 164px; 531 | min-width: 164px; 532 | margin-right: 24px; 533 | color: var(--greyColor); 534 | } 535 | 536 | .trans_detail li:first-child p { 537 | color: var(--greenColor); 538 | } 539 | 540 | .trans_detail li p { 541 | word-wrap: break-word; 542 | } 543 | 544 | .trans_detail .txHash { 545 | padding-top: 28px; 546 | margin-top: 16px; 547 | border-top: 1px solid var(--pale-grey); 548 | } 549 | 550 | .fee-set .setBtn { 551 | cursor: pointer; 552 | color: var(--blueColor); 553 | padding-left: 12px; 554 | margin-left: 12px; 555 | border-left: 1px solid var(--pale-grey); 556 | } 557 | 558 | .fee-set li { 559 | position: relative; 560 | float: left; 561 | } 562 | 563 | .fee-set li span { 564 | position: absolute; 565 | top: 16px; 566 | left: 12px; 567 | font-size: 12px; 568 | line-height: 24px; 569 | } 570 | 571 | .fee-set .slider { 572 | position: relative; 573 | margin: 14px 0 30px; 574 | height: 4px; 575 | background: var(--pale-grey); 576 | cursor: pointer 577 | } 578 | 579 | .fee-set .slider .thunk { 580 | position: absolute; 581 | left: 100px; 582 | top: -14px; 583 | width: 32px; 584 | height: 32px 585 | } 586 | 587 | .fee-set .slider .block { 588 | width: 32px; 589 | height: 32px; 590 | border-radius: 50%; 591 | border: 1px solid var(--pale-grey); 592 | background: #fff; 593 | transition: .2s all; 594 | text-align: center; 595 | line-height: 32px; 596 | } 597 | 598 | .fee-set .slider .cheap, 599 | .fee-set .slider .fast { 600 | position: absolute; 601 | top: 18px; 602 | color: var(--greyColor); 603 | font-size: 12px; 604 | line-height: 16px; 605 | } 606 | 607 | .fee-set .slider .cheap { 608 | left: 0; 609 | } 610 | 611 | .fee-set .slider .fast { 612 | right: 0; 613 | } 614 | 615 | .fee-set .gas-price, 616 | .fee-set .gas-limit { 617 | width: 282px; 618 | } 619 | 620 | .fee-set .gas-limit { 621 | margin-left: 24px; 622 | } 623 | 624 | .fee-set .gas-price input, 625 | .fee-set .gas-limit input { 626 | text-align: right; 627 | padding-left: 130px; 628 | } 629 | -------------------------------------------------------------------------------- /static/img/chain/harmony_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/chain/harmony_banner.jpg -------------------------------------------------------------------------------- /static/img/chain/harmony_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/chain/harmony_icon@2x.png -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/icons/MathWallet_Logo_Horizontal_White.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/MathWallet_Logo_Horizontal_White.png -------------------------------------------------------------------------------- /static/img/icons/dropdown_black@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/dropdown_black@2x.png -------------------------------------------------------------------------------- /static/img/icons/dropdown_white@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/dropdown_white@2x.png -------------------------------------------------------------------------------- /static/img/icons/first@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/first@2x.png -------------------------------------------------------------------------------- /static/img/icons/first_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/first_disabled@2x.png -------------------------------------------------------------------------------- /static/img/icons/last@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/last@2x.png -------------------------------------------------------------------------------- /static/img/icons/last_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/last_disabled@2x.png -------------------------------------------------------------------------------- /static/img/icons/logout_blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/logout_blue@2x.png -------------------------------------------------------------------------------- /static/img/icons/logout_grey@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/logout_grey@2x.png -------------------------------------------------------------------------------- /static/img/icons/mathwallet_webwallet@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/mathwallet_webwallet@2x.png -------------------------------------------------------------------------------- /static/img/icons/next@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/next@2x.png -------------------------------------------------------------------------------- /static/img/icons/next_disabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/next_disabled@2x.png -------------------------------------------------------------------------------- /static/img/icons/phone_blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/phone_blue@2x.png -------------------------------------------------------------------------------- /static/img/icons/previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/previous.png -------------------------------------------------------------------------------- /static/img/icons/previous_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/previous_disabled.png -------------------------------------------------------------------------------- /static/img/icons/refresh_blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/refresh_blue@2x.png -------------------------------------------------------------------------------- /static/img/icons/refresh_grey@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/refresh_grey@2x.png -------------------------------------------------------------------------------- /static/img/icons/slider@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/slider@2x.png -------------------------------------------------------------------------------- /static/js/bignumber.mjs: -------------------------------------------------------------------------------- 1 | /* 2 | * bignumber.js v9.0.0 3 | * A JavaScript library for arbitrary-precision arithmetic. 4 | * https://github.com/MikeMcl/bignumber.js 5 | * Copyright (c) 2019 Michael Mclaughlin 6 | * MIT Licensed. 7 | * 8 | * BigNumber.prototype methods | BigNumber methods 9 | * | 10 | * absoluteValue abs | clone 11 | * comparedTo | config set 12 | * decimalPlaces dp | DECIMAL_PLACES 13 | * dividedBy div | ROUNDING_MODE 14 | * dividedToIntegerBy idiv | EXPONENTIAL_AT 15 | * exponentiatedBy pow | RANGE 16 | * integerValue | CRYPTO 17 | * isEqualTo eq | MODULO_MODE 18 | * isFinite | POW_PRECISION 19 | * isGreaterThan gt | FORMAT 20 | * isGreaterThanOrEqualTo gte | ALPHABET 21 | * isInteger | isBigNumber 22 | * isLessThan lt | maximum max 23 | * isLessThanOrEqualTo lte | minimum min 24 | * isNaN | random 25 | * isNegative | sum 26 | * isPositive | 27 | * isZero | 28 | * minus | 29 | * modulo mod | 30 | * multipliedBy times | 31 | * negated | 32 | * plus | 33 | * precision sd | 34 | * shiftedBy | 35 | * squareRoot sqrt | 36 | * toExponential | 37 | * toFixed | 38 | * toFormat | 39 | * toFraction | 40 | * toJSON | 41 | * toNumber | 42 | * toPrecision | 43 | * toString | 44 | * valueOf | 45 | * 46 | */ 47 | 48 | 49 | var 50 | isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, 51 | 52 | mathceil = Math.ceil, 53 | mathfloor = Math.floor, 54 | 55 | bignumberError = '[BigNumber Error] ', 56 | tooManyDigits = bignumberError + 'Number primitive has more than 15 significant digits: ', 57 | 58 | BASE = 1e14, 59 | LOG_BASE = 14, 60 | MAX_SAFE_INTEGER = 0x1fffffffffffff, // 2^53 - 1 61 | // MAX_INT32 = 0x7fffffff, // 2^31 - 1 62 | POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], 63 | SQRT_BASE = 1e7, 64 | 65 | // EDITABLE 66 | // The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and 67 | // the arguments to toExponential, toFixed, toFormat, and toPrecision. 68 | MAX = 1E9; // 0 to MAX_INT32 69 | 70 | 71 | /* 72 | * Create and return a BigNumber constructor. 73 | */ 74 | function clone(configObject) { 75 | var div, convertBase, parseNumeric, 76 | P = BigNumber.prototype = { constructor: BigNumber, toString: null, valueOf: null }, 77 | ONE = new BigNumber(1), 78 | 79 | 80 | //----------------------------- EDITABLE CONFIG DEFAULTS ------------------------------- 81 | 82 | 83 | // The default values below must be integers within the inclusive ranges stated. 84 | // The values can also be changed at run-time using BigNumber.set. 85 | 86 | // The maximum number of decimal places for operations involving division. 87 | DECIMAL_PLACES = 20, // 0 to MAX 88 | 89 | // The rounding mode used when rounding to the above decimal places, and when using 90 | // toExponential, toFixed, toFormat and toPrecision, and round (default value). 91 | // UP 0 Away from zero. 92 | // DOWN 1 Towards zero. 93 | // CEIL 2 Towards +Infinity. 94 | // FLOOR 3 Towards -Infinity. 95 | // HALF_UP 4 Towards nearest neighbour. If equidistant, up. 96 | // HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. 97 | // HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. 98 | // HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. 99 | // HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. 100 | ROUNDING_MODE = 4, // 0 to 8 101 | 102 | // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS] 103 | 104 | // The exponent value at and beneath which toString returns exponential notation. 105 | // Number type: -7 106 | TO_EXP_NEG = -7, // 0 to -MAX 107 | 108 | // The exponent value at and above which toString returns exponential notation. 109 | // Number type: 21 110 | TO_EXP_POS = 21, // 0 to MAX 111 | 112 | // RANGE : [MIN_EXP, MAX_EXP] 113 | 114 | // The minimum exponent value, beneath which underflow to zero occurs. 115 | // Number type: -324 (5e-324) 116 | MIN_EXP = -1e7, // -1 to -MAX 117 | 118 | // The maximum exponent value, above which overflow to Infinity occurs. 119 | // Number type: 308 (1.7976931348623157e+308) 120 | // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow. 121 | MAX_EXP = 1e7, // 1 to MAX 122 | 123 | // Whether to use cryptographically-secure random number generation, if available. 124 | CRYPTO = false, // true or false 125 | 126 | // The modulo mode used when calculating the modulus: a mod n. 127 | // The quotient (q = a / n) is calculated according to the corresponding rounding mode. 128 | // The remainder (r) is calculated as: r = a - n * q. 129 | // 130 | // UP 0 The remainder is positive if the dividend is negative, else is negative. 131 | // DOWN 1 The remainder has the same sign as the dividend. 132 | // This modulo mode is commonly known as 'truncated division' and is 133 | // equivalent to (a % n) in JavaScript. 134 | // FLOOR 3 The remainder has the same sign as the divisor (Python %). 135 | // HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function. 136 | // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). 137 | // The remainder is always positive. 138 | // 139 | // The truncated division, floored division, Euclidian division and IEEE 754 remainder 140 | // modes are commonly used for the modulus operation. 141 | // Although the other rounding modes can also be used, they may not give useful results. 142 | MODULO_MODE = 1, // 0 to 9 143 | 144 | // The maximum number of significant digits of the result of the exponentiatedBy operation. 145 | // If POW_PRECISION is 0, there will be unlimited significant digits. 146 | POW_PRECISION = 0, // 0 to MAX 147 | 148 | // The format specification used by the BigNumber.prototype.toFormat method. 149 | FORMAT = { 150 | prefix: '', 151 | groupSize: 3, 152 | secondaryGroupSize: 0, 153 | groupSeparator: ',', 154 | decimalSeparator: '.', 155 | fractionGroupSize: 0, 156 | fractionGroupSeparator: '\xA0', // non-breaking space 157 | suffix: '' 158 | }, 159 | 160 | // The alphabet used for base conversion. It must be at least 2 characters long, with no '+', 161 | // '-', '.', whitespace, or repeated character. 162 | // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_' 163 | ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz'; 164 | 165 | 166 | //------------------------------------------------------------------------------------------ 167 | 168 | 169 | // CONSTRUCTOR 170 | 171 | 172 | /* 173 | * The BigNumber constructor and exported function. 174 | * Create and return a new instance of a BigNumber object. 175 | * 176 | * v {number|string|BigNumber} A numeric value. 177 | * [b] {number} The base of v. Integer, 2 to ALPHABET.length inclusive. 178 | */ 179 | function BigNumber(v, b) { 180 | var alphabet, c, caseChanged, e, i, isNum, len, str, 181 | x = this; 182 | 183 | // Enable constructor call without `new`. 184 | if (!(x instanceof BigNumber)) return new BigNumber(v, b); 185 | 186 | if (b == null) { 187 | 188 | if (v && v._isBigNumber === true) { 189 | x.s = v.s; 190 | 191 | if (!v.c || v.e > MAX_EXP) { 192 | x.c = x.e = null; 193 | } else if (v.e < MIN_EXP) { 194 | x.c = [x.e = 0]; 195 | } else { 196 | x.e = v.e; 197 | x.c = v.c.slice(); 198 | } 199 | 200 | return; 201 | } 202 | 203 | if ((isNum = typeof v == 'number') && v * 0 == 0) { 204 | 205 | // Use `1 / n` to handle minus zero also. 206 | x.s = 1 / v < 0 ? (v = -v, -1) : 1; 207 | 208 | // Fast path for integers, where n < 2147483648 (2**31). 209 | if (v === ~~v) { 210 | for (e = 0, i = v; i >= 10; i /= 10, e++); 211 | 212 | if (e > MAX_EXP) { 213 | x.c = x.e = null; 214 | } else { 215 | x.e = e; 216 | x.c = [v]; 217 | } 218 | 219 | return; 220 | } 221 | 222 | str = String(v); 223 | } else { 224 | 225 | if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum); 226 | 227 | x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1; 228 | } 229 | 230 | // Decimal point? 231 | if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); 232 | 233 | // Exponential form? 234 | if ((i = str.search(/e/i)) > 0) { 235 | 236 | // Determine exponent. 237 | if (e < 0) e = i; 238 | e += +str.slice(i + 1); 239 | str = str.substring(0, i); 240 | } else if (e < 0) { 241 | 242 | // Integer. 243 | e = str.length; 244 | } 245 | 246 | } else { 247 | 248 | // '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}' 249 | intCheck(b, 2, ALPHABET.length, 'Base'); 250 | 251 | // Allow exponential notation to be used with base 10 argument, while 252 | // also rounding to DECIMAL_PLACES as with other bases. 253 | if (b == 10) { 254 | x = new BigNumber(v); 255 | return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE); 256 | } 257 | 258 | str = String(v); 259 | 260 | if (isNum = typeof v == 'number') { 261 | 262 | // Avoid potential interpretation of Infinity and NaN as base 44+ values. 263 | if (v * 0 != 0) return parseNumeric(x, str, isNum, b); 264 | 265 | x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1; 266 | 267 | // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}' 268 | if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, '').length > 15) { 269 | throw Error 270 | (tooManyDigits + v); 271 | } 272 | } else { 273 | x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1; 274 | } 275 | 276 | alphabet = ALPHABET.slice(0, b); 277 | e = i = 0; 278 | 279 | // Check that str is a valid base b number. 280 | // Don't use RegExp, so alphabet can contain special characters. 281 | for (len = str.length; i < len; i++) { 282 | if (alphabet.indexOf(c = str.charAt(i)) < 0) { 283 | if (c == '.') { 284 | 285 | // If '.' is not the first character and it has not be found before. 286 | if (i > e) { 287 | e = len; 288 | continue; 289 | } 290 | } else if (!caseChanged) { 291 | 292 | // Allow e.g. hexadecimal 'FF' as well as 'ff'. 293 | if (str == str.toUpperCase() && (str = str.toLowerCase()) || 294 | str == str.toLowerCase() && (str = str.toUpperCase())) { 295 | caseChanged = true; 296 | i = -1; 297 | e = 0; 298 | continue; 299 | } 300 | } 301 | 302 | return parseNumeric(x, String(v), isNum, b); 303 | } 304 | } 305 | 306 | // Prevent later check for length on converted number. 307 | isNum = false; 308 | str = convertBase(str, b, 10, x.s); 309 | 310 | // Decimal point? 311 | if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); 312 | else e = str.length; 313 | } 314 | 315 | // Determine leading zeros. 316 | for (i = 0; str.charCodeAt(i) === 48; i++); 317 | 318 | // Determine trailing zeros. 319 | for (len = str.length; str.charCodeAt(--len) === 48;); 320 | 321 | if (str = str.slice(i, ++len)) { 322 | len -= i; 323 | 324 | // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}' 325 | if (isNum && BigNumber.DEBUG && 326 | len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) { 327 | throw Error 328 | (tooManyDigits + (x.s * v)); 329 | } 330 | 331 | // Overflow? 332 | if ((e = e - i - 1) > MAX_EXP) { 333 | 334 | // Infinity. 335 | x.c = x.e = null; 336 | 337 | // Underflow? 338 | } else if (e < MIN_EXP) { 339 | 340 | // Zero. 341 | x.c = [x.e = 0]; 342 | } else { 343 | x.e = e; 344 | x.c = []; 345 | 346 | // Transform base 347 | 348 | // e is the base 10 exponent. 349 | // i is where to slice str to get the first element of the coefficient array. 350 | i = (e + 1) % LOG_BASE; 351 | if (e < 0) i += LOG_BASE; // i < 1 352 | 353 | if (i < len) { 354 | if (i) x.c.push(+str.slice(0, i)); 355 | 356 | for (len -= LOG_BASE; i < len;) { 357 | x.c.push(+str.slice(i, i += LOG_BASE)); 358 | } 359 | 360 | i = LOG_BASE - (str = str.slice(i)).length; 361 | } else { 362 | i -= len; 363 | } 364 | 365 | for (; i--; str += '0'); 366 | x.c.push(+str); 367 | } 368 | } else { 369 | 370 | // Zero. 371 | x.c = [x.e = 0]; 372 | } 373 | } 374 | 375 | 376 | // CONSTRUCTOR PROPERTIES 377 | 378 | 379 | BigNumber.clone = clone; 380 | 381 | BigNumber.ROUND_UP = 0; 382 | BigNumber.ROUND_DOWN = 1; 383 | BigNumber.ROUND_CEIL = 2; 384 | BigNumber.ROUND_FLOOR = 3; 385 | BigNumber.ROUND_HALF_UP = 4; 386 | BigNumber.ROUND_HALF_DOWN = 5; 387 | BigNumber.ROUND_HALF_EVEN = 6; 388 | BigNumber.ROUND_HALF_CEIL = 7; 389 | BigNumber.ROUND_HALF_FLOOR = 8; 390 | BigNumber.EUCLID = 9; 391 | 392 | 393 | /* 394 | * Configure infrequently-changing library-wide settings. 395 | * 396 | * Accept an object with the following optional properties (if the value of a property is 397 | * a number, it must be an integer within the inclusive range stated): 398 | * 399 | * DECIMAL_PLACES {number} 0 to MAX 400 | * ROUNDING_MODE {number} 0 to 8 401 | * EXPONENTIAL_AT {number|number[]} -MAX to MAX or [-MAX to 0, 0 to MAX] 402 | * RANGE {number|number[]} -MAX to MAX (not zero) or [-MAX to -1, 1 to MAX] 403 | * CRYPTO {boolean} true or false 404 | * MODULO_MODE {number} 0 to 9 405 | * POW_PRECISION {number} 0 to MAX 406 | * ALPHABET {string} A string of two or more unique characters which does 407 | * not contain '.'. 408 | * FORMAT {object} An object with some of the following properties: 409 | * prefix {string} 410 | * groupSize {number} 411 | * secondaryGroupSize {number} 412 | * groupSeparator {string} 413 | * decimalSeparator {string} 414 | * fractionGroupSize {number} 415 | * fractionGroupSeparator {string} 416 | * suffix {string} 417 | * 418 | * (The values assigned to the above FORMAT object properties are not checked for validity.) 419 | * 420 | * E.g. 421 | * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 }) 422 | * 423 | * Ignore properties/parameters set to null or undefined, except for ALPHABET. 424 | * 425 | * Return an object with the properties current values. 426 | */ 427 | BigNumber.config = BigNumber.set = function (obj) { 428 | var p, v; 429 | 430 | if (obj != null) { 431 | 432 | if (typeof obj == 'object') { 433 | 434 | // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive. 435 | // '[BigNumber Error] DECIMAL_PLACES {not a primitive number|not an integer|out of range}: {v}' 436 | if (obj.hasOwnProperty(p = 'DECIMAL_PLACES')) { 437 | v = obj[p]; 438 | intCheck(v, 0, MAX, p); 439 | DECIMAL_PLACES = v; 440 | } 441 | 442 | // ROUNDING_MODE {number} Integer, 0 to 8 inclusive. 443 | // '[BigNumber Error] ROUNDING_MODE {not a primitive number|not an integer|out of range}: {v}' 444 | if (obj.hasOwnProperty(p = 'ROUNDING_MODE')) { 445 | v = obj[p]; 446 | intCheck(v, 0, 8, p); 447 | ROUNDING_MODE = v; 448 | } 449 | 450 | // EXPONENTIAL_AT {number|number[]} 451 | // Integer, -MAX to MAX inclusive or 452 | // [integer -MAX to 0 inclusive, 0 to MAX inclusive]. 453 | // '[BigNumber Error] EXPONENTIAL_AT {not a primitive number|not an integer|out of range}: {v}' 454 | if (obj.hasOwnProperty(p = 'EXPONENTIAL_AT')) { 455 | v = obj[p]; 456 | if (v && v.pop) { 457 | intCheck(v[0], -MAX, 0, p); 458 | intCheck(v[1], 0, MAX, p); 459 | TO_EXP_NEG = v[0]; 460 | TO_EXP_POS = v[1]; 461 | } else { 462 | intCheck(v, -MAX, MAX, p); 463 | TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v); 464 | } 465 | } 466 | 467 | // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or 468 | // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive]. 469 | // '[BigNumber Error] RANGE {not a primitive number|not an integer|out of range|cannot be zero}: {v}' 470 | if (obj.hasOwnProperty(p = 'RANGE')) { 471 | v = obj[p]; 472 | if (v && v.pop) { 473 | intCheck(v[0], -MAX, -1, p); 474 | intCheck(v[1], 1, MAX, p); 475 | MIN_EXP = v[0]; 476 | MAX_EXP = v[1]; 477 | } else { 478 | intCheck(v, -MAX, MAX, p); 479 | if (v) { 480 | MIN_EXP = -(MAX_EXP = v < 0 ? -v : v); 481 | } else { 482 | throw Error 483 | (bignumberError + p + ' cannot be zero: ' + v); 484 | } 485 | } 486 | } 487 | 488 | // CRYPTO {boolean} true or false. 489 | // '[BigNumber Error] CRYPTO not true or false: {v}' 490 | // '[BigNumber Error] crypto unavailable' 491 | if (obj.hasOwnProperty(p = 'CRYPTO')) { 492 | v = obj[p]; 493 | if (v === !!v) { 494 | if (v) { 495 | if (typeof crypto != 'undefined' && crypto && 496 | (crypto.getRandomValues || crypto.randomBytes)) { 497 | CRYPTO = v; 498 | } else { 499 | CRYPTO = !v; 500 | throw Error 501 | (bignumberError + 'crypto unavailable'); 502 | } 503 | } else { 504 | CRYPTO = v; 505 | } 506 | } else { 507 | throw Error 508 | (bignumberError + p + ' not true or false: ' + v); 509 | } 510 | } 511 | 512 | // MODULO_MODE {number} Integer, 0 to 9 inclusive. 513 | // '[BigNumber Error] MODULO_MODE {not a primitive number|not an integer|out of range}: {v}' 514 | if (obj.hasOwnProperty(p = 'MODULO_MODE')) { 515 | v = obj[p]; 516 | intCheck(v, 0, 9, p); 517 | MODULO_MODE = v; 518 | } 519 | 520 | // POW_PRECISION {number} Integer, 0 to MAX inclusive. 521 | // '[BigNumber Error] POW_PRECISION {not a primitive number|not an integer|out of range}: {v}' 522 | if (obj.hasOwnProperty(p = 'POW_PRECISION')) { 523 | v = obj[p]; 524 | intCheck(v, 0, MAX, p); 525 | POW_PRECISION = v; 526 | } 527 | 528 | // FORMAT {object} 529 | // '[BigNumber Error] FORMAT not an object: {v}' 530 | if (obj.hasOwnProperty(p = 'FORMAT')) { 531 | v = obj[p]; 532 | if (typeof v == 'object') FORMAT = v; 533 | else throw Error 534 | (bignumberError + p + ' not an object: ' + v); 535 | } 536 | 537 | // ALPHABET {string} 538 | // '[BigNumber Error] ALPHABET invalid: {v}' 539 | if (obj.hasOwnProperty(p = 'ALPHABET')) { 540 | v = obj[p]; 541 | 542 | // Disallow if only one character, 543 | // or if it contains '+', '-', '.', whitespace, or a repeated character. 544 | if (typeof v == 'string' && !/^.$|[+-.\s]|(.).*\1/.test(v)) { 545 | ALPHABET = v; 546 | } else { 547 | throw Error 548 | (bignumberError + p + ' invalid: ' + v); 549 | } 550 | } 551 | 552 | } else { 553 | 554 | // '[BigNumber Error] Object expected: {v}' 555 | throw Error 556 | (bignumberError + 'Object expected: ' + obj); 557 | } 558 | } 559 | 560 | return { 561 | DECIMAL_PLACES: DECIMAL_PLACES, 562 | ROUNDING_MODE: ROUNDING_MODE, 563 | EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS], 564 | RANGE: [MIN_EXP, MAX_EXP], 565 | CRYPTO: CRYPTO, 566 | MODULO_MODE: MODULO_MODE, 567 | POW_PRECISION: POW_PRECISION, 568 | FORMAT: FORMAT, 569 | ALPHABET: ALPHABET 570 | }; 571 | }; 572 | 573 | 574 | /* 575 | * Return true if v is a BigNumber instance, otherwise return false. 576 | * 577 | * If BigNumber.DEBUG is true, throw if a BigNumber instance is not well-formed. 578 | * 579 | * v {any} 580 | * 581 | * '[BigNumber Error] Invalid BigNumber: {v}' 582 | */ 583 | BigNumber.isBigNumber = function (v) { 584 | if (!v || v._isBigNumber !== true) return false; 585 | if (!BigNumber.DEBUG) return true; 586 | 587 | var i, n, 588 | c = v.c, 589 | e = v.e, 590 | s = v.s; 591 | 592 | out: if ({}.toString.call(c) == '[object Array]') { 593 | 594 | if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) { 595 | 596 | // If the first element is zero, the BigNumber value must be zero. 597 | if (c[0] === 0) { 598 | if (e === 0 && c.length === 1) return true; 599 | break out; 600 | } 601 | 602 | // Calculate number of digits that c[0] should have, based on the exponent. 603 | i = (e + 1) % LOG_BASE; 604 | if (i < 1) i += LOG_BASE; 605 | 606 | // Calculate number of digits of c[0]. 607 | //if (Math.ceil(Math.log(c[0] + 1) / Math.LN10) == i) { 608 | if (String(c[0]).length == i) { 609 | 610 | for (i = 0; i < c.length; i++) { 611 | n = c[i]; 612 | if (n < 0 || n >= BASE || n !== mathfloor(n)) break out; 613 | } 614 | 615 | // Last element cannot be zero, unless it is the only element. 616 | if (n !== 0) return true; 617 | } 618 | } 619 | 620 | // Infinity/NaN 621 | } else if (c === null && e === null && (s === null || s === 1 || s === -1)) { 622 | return true; 623 | } 624 | 625 | throw Error 626 | (bignumberError + 'Invalid BigNumber: ' + v); 627 | }; 628 | 629 | 630 | /* 631 | * Return a new BigNumber whose value is the maximum of the arguments. 632 | * 633 | * arguments {number|string|BigNumber} 634 | */ 635 | BigNumber.maximum = BigNumber.max = function () { 636 | return maxOrMin(arguments, P.lt); 637 | }; 638 | 639 | 640 | /* 641 | * Return a new BigNumber whose value is the minimum of the arguments. 642 | * 643 | * arguments {number|string|BigNumber} 644 | */ 645 | BigNumber.minimum = BigNumber.min = function () { 646 | return maxOrMin(arguments, P.gt); 647 | }; 648 | 649 | 650 | /* 651 | * Return a new BigNumber with a random value equal to or greater than 0 and less than 1, 652 | * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing 653 | * zeros are produced). 654 | * 655 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. 656 | * 657 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp}' 658 | * '[BigNumber Error] crypto unavailable' 659 | */ 660 | BigNumber.random = (function () { 661 | var pow2_53 = 0x20000000000000; 662 | 663 | // Return a 53 bit integer n, where 0 <= n < 9007199254740992. 664 | // Check if Math.random() produces more than 32 bits of randomness. 665 | // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits. 666 | // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1. 667 | var random53bitInt = (Math.random() * pow2_53) & 0x1fffff 668 | ? function () { return mathfloor(Math.random() * pow2_53); } 669 | : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) + 670 | (Math.random() * 0x800000 | 0); }; 671 | 672 | return function (dp) { 673 | var a, b, e, k, v, 674 | i = 0, 675 | c = [], 676 | rand = new BigNumber(ONE); 677 | 678 | if (dp == null) dp = DECIMAL_PLACES; 679 | else intCheck(dp, 0, MAX); 680 | 681 | k = mathceil(dp / LOG_BASE); 682 | 683 | if (CRYPTO) { 684 | 685 | // Browsers supporting crypto.getRandomValues. 686 | if (crypto.getRandomValues) { 687 | 688 | a = crypto.getRandomValues(new Uint32Array(k *= 2)); 689 | 690 | for (; i < k;) { 691 | 692 | // 53 bits: 693 | // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2) 694 | // 11111 11111111 11111111 11111111 11100000 00000000 00000000 695 | // ((Math.pow(2, 32) - 1) >>> 11).toString(2) 696 | // 11111 11111111 11111111 697 | // 0x20000 is 2^21. 698 | v = a[i] * 0x20000 + (a[i + 1] >>> 11); 699 | 700 | // Rejection sampling: 701 | // 0 <= v < 9007199254740992 702 | // Probability that v >= 9e15, is 703 | // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251 704 | if (v >= 9e15) { 705 | b = crypto.getRandomValues(new Uint32Array(2)); 706 | a[i] = b[0]; 707 | a[i + 1] = b[1]; 708 | } else { 709 | 710 | // 0 <= v <= 8999999999999999 711 | // 0 <= (v % 1e14) <= 99999999999999 712 | c.push(v % 1e14); 713 | i += 2; 714 | } 715 | } 716 | i = k / 2; 717 | 718 | // Node.js supporting crypto.randomBytes. 719 | } else if (crypto.randomBytes) { 720 | 721 | // buffer 722 | a = crypto.randomBytes(k *= 7); 723 | 724 | for (; i < k;) { 725 | 726 | // 0x1000000000000 is 2^48, 0x10000000000 is 2^40 727 | // 0x100000000 is 2^32, 0x1000000 is 2^24 728 | // 11111 11111111 11111111 11111111 11111111 11111111 11111111 729 | // 0 <= v < 9007199254740992 730 | v = ((a[i] & 31) * 0x1000000000000) + (a[i + 1] * 0x10000000000) + 731 | (a[i + 2] * 0x100000000) + (a[i + 3] * 0x1000000) + 732 | (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6]; 733 | 734 | if (v >= 9e15) { 735 | crypto.randomBytes(7).copy(a, i); 736 | } else { 737 | 738 | // 0 <= (v % 1e14) <= 99999999999999 739 | c.push(v % 1e14); 740 | i += 7; 741 | } 742 | } 743 | i = k / 7; 744 | } else { 745 | CRYPTO = false; 746 | throw Error 747 | (bignumberError + 'crypto unavailable'); 748 | } 749 | } 750 | 751 | // Use Math.random. 752 | if (!CRYPTO) { 753 | 754 | for (; i < k;) { 755 | v = random53bitInt(); 756 | if (v < 9e15) c[i++] = v % 1e14; 757 | } 758 | } 759 | 760 | k = c[--i]; 761 | dp %= LOG_BASE; 762 | 763 | // Convert trailing digits to zeros according to dp. 764 | if (k && dp) { 765 | v = POWS_TEN[LOG_BASE - dp]; 766 | c[i] = mathfloor(k / v) * v; 767 | } 768 | 769 | // Remove trailing elements which are zero. 770 | for (; c[i] === 0; c.pop(), i--); 771 | 772 | // Zero? 773 | if (i < 0) { 774 | c = [e = 0]; 775 | } else { 776 | 777 | // Remove leading elements which are zero and adjust exponent accordingly. 778 | for (e = -1 ; c[0] === 0; c.splice(0, 1), e -= LOG_BASE); 779 | 780 | // Count the digits of the first element of c to determine leading zeros, and... 781 | for (i = 1, v = c[0]; v >= 10; v /= 10, i++); 782 | 783 | // adjust the exponent accordingly. 784 | if (i < LOG_BASE) e -= LOG_BASE - i; 785 | } 786 | 787 | rand.e = e; 788 | rand.c = c; 789 | return rand; 790 | }; 791 | })(); 792 | 793 | 794 | /* 795 | * Return a BigNumber whose value is the sum of the arguments. 796 | * 797 | * arguments {number|string|BigNumber} 798 | */ 799 | BigNumber.sum = function () { 800 | var i = 1, 801 | args = arguments, 802 | sum = new BigNumber(args[0]); 803 | for (; i < args.length;) sum = sum.plus(args[i++]); 804 | return sum; 805 | }; 806 | 807 | 808 | // PRIVATE FUNCTIONS 809 | 810 | 811 | // Called by BigNumber and BigNumber.prototype.toString. 812 | convertBase = (function () { 813 | var decimal = '0123456789'; 814 | 815 | /* 816 | * Convert string of baseIn to an array of numbers of baseOut. 817 | * Eg. toBaseOut('255', 10, 16) returns [15, 15]. 818 | * Eg. toBaseOut('ff', 16, 10) returns [2, 5, 5]. 819 | */ 820 | function toBaseOut(str, baseIn, baseOut, alphabet) { 821 | var j, 822 | arr = [0], 823 | arrL, 824 | i = 0, 825 | len = str.length; 826 | 827 | for (; i < len;) { 828 | for (arrL = arr.length; arrL--; arr[arrL] *= baseIn); 829 | 830 | arr[0] += alphabet.indexOf(str.charAt(i++)); 831 | 832 | for (j = 0; j < arr.length; j++) { 833 | 834 | if (arr[j] > baseOut - 1) { 835 | if (arr[j + 1] == null) arr[j + 1] = 0; 836 | arr[j + 1] += arr[j] / baseOut | 0; 837 | arr[j] %= baseOut; 838 | } 839 | } 840 | } 841 | 842 | return arr.reverse(); 843 | } 844 | 845 | // Convert a numeric string of baseIn to a numeric string of baseOut. 846 | // If the caller is toString, we are converting from base 10 to baseOut. 847 | // If the caller is BigNumber, we are converting from baseIn to base 10. 848 | return function (str, baseIn, baseOut, sign, callerIsToString) { 849 | var alphabet, d, e, k, r, x, xc, y, 850 | i = str.indexOf('.'), 851 | dp = DECIMAL_PLACES, 852 | rm = ROUNDING_MODE; 853 | 854 | // Non-integer. 855 | if (i >= 0) { 856 | k = POW_PRECISION; 857 | 858 | // Unlimited precision. 859 | POW_PRECISION = 0; 860 | str = str.replace('.', ''); 861 | y = new BigNumber(baseIn); 862 | x = y.pow(str.length - i); 863 | POW_PRECISION = k; 864 | 865 | // Convert str as if an integer, then restore the fraction part by dividing the 866 | // result by its base raised to a power. 867 | 868 | y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, '0'), 869 | 10, baseOut, decimal); 870 | y.e = y.c.length; 871 | } 872 | 873 | // Convert the number as integer. 874 | 875 | xc = toBaseOut(str, baseIn, baseOut, callerIsToString 876 | ? (alphabet = ALPHABET, decimal) 877 | : (alphabet = decimal, ALPHABET)); 878 | 879 | // xc now represents str as an integer and converted to baseOut. e is the exponent. 880 | e = k = xc.length; 881 | 882 | // Remove trailing zeros. 883 | for (; xc[--k] == 0; xc.pop()); 884 | 885 | // Zero? 886 | if (!xc[0]) return alphabet.charAt(0); 887 | 888 | // Does str represent an integer? If so, no need for the division. 889 | if (i < 0) { 890 | --e; 891 | } else { 892 | x.c = xc; 893 | x.e = e; 894 | 895 | // The sign is needed for correct rounding. 896 | x.s = sign; 897 | x = div(x, y, dp, rm, baseOut); 898 | xc = x.c; 899 | r = x.r; 900 | e = x.e; 901 | } 902 | 903 | // xc now represents str converted to baseOut. 904 | 905 | // THe index of the rounding digit. 906 | d = e + dp + 1; 907 | 908 | // The rounding digit: the digit to the right of the digit that may be rounded up. 909 | i = xc[d]; 910 | 911 | // Look at the rounding digits and mode to determine whether to round up. 912 | 913 | k = baseOut / 2; 914 | r = r || d < 0 || xc[d + 1] != null; 915 | 916 | r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) 917 | : i > k || i == k &&(rm == 4 || r || rm == 6 && xc[d - 1] & 1 || 918 | rm == (x.s < 0 ? 8 : 7)); 919 | 920 | // If the index of the rounding digit is not greater than zero, or xc represents 921 | // zero, then the result of the base conversion is zero or, if rounding up, a value 922 | // such as 0.00001. 923 | if (d < 1 || !xc[0]) { 924 | 925 | // 1^-dp or 0 926 | str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0); 927 | } else { 928 | 929 | // Truncate xc to the required number of decimal places. 930 | xc.length = d; 931 | 932 | // Round up? 933 | if (r) { 934 | 935 | // Rounding up may mean the previous digit has to be rounded up and so on. 936 | for (--baseOut; ++xc[--d] > baseOut;) { 937 | xc[d] = 0; 938 | 939 | if (!d) { 940 | ++e; 941 | xc = [1].concat(xc); 942 | } 943 | } 944 | } 945 | 946 | // Determine trailing zeros. 947 | for (k = xc.length; !xc[--k];); 948 | 949 | // E.g. [4, 11, 15] becomes 4bf. 950 | for (i = 0, str = ''; i <= k; str += alphabet.charAt(xc[i++])); 951 | 952 | // Add leading zeros, decimal point and trailing zeros as required. 953 | str = toFixedPoint(str, e, alphabet.charAt(0)); 954 | } 955 | 956 | // The caller will add the sign. 957 | return str; 958 | }; 959 | })(); 960 | 961 | 962 | // Perform division in the specified base. Called by div and convertBase. 963 | div = (function () { 964 | 965 | // Assume non-zero x and k. 966 | function multiply(x, k, base) { 967 | var m, temp, xlo, xhi, 968 | carry = 0, 969 | i = x.length, 970 | klo = k % SQRT_BASE, 971 | khi = k / SQRT_BASE | 0; 972 | 973 | for (x = x.slice(); i--;) { 974 | xlo = x[i] % SQRT_BASE; 975 | xhi = x[i] / SQRT_BASE | 0; 976 | m = khi * xlo + xhi * klo; 977 | temp = klo * xlo + ((m % SQRT_BASE) * SQRT_BASE) + carry; 978 | carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi; 979 | x[i] = temp % base; 980 | } 981 | 982 | if (carry) x = [carry].concat(x); 983 | 984 | return x; 985 | } 986 | 987 | function compare(a, b, aL, bL) { 988 | var i, cmp; 989 | 990 | if (aL != bL) { 991 | cmp = aL > bL ? 1 : -1; 992 | } else { 993 | 994 | for (i = cmp = 0; i < aL; i++) { 995 | 996 | if (a[i] != b[i]) { 997 | cmp = a[i] > b[i] ? 1 : -1; 998 | break; 999 | } 1000 | } 1001 | } 1002 | 1003 | return cmp; 1004 | } 1005 | 1006 | function subtract(a, b, aL, base) { 1007 | var i = 0; 1008 | 1009 | // Subtract b from a. 1010 | for (; aL--;) { 1011 | a[aL] -= i; 1012 | i = a[aL] < b[aL] ? 1 : 0; 1013 | a[aL] = i * base + a[aL] - b[aL]; 1014 | } 1015 | 1016 | // Remove leading zeros. 1017 | for (; !a[0] && a.length > 1; a.splice(0, 1)); 1018 | } 1019 | 1020 | // x: dividend, y: divisor. 1021 | return function (x, y, dp, rm, base) { 1022 | var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0, 1023 | yL, yz, 1024 | s = x.s == y.s ? 1 : -1, 1025 | xc = x.c, 1026 | yc = y.c; 1027 | 1028 | // Either NaN, Infinity or 0? 1029 | if (!xc || !xc[0] || !yc || !yc[0]) { 1030 | 1031 | return new BigNumber( 1032 | 1033 | // Return NaN if either NaN, or both Infinity or 0. 1034 | !x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN : 1035 | 1036 | // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0. 1037 | xc && xc[0] == 0 || !yc ? s * 0 : s / 0 1038 | ); 1039 | } 1040 | 1041 | q = new BigNumber(s); 1042 | qc = q.c = []; 1043 | e = x.e - y.e; 1044 | s = dp + e + 1; 1045 | 1046 | if (!base) { 1047 | base = BASE; 1048 | e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE); 1049 | s = s / LOG_BASE | 0; 1050 | } 1051 | 1052 | // Result exponent may be one less then the current value of e. 1053 | // The coefficients of the BigNumbers from convertBase may have trailing zeros. 1054 | for (i = 0; yc[i] == (xc[i] || 0); i++); 1055 | 1056 | if (yc[i] > (xc[i] || 0)) e--; 1057 | 1058 | if (s < 0) { 1059 | qc.push(1); 1060 | more = true; 1061 | } else { 1062 | xL = xc.length; 1063 | yL = yc.length; 1064 | i = 0; 1065 | s += 2; 1066 | 1067 | // Normalise xc and yc so highest order digit of yc is >= base / 2. 1068 | 1069 | n = mathfloor(base / (yc[0] + 1)); 1070 | 1071 | // Not necessary, but to handle odd bases where yc[0] == (base / 2) - 1. 1072 | // if (n > 1 || n++ == 1 && yc[0] < base / 2) { 1073 | if (n > 1) { 1074 | yc = multiply(yc, n, base); 1075 | xc = multiply(xc, n, base); 1076 | yL = yc.length; 1077 | xL = xc.length; 1078 | } 1079 | 1080 | xi = yL; 1081 | rem = xc.slice(0, yL); 1082 | remL = rem.length; 1083 | 1084 | // Add zeros to make remainder as long as divisor. 1085 | for (; remL < yL; rem[remL++] = 0); 1086 | yz = yc.slice(); 1087 | yz = [0].concat(yz); 1088 | yc0 = yc[0]; 1089 | if (yc[1] >= base / 2) yc0++; 1090 | // Not necessary, but to prevent trial digit n > base, when using base 3. 1091 | // else if (base == 3 && yc0 == 1) yc0 = 1 + 1e-15; 1092 | 1093 | do { 1094 | n = 0; 1095 | 1096 | // Compare divisor and remainder. 1097 | cmp = compare(yc, rem, yL, remL); 1098 | 1099 | // If divisor < remainder. 1100 | if (cmp < 0) { 1101 | 1102 | // Calculate trial digit, n. 1103 | 1104 | rem0 = rem[0]; 1105 | if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); 1106 | 1107 | // n is how many times the divisor goes into the current remainder. 1108 | n = mathfloor(rem0 / yc0); 1109 | 1110 | // Algorithm: 1111 | // product = divisor multiplied by trial digit (n). 1112 | // Compare product and remainder. 1113 | // If product is greater than remainder: 1114 | // Subtract divisor from product, decrement trial digit. 1115 | // Subtract product from remainder. 1116 | // If product was less than remainder at the last compare: 1117 | // Compare new remainder and divisor. 1118 | // If remainder is greater than divisor: 1119 | // Subtract divisor from remainder, increment trial digit. 1120 | 1121 | if (n > 1) { 1122 | 1123 | // n may be > base only when base is 3. 1124 | if (n >= base) n = base - 1; 1125 | 1126 | // product = divisor * trial digit. 1127 | prod = multiply(yc, n, base); 1128 | prodL = prod.length; 1129 | remL = rem.length; 1130 | 1131 | // Compare product and remainder. 1132 | // If product > remainder then trial digit n too high. 1133 | // n is 1 too high about 5% of the time, and is not known to have 1134 | // ever been more than 1 too high. 1135 | while (compare(prod, rem, prodL, remL) == 1) { 1136 | n--; 1137 | 1138 | // Subtract divisor from product. 1139 | subtract(prod, yL < prodL ? yz : yc, prodL, base); 1140 | prodL = prod.length; 1141 | cmp = 1; 1142 | } 1143 | } else { 1144 | 1145 | // n is 0 or 1, cmp is -1. 1146 | // If n is 0, there is no need to compare yc and rem again below, 1147 | // so change cmp to 1 to avoid it. 1148 | // If n is 1, leave cmp as -1, so yc and rem are compared again. 1149 | if (n == 0) { 1150 | 1151 | // divisor < remainder, so n must be at least 1. 1152 | cmp = n = 1; 1153 | } 1154 | 1155 | // product = divisor 1156 | prod = yc.slice(); 1157 | prodL = prod.length; 1158 | } 1159 | 1160 | if (prodL < remL) prod = [0].concat(prod); 1161 | 1162 | // Subtract product from remainder. 1163 | subtract(rem, prod, remL, base); 1164 | remL = rem.length; 1165 | 1166 | // If product was < remainder. 1167 | if (cmp == -1) { 1168 | 1169 | // Compare divisor and new remainder. 1170 | // If divisor < new remainder, subtract divisor from remainder. 1171 | // Trial digit n too low. 1172 | // n is 1 too low about 5% of the time, and very rarely 2 too low. 1173 | while (compare(yc, rem, yL, remL) < 1) { 1174 | n++; 1175 | 1176 | // Subtract divisor from remainder. 1177 | subtract(rem, yL < remL ? yz : yc, remL, base); 1178 | remL = rem.length; 1179 | } 1180 | } 1181 | } else if (cmp === 0) { 1182 | n++; 1183 | rem = [0]; 1184 | } // else cmp === 1 and n will be 0 1185 | 1186 | // Add the next digit, n, to the result array. 1187 | qc[i++] = n; 1188 | 1189 | // Update the remainder. 1190 | if (rem[0]) { 1191 | rem[remL++] = xc[xi] || 0; 1192 | } else { 1193 | rem = [xc[xi]]; 1194 | remL = 1; 1195 | } 1196 | } while ((xi++ < xL || rem[0] != null) && s--); 1197 | 1198 | more = rem[0] != null; 1199 | 1200 | // Leading zero? 1201 | if (!qc[0]) qc.splice(0, 1); 1202 | } 1203 | 1204 | if (base == BASE) { 1205 | 1206 | // To calculate q.e, first get the number of digits of qc[0]. 1207 | for (i = 1, s = qc[0]; s >= 10; s /= 10, i++); 1208 | 1209 | round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more); 1210 | 1211 | // Caller is convertBase. 1212 | } else { 1213 | q.e = e; 1214 | q.r = +more; 1215 | } 1216 | 1217 | return q; 1218 | }; 1219 | })(); 1220 | 1221 | 1222 | /* 1223 | * Return a string representing the value of BigNumber n in fixed-point or exponential 1224 | * notation rounded to the specified decimal places or significant digits. 1225 | * 1226 | * n: a BigNumber. 1227 | * i: the index of the last digit required (i.e. the digit that may be rounded up). 1228 | * rm: the rounding mode. 1229 | * id: 1 (toExponential) or 2 (toPrecision). 1230 | */ 1231 | function format(n, i, rm, id) { 1232 | var c0, e, ne, len, str; 1233 | 1234 | if (rm == null) rm = ROUNDING_MODE; 1235 | else intCheck(rm, 0, 8); 1236 | 1237 | if (!n.c) return n.toString(); 1238 | 1239 | c0 = n.c[0]; 1240 | ne = n.e; 1241 | 1242 | if (i == null) { 1243 | str = coeffToString(n.c); 1244 | str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS) 1245 | ? toExponential(str, ne) 1246 | : toFixedPoint(str, ne, '0'); 1247 | } else { 1248 | n = round(new BigNumber(n), i, rm); 1249 | 1250 | // n.e may have changed if the value was rounded up. 1251 | e = n.e; 1252 | 1253 | str = coeffToString(n.c); 1254 | len = str.length; 1255 | 1256 | // toPrecision returns exponential notation if the number of significant digits 1257 | // specified is less than the number of digits necessary to represent the integer 1258 | // part of the value in fixed-point notation. 1259 | 1260 | // Exponential notation. 1261 | if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) { 1262 | 1263 | // Append zeros? 1264 | for (; len < i; str += '0', len++); 1265 | str = toExponential(str, e); 1266 | 1267 | // Fixed-point notation. 1268 | } else { 1269 | i -= ne; 1270 | str = toFixedPoint(str, e, '0'); 1271 | 1272 | // Append zeros? 1273 | if (e + 1 > len) { 1274 | if (--i > 0) for (str += '.'; i--; str += '0'); 1275 | } else { 1276 | i += e - len; 1277 | if (i > 0) { 1278 | if (e + 1 == len) str += '.'; 1279 | for (; i--; str += '0'); 1280 | } 1281 | } 1282 | } 1283 | } 1284 | 1285 | return n.s < 0 && c0 ? '-' + str : str; 1286 | } 1287 | 1288 | 1289 | // Handle BigNumber.max and BigNumber.min. 1290 | function maxOrMin(args, method) { 1291 | var n, 1292 | i = 1, 1293 | m = new BigNumber(args[0]); 1294 | 1295 | for (; i < args.length; i++) { 1296 | n = new BigNumber(args[i]); 1297 | 1298 | // If any number is NaN, return NaN. 1299 | if (!n.s) { 1300 | m = n; 1301 | break; 1302 | } else if (method.call(m, n)) { 1303 | m = n; 1304 | } 1305 | } 1306 | 1307 | return m; 1308 | } 1309 | 1310 | 1311 | /* 1312 | * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP. 1313 | * Called by minus, plus and times. 1314 | */ 1315 | function normalise(n, c, e) { 1316 | var i = 1, 1317 | j = c.length; 1318 | 1319 | // Remove trailing zeros. 1320 | for (; !c[--j]; c.pop()); 1321 | 1322 | // Calculate the base 10 exponent. First get the number of digits of c[0]. 1323 | for (j = c[0]; j >= 10; j /= 10, i++); 1324 | 1325 | // Overflow? 1326 | if ((e = i + e * LOG_BASE - 1) > MAX_EXP) { 1327 | 1328 | // Infinity. 1329 | n.c = n.e = null; 1330 | 1331 | // Underflow? 1332 | } else if (e < MIN_EXP) { 1333 | 1334 | // Zero. 1335 | n.c = [n.e = 0]; 1336 | } else { 1337 | n.e = e; 1338 | n.c = c; 1339 | } 1340 | 1341 | return n; 1342 | } 1343 | 1344 | 1345 | // Handle values that fail the validity test in BigNumber. 1346 | parseNumeric = (function () { 1347 | var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, 1348 | dotAfter = /^([^.]+)\.$/, 1349 | dotBefore = /^\.([^.]+)$/, 1350 | isInfinityOrNaN = /^-?(Infinity|NaN)$/, 1351 | whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g; 1352 | 1353 | return function (x, str, isNum, b) { 1354 | var base, 1355 | s = isNum ? str : str.replace(whitespaceOrPlus, ''); 1356 | 1357 | // No exception on ±Infinity or NaN. 1358 | if (isInfinityOrNaN.test(s)) { 1359 | x.s = isNaN(s) ? null : s < 0 ? -1 : 1; 1360 | } else { 1361 | if (!isNum) { 1362 | 1363 | // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i 1364 | s = s.replace(basePrefix, function (m, p1, p2) { 1365 | base = (p2 = p2.toLowerCase()) == 'x' ? 16 : p2 == 'b' ? 2 : 8; 1366 | return !b || b == base ? p1 : m; 1367 | }); 1368 | 1369 | if (b) { 1370 | base = b; 1371 | 1372 | // E.g. '1.' to '1', '.1' to '0.1' 1373 | s = s.replace(dotAfter, '$1').replace(dotBefore, '0.$1'); 1374 | } 1375 | 1376 | if (str != s) return new BigNumber(s, base); 1377 | } 1378 | 1379 | // '[BigNumber Error] Not a number: {n}' 1380 | // '[BigNumber Error] Not a base {b} number: {n}' 1381 | if (BigNumber.DEBUG) { 1382 | throw Error 1383 | (bignumberError + 'Not a' + (b ? ' base ' + b : '') + ' number: ' + str); 1384 | } 1385 | 1386 | // NaN 1387 | x.s = null; 1388 | } 1389 | 1390 | x.c = x.e = null; 1391 | } 1392 | })(); 1393 | 1394 | 1395 | /* 1396 | * Round x to sd significant digits using rounding mode rm. Check for over/under-flow. 1397 | * If r is truthy, it is known that there are more digits after the rounding digit. 1398 | */ 1399 | function round(x, sd, rm, r) { 1400 | var d, i, j, k, n, ni, rd, 1401 | xc = x.c, 1402 | pows10 = POWS_TEN; 1403 | 1404 | // if x is not Infinity or NaN... 1405 | if (xc) { 1406 | 1407 | // rd is the rounding digit, i.e. the digit after the digit that may be rounded up. 1408 | // n is a base 1e14 number, the value of the element of array x.c containing rd. 1409 | // ni is the index of n within x.c. 1410 | // d is the number of digits of n. 1411 | // i is the index of rd within n including leading zeros. 1412 | // j is the actual index of rd within n (if < 0, rd is a leading zero). 1413 | out: { 1414 | 1415 | // Get the number of digits of the first element of xc. 1416 | for (d = 1, k = xc[0]; k >= 10; k /= 10, d++); 1417 | i = sd - d; 1418 | 1419 | // If the rounding digit is in the first element of xc... 1420 | if (i < 0) { 1421 | i += LOG_BASE; 1422 | j = sd; 1423 | n = xc[ni = 0]; 1424 | 1425 | // Get the rounding digit at index j of n. 1426 | rd = n / pows10[d - j - 1] % 10 | 0; 1427 | } else { 1428 | ni = mathceil((i + 1) / LOG_BASE); 1429 | 1430 | if (ni >= xc.length) { 1431 | 1432 | if (r) { 1433 | 1434 | // Needed by sqrt. 1435 | for (; xc.length <= ni; xc.push(0)); 1436 | n = rd = 0; 1437 | d = 1; 1438 | i %= LOG_BASE; 1439 | j = i - LOG_BASE + 1; 1440 | } else { 1441 | break out; 1442 | } 1443 | } else { 1444 | n = k = xc[ni]; 1445 | 1446 | // Get the number of digits of n. 1447 | for (d = 1; k >= 10; k /= 10, d++); 1448 | 1449 | // Get the index of rd within n. 1450 | i %= LOG_BASE; 1451 | 1452 | // Get the index of rd within n, adjusted for leading zeros. 1453 | // The number of leading zeros of n is given by LOG_BASE - d. 1454 | j = i - LOG_BASE + d; 1455 | 1456 | // Get the rounding digit at index j of n. 1457 | rd = j < 0 ? 0 : n / pows10[d - j - 1] % 10 | 0; 1458 | } 1459 | } 1460 | 1461 | r = r || sd < 0 || 1462 | 1463 | // Are there any non-zero digits after the rounding digit? 1464 | // The expression n % pows10[d - j - 1] returns all digits of n to the right 1465 | // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714. 1466 | xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]); 1467 | 1468 | r = rm < 4 1469 | ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) 1470 | : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 && 1471 | 1472 | // Check whether the digit to the left of the rounding digit is odd. 1473 | ((i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10) & 1 || 1474 | rm == (x.s < 0 ? 8 : 7)); 1475 | 1476 | if (sd < 1 || !xc[0]) { 1477 | xc.length = 0; 1478 | 1479 | if (r) { 1480 | 1481 | // Convert sd to decimal places. 1482 | sd -= x.e + 1; 1483 | 1484 | // 1, 0.1, 0.01, 0.001, 0.0001 etc. 1485 | xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE]; 1486 | x.e = -sd || 0; 1487 | } else { 1488 | 1489 | // Zero. 1490 | xc[0] = x.e = 0; 1491 | } 1492 | 1493 | return x; 1494 | } 1495 | 1496 | // Remove excess digits. 1497 | if (i == 0) { 1498 | xc.length = ni; 1499 | k = 1; 1500 | ni--; 1501 | } else { 1502 | xc.length = ni + 1; 1503 | k = pows10[LOG_BASE - i]; 1504 | 1505 | // E.g. 56700 becomes 56000 if 7 is the rounding digit. 1506 | // j > 0 means i > number of leading zeros of n. 1507 | xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0; 1508 | } 1509 | 1510 | // Round up? 1511 | if (r) { 1512 | 1513 | for (; ;) { 1514 | 1515 | // If the digit to be rounded up is in the first element of xc... 1516 | if (ni == 0) { 1517 | 1518 | // i will be the length of xc[0] before k is added. 1519 | for (i = 1, j = xc[0]; j >= 10; j /= 10, i++); 1520 | j = xc[0] += k; 1521 | for (k = 1; j >= 10; j /= 10, k++); 1522 | 1523 | // if i != k the length has increased. 1524 | if (i != k) { 1525 | x.e++; 1526 | if (xc[0] == BASE) xc[0] = 1; 1527 | } 1528 | 1529 | break; 1530 | } else { 1531 | xc[ni] += k; 1532 | if (xc[ni] != BASE) break; 1533 | xc[ni--] = 0; 1534 | k = 1; 1535 | } 1536 | } 1537 | } 1538 | 1539 | // Remove trailing zeros. 1540 | for (i = xc.length; xc[--i] === 0; xc.pop()); 1541 | } 1542 | 1543 | // Overflow? Infinity. 1544 | if (x.e > MAX_EXP) { 1545 | x.c = x.e = null; 1546 | 1547 | // Underflow? Zero. 1548 | } else if (x.e < MIN_EXP) { 1549 | x.c = [x.e = 0]; 1550 | } 1551 | } 1552 | 1553 | return x; 1554 | } 1555 | 1556 | 1557 | function valueOf(n) { 1558 | var str, 1559 | e = n.e; 1560 | 1561 | if (e === null) return n.toString(); 1562 | 1563 | str = coeffToString(n.c); 1564 | 1565 | str = e <= TO_EXP_NEG || e >= TO_EXP_POS 1566 | ? toExponential(str, e) 1567 | : toFixedPoint(str, e, '0'); 1568 | 1569 | return n.s < 0 ? '-' + str : str; 1570 | } 1571 | 1572 | 1573 | // PROTOTYPE/INSTANCE METHODS 1574 | 1575 | 1576 | /* 1577 | * Return a new BigNumber whose value is the absolute value of this BigNumber. 1578 | */ 1579 | P.absoluteValue = P.abs = function () { 1580 | var x = new BigNumber(this); 1581 | if (x.s < 0) x.s = 1; 1582 | return x; 1583 | }; 1584 | 1585 | 1586 | /* 1587 | * Return 1588 | * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b), 1589 | * -1 if the value of this BigNumber is less than the value of BigNumber(y, b), 1590 | * 0 if they have the same value, 1591 | * or null if the value of either is NaN. 1592 | */ 1593 | P.comparedTo = function (y, b) { 1594 | return compare(this, new BigNumber(y, b)); 1595 | }; 1596 | 1597 | 1598 | /* 1599 | * If dp is undefined or null or true or false, return the number of decimal places of the 1600 | * value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN. 1601 | * 1602 | * Otherwise, if dp is a number, return a new BigNumber whose value is the value of this 1603 | * BigNumber rounded to a maximum of dp decimal places using rounding mode rm, or 1604 | * ROUNDING_MODE if rm is omitted. 1605 | * 1606 | * [dp] {number} Decimal places: integer, 0 to MAX inclusive. 1607 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 1608 | * 1609 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' 1610 | */ 1611 | P.decimalPlaces = P.dp = function (dp, rm) { 1612 | var c, n, v, 1613 | x = this; 1614 | 1615 | if (dp != null) { 1616 | intCheck(dp, 0, MAX); 1617 | if (rm == null) rm = ROUNDING_MODE; 1618 | else intCheck(rm, 0, 8); 1619 | 1620 | return round(new BigNumber(x), dp + x.e + 1, rm); 1621 | } 1622 | 1623 | if (!(c = x.c)) return null; 1624 | n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE; 1625 | 1626 | // Subtract the number of trailing zeros of the last number. 1627 | if (v = c[v]) for (; v % 10 == 0; v /= 10, n--); 1628 | if (n < 0) n = 0; 1629 | 1630 | return n; 1631 | }; 1632 | 1633 | 1634 | /* 1635 | * n / 0 = I 1636 | * n / N = N 1637 | * n / I = 0 1638 | * 0 / n = 0 1639 | * 0 / 0 = N 1640 | * 0 / N = N 1641 | * 0 / I = 0 1642 | * N / n = N 1643 | * N / 0 = N 1644 | * N / N = N 1645 | * N / I = N 1646 | * I / n = I 1647 | * I / 0 = I 1648 | * I / N = N 1649 | * I / I = N 1650 | * 1651 | * Return a new BigNumber whose value is the value of this BigNumber divided by the value of 1652 | * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE. 1653 | */ 1654 | P.dividedBy = P.div = function (y, b) { 1655 | return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE); 1656 | }; 1657 | 1658 | 1659 | /* 1660 | * Return a new BigNumber whose value is the integer part of dividing the value of this 1661 | * BigNumber by the value of BigNumber(y, b). 1662 | */ 1663 | P.dividedToIntegerBy = P.idiv = function (y, b) { 1664 | return div(this, new BigNumber(y, b), 0, 1); 1665 | }; 1666 | 1667 | 1668 | /* 1669 | * Return a BigNumber whose value is the value of this BigNumber exponentiated by n. 1670 | * 1671 | * If m is present, return the result modulo m. 1672 | * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE. 1673 | * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using ROUNDING_MODE. 1674 | * 1675 | * The modular power operation works efficiently when x, n, and m are integers, otherwise it 1676 | * is equivalent to calculating x.exponentiatedBy(n).modulo(m) with a POW_PRECISION of 0. 1677 | * 1678 | * n {number|string|BigNumber} The exponent. An integer. 1679 | * [m] {number|string|BigNumber} The modulus. 1680 | * 1681 | * '[BigNumber Error] Exponent not an integer: {n}' 1682 | */ 1683 | P.exponentiatedBy = P.pow = function (n, m) { 1684 | var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y, 1685 | x = this; 1686 | 1687 | n = new BigNumber(n); 1688 | 1689 | // Allow NaN and ±Infinity, but not other non-integers. 1690 | if (n.c && !n.isInteger()) { 1691 | throw Error 1692 | (bignumberError + 'Exponent not an integer: ' + valueOf(n)); 1693 | } 1694 | 1695 | if (m != null) m = new BigNumber(m); 1696 | 1697 | // Exponent of MAX_SAFE_INTEGER is 15. 1698 | nIsBig = n.e > 14; 1699 | 1700 | // If x is NaN, ±Infinity, ±0 or ±1, or n is ±Infinity, NaN or ±0. 1701 | if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) { 1702 | 1703 | // The sign of the result of pow when x is negative depends on the evenness of n. 1704 | // If +n overflows to ±Infinity, the evenness of n would be not be known. 1705 | y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? 2 - isOdd(n) : +valueOf(n))); 1706 | return m ? y.mod(m) : y; 1707 | } 1708 | 1709 | nIsNeg = n.s < 0; 1710 | 1711 | if (m) { 1712 | 1713 | // x % m returns NaN if abs(m) is zero, or m is NaN. 1714 | if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN); 1715 | 1716 | isModExp = !nIsNeg && x.isInteger() && m.isInteger(); 1717 | 1718 | if (isModExp) x = x.mod(m); 1719 | 1720 | // Overflow to ±Infinity: >=2**1e10 or >=1.0000024**1e15. 1721 | // Underflow to ±0: <=0.79**1e10 or <=0.9999975**1e15. 1722 | } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0 1723 | // [1, 240000000] 1724 | ? x.c[0] > 1 || nIsBig && x.c[1] >= 24e7 1725 | // [80000000000000] [99999750000000] 1726 | : x.c[0] < 8e13 || nIsBig && x.c[0] <= 9999975e7))) { 1727 | 1728 | // If x is negative and n is odd, k = -0, else k = 0. 1729 | k = x.s < 0 && isOdd(n) ? -0 : 0; 1730 | 1731 | // If x >= 1, k = ±Infinity. 1732 | if (x.e > -1) k = 1 / k; 1733 | 1734 | // If n is negative return ±0, else return ±Infinity. 1735 | return new BigNumber(nIsNeg ? 1 / k : k); 1736 | 1737 | } else if (POW_PRECISION) { 1738 | 1739 | // Truncating each coefficient array to a length of k after each multiplication 1740 | // equates to truncating significant digits to POW_PRECISION + [28, 41], 1741 | // i.e. there will be a minimum of 28 guard digits retained. 1742 | k = mathceil(POW_PRECISION / LOG_BASE + 2); 1743 | } 1744 | 1745 | if (nIsBig) { 1746 | half = new BigNumber(0.5); 1747 | if (nIsNeg) n.s = 1; 1748 | nIsOdd = isOdd(n); 1749 | } else { 1750 | i = Math.abs(+valueOf(n)); 1751 | nIsOdd = i % 2; 1752 | } 1753 | 1754 | y = new BigNumber(ONE); 1755 | 1756 | // Performs 54 loop iterations for n of 9007199254740991. 1757 | for (; ;) { 1758 | 1759 | if (nIsOdd) { 1760 | y = y.times(x); 1761 | if (!y.c) break; 1762 | 1763 | if (k) { 1764 | if (y.c.length > k) y.c.length = k; 1765 | } else if (isModExp) { 1766 | y = y.mod(m); //y = y.minus(div(y, m, 0, MODULO_MODE).times(m)); 1767 | } 1768 | } 1769 | 1770 | if (i) { 1771 | i = mathfloor(i / 2); 1772 | if (i === 0) break; 1773 | nIsOdd = i % 2; 1774 | } else { 1775 | n = n.times(half); 1776 | round(n, n.e + 1, 1); 1777 | 1778 | if (n.e > 14) { 1779 | nIsOdd = isOdd(n); 1780 | } else { 1781 | i = +valueOf(n); 1782 | if (i === 0) break; 1783 | nIsOdd = i % 2; 1784 | } 1785 | } 1786 | 1787 | x = x.times(x); 1788 | 1789 | if (k) { 1790 | if (x.c && x.c.length > k) x.c.length = k; 1791 | } else if (isModExp) { 1792 | x = x.mod(m); //x = x.minus(div(x, m, 0, MODULO_MODE).times(m)); 1793 | } 1794 | } 1795 | 1796 | if (isModExp) return y; 1797 | if (nIsNeg) y = ONE.div(y); 1798 | 1799 | return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y; 1800 | }; 1801 | 1802 | 1803 | /* 1804 | * Return a new BigNumber whose value is the value of this BigNumber rounded to an integer 1805 | * using rounding mode rm, or ROUNDING_MODE if rm is omitted. 1806 | * 1807 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 1808 | * 1809 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {rm}' 1810 | */ 1811 | P.integerValue = function (rm) { 1812 | var n = new BigNumber(this); 1813 | if (rm == null) rm = ROUNDING_MODE; 1814 | else intCheck(rm, 0, 8); 1815 | return round(n, n.e + 1, rm); 1816 | }; 1817 | 1818 | 1819 | /* 1820 | * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b), 1821 | * otherwise return false. 1822 | */ 1823 | P.isEqualTo = P.eq = function (y, b) { 1824 | return compare(this, new BigNumber(y, b)) === 0; 1825 | }; 1826 | 1827 | 1828 | /* 1829 | * Return true if the value of this BigNumber is a finite number, otherwise return false. 1830 | */ 1831 | P.isFinite = function () { 1832 | return !!this.c; 1833 | }; 1834 | 1835 | 1836 | /* 1837 | * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b), 1838 | * otherwise return false. 1839 | */ 1840 | P.isGreaterThan = P.gt = function (y, b) { 1841 | return compare(this, new BigNumber(y, b)) > 0; 1842 | }; 1843 | 1844 | 1845 | /* 1846 | * Return true if the value of this BigNumber is greater than or equal to the value of 1847 | * BigNumber(y, b), otherwise return false. 1848 | */ 1849 | P.isGreaterThanOrEqualTo = P.gte = function (y, b) { 1850 | return (b = compare(this, new BigNumber(y, b))) === 1 || b === 0; 1851 | 1852 | }; 1853 | 1854 | 1855 | /* 1856 | * Return true if the value of this BigNumber is an integer, otherwise return false. 1857 | */ 1858 | P.isInteger = function () { 1859 | return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2; 1860 | }; 1861 | 1862 | 1863 | /* 1864 | * Return true if the value of this BigNumber is less than the value of BigNumber(y, b), 1865 | * otherwise return false. 1866 | */ 1867 | P.isLessThan = P.lt = function (y, b) { 1868 | return compare(this, new BigNumber(y, b)) < 0; 1869 | }; 1870 | 1871 | 1872 | /* 1873 | * Return true if the value of this BigNumber is less than or equal to the value of 1874 | * BigNumber(y, b), otherwise return false. 1875 | */ 1876 | P.isLessThanOrEqualTo = P.lte = function (y, b) { 1877 | return (b = compare(this, new BigNumber(y, b))) === -1 || b === 0; 1878 | }; 1879 | 1880 | 1881 | /* 1882 | * Return true if the value of this BigNumber is NaN, otherwise return false. 1883 | */ 1884 | P.isNaN = function () { 1885 | return !this.s; 1886 | }; 1887 | 1888 | 1889 | /* 1890 | * Return true if the value of this BigNumber is negative, otherwise return false. 1891 | */ 1892 | P.isNegative = function () { 1893 | return this.s < 0; 1894 | }; 1895 | 1896 | 1897 | /* 1898 | * Return true if the value of this BigNumber is positive, otherwise return false. 1899 | */ 1900 | P.isPositive = function () { 1901 | return this.s > 0; 1902 | }; 1903 | 1904 | 1905 | /* 1906 | * Return true if the value of this BigNumber is 0 or -0, otherwise return false. 1907 | */ 1908 | P.isZero = function () { 1909 | return !!this.c && this.c[0] == 0; 1910 | }; 1911 | 1912 | 1913 | /* 1914 | * n - 0 = n 1915 | * n - N = N 1916 | * n - I = -I 1917 | * 0 - n = -n 1918 | * 0 - 0 = 0 1919 | * 0 - N = N 1920 | * 0 - I = -I 1921 | * N - n = N 1922 | * N - 0 = N 1923 | * N - N = N 1924 | * N - I = N 1925 | * I - n = I 1926 | * I - 0 = I 1927 | * I - N = N 1928 | * I - I = N 1929 | * 1930 | * Return a new BigNumber whose value is the value of this BigNumber minus the value of 1931 | * BigNumber(y, b). 1932 | */ 1933 | P.minus = function (y, b) { 1934 | var i, j, t, xLTy, 1935 | x = this, 1936 | a = x.s; 1937 | 1938 | y = new BigNumber(y, b); 1939 | b = y.s; 1940 | 1941 | // Either NaN? 1942 | if (!a || !b) return new BigNumber(NaN); 1943 | 1944 | // Signs differ? 1945 | if (a != b) { 1946 | y.s = -b; 1947 | return x.plus(y); 1948 | } 1949 | 1950 | var xe = x.e / LOG_BASE, 1951 | ye = y.e / LOG_BASE, 1952 | xc = x.c, 1953 | yc = y.c; 1954 | 1955 | if (!xe || !ye) { 1956 | 1957 | // Either Infinity? 1958 | if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN); 1959 | 1960 | // Either zero? 1961 | if (!xc[0] || !yc[0]) { 1962 | 1963 | // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. 1964 | return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x : 1965 | 1966 | // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity 1967 | ROUNDING_MODE == 3 ? -0 : 0); 1968 | } 1969 | } 1970 | 1971 | xe = bitFloor(xe); 1972 | ye = bitFloor(ye); 1973 | xc = xc.slice(); 1974 | 1975 | // Determine which is the bigger number. 1976 | if (a = xe - ye) { 1977 | 1978 | if (xLTy = a < 0) { 1979 | a = -a; 1980 | t = xc; 1981 | } else { 1982 | ye = xe; 1983 | t = yc; 1984 | } 1985 | 1986 | t.reverse(); 1987 | 1988 | // Prepend zeros to equalise exponents. 1989 | for (b = a; b--; t.push(0)); 1990 | t.reverse(); 1991 | } else { 1992 | 1993 | // Exponents equal. Check digit by digit. 1994 | j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b; 1995 | 1996 | for (a = b = 0; b < j; b++) { 1997 | 1998 | if (xc[b] != yc[b]) { 1999 | xLTy = xc[b] < yc[b]; 2000 | break; 2001 | } 2002 | } 2003 | } 2004 | 2005 | // x < y? Point xc to the array of the bigger number. 2006 | if (xLTy) t = xc, xc = yc, yc = t, y.s = -y.s; 2007 | 2008 | b = (j = yc.length) - (i = xc.length); 2009 | 2010 | // Append zeros to xc if shorter. 2011 | // No need to add zeros to yc if shorter as subtract only needs to start at yc.length. 2012 | if (b > 0) for (; b--; xc[i++] = 0); 2013 | b = BASE - 1; 2014 | 2015 | // Subtract yc from xc. 2016 | for (; j > a;) { 2017 | 2018 | if (xc[--j] < yc[j]) { 2019 | for (i = j; i && !xc[--i]; xc[i] = b); 2020 | --xc[i]; 2021 | xc[j] += BASE; 2022 | } 2023 | 2024 | xc[j] -= yc[j]; 2025 | } 2026 | 2027 | // Remove leading zeros and adjust exponent accordingly. 2028 | for (; xc[0] == 0; xc.splice(0, 1), --ye); 2029 | 2030 | // Zero? 2031 | if (!xc[0]) { 2032 | 2033 | // Following IEEE 754 (2008) 6.3, 2034 | // n - n = +0 but n - n = -0 when rounding towards -Infinity. 2035 | y.s = ROUNDING_MODE == 3 ? -1 : 1; 2036 | y.c = [y.e = 0]; 2037 | return y; 2038 | } 2039 | 2040 | // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity 2041 | // for finite x and y. 2042 | return normalise(y, xc, ye); 2043 | }; 2044 | 2045 | 2046 | /* 2047 | * n % 0 = N 2048 | * n % N = N 2049 | * n % I = n 2050 | * 0 % n = 0 2051 | * -0 % n = -0 2052 | * 0 % 0 = N 2053 | * 0 % N = N 2054 | * 0 % I = 0 2055 | * N % n = N 2056 | * N % 0 = N 2057 | * N % N = N 2058 | * N % I = N 2059 | * I % n = N 2060 | * I % 0 = N 2061 | * I % N = N 2062 | * I % I = N 2063 | * 2064 | * Return a new BigNumber whose value is the value of this BigNumber modulo the value of 2065 | * BigNumber(y, b). The result depends on the value of MODULO_MODE. 2066 | */ 2067 | P.modulo = P.mod = function (y, b) { 2068 | var q, s, 2069 | x = this; 2070 | 2071 | y = new BigNumber(y, b); 2072 | 2073 | // Return NaN if x is Infinity or NaN, or y is NaN or zero. 2074 | if (!x.c || !y.s || y.c && !y.c[0]) { 2075 | return new BigNumber(NaN); 2076 | 2077 | // Return x if y is Infinity or x is zero. 2078 | } else if (!y.c || x.c && !x.c[0]) { 2079 | return new BigNumber(x); 2080 | } 2081 | 2082 | if (MODULO_MODE == 9) { 2083 | 2084 | // Euclidian division: q = sign(y) * floor(x / abs(y)) 2085 | // r = x - qy where 0 <= r < abs(y) 2086 | s = y.s; 2087 | y.s = 1; 2088 | q = div(x, y, 0, 3); 2089 | y.s = s; 2090 | q.s *= s; 2091 | } else { 2092 | q = div(x, y, 0, MODULO_MODE); 2093 | } 2094 | 2095 | y = x.minus(q.times(y)); 2096 | 2097 | // To match JavaScript %, ensure sign of zero is sign of dividend. 2098 | if (!y.c[0] && MODULO_MODE == 1) y.s = x.s; 2099 | 2100 | return y; 2101 | }; 2102 | 2103 | 2104 | /* 2105 | * n * 0 = 0 2106 | * n * N = N 2107 | * n * I = I 2108 | * 0 * n = 0 2109 | * 0 * 0 = 0 2110 | * 0 * N = N 2111 | * 0 * I = N 2112 | * N * n = N 2113 | * N * 0 = N 2114 | * N * N = N 2115 | * N * I = N 2116 | * I * n = I 2117 | * I * 0 = N 2118 | * I * N = N 2119 | * I * I = I 2120 | * 2121 | * Return a new BigNumber whose value is the value of this BigNumber multiplied by the value 2122 | * of BigNumber(y, b). 2123 | */ 2124 | P.multipliedBy = P.times = function (y, b) { 2125 | var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc, 2126 | base, sqrtBase, 2127 | x = this, 2128 | xc = x.c, 2129 | yc = (y = new BigNumber(y, b)).c; 2130 | 2131 | // Either NaN, ±Infinity or ±0? 2132 | if (!xc || !yc || !xc[0] || !yc[0]) { 2133 | 2134 | // Return NaN if either is NaN, or one is 0 and the other is Infinity. 2135 | if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) { 2136 | y.c = y.e = y.s = null; 2137 | } else { 2138 | y.s *= x.s; 2139 | 2140 | // Return ±Infinity if either is ±Infinity. 2141 | if (!xc || !yc) { 2142 | y.c = y.e = null; 2143 | 2144 | // Return ±0 if either is ±0. 2145 | } else { 2146 | y.c = [0]; 2147 | y.e = 0; 2148 | } 2149 | } 2150 | 2151 | return y; 2152 | } 2153 | 2154 | e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE); 2155 | y.s *= x.s; 2156 | xcL = xc.length; 2157 | ycL = yc.length; 2158 | 2159 | // Ensure xc points to longer array and xcL to its length. 2160 | if (xcL < ycL) zc = xc, xc = yc, yc = zc, i = xcL, xcL = ycL, ycL = i; 2161 | 2162 | // Initialise the result array with zeros. 2163 | for (i = xcL + ycL, zc = []; i--; zc.push(0)); 2164 | 2165 | base = BASE; 2166 | sqrtBase = SQRT_BASE; 2167 | 2168 | for (i = ycL; --i >= 0;) { 2169 | c = 0; 2170 | ylo = yc[i] % sqrtBase; 2171 | yhi = yc[i] / sqrtBase | 0; 2172 | 2173 | for (k = xcL, j = i + k; j > i;) { 2174 | xlo = xc[--k] % sqrtBase; 2175 | xhi = xc[k] / sqrtBase | 0; 2176 | m = yhi * xlo + xhi * ylo; 2177 | xlo = ylo * xlo + ((m % sqrtBase) * sqrtBase) + zc[j] + c; 2178 | c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi; 2179 | zc[j--] = xlo % base; 2180 | } 2181 | 2182 | zc[j] = c; 2183 | } 2184 | 2185 | if (c) { 2186 | ++e; 2187 | } else { 2188 | zc.splice(0, 1); 2189 | } 2190 | 2191 | return normalise(y, zc, e); 2192 | }; 2193 | 2194 | 2195 | /* 2196 | * Return a new BigNumber whose value is the value of this BigNumber negated, 2197 | * i.e. multiplied by -1. 2198 | */ 2199 | P.negated = function () { 2200 | var x = new BigNumber(this); 2201 | x.s = -x.s || null; 2202 | return x; 2203 | }; 2204 | 2205 | 2206 | /* 2207 | * n + 0 = n 2208 | * n + N = N 2209 | * n + I = I 2210 | * 0 + n = n 2211 | * 0 + 0 = 0 2212 | * 0 + N = N 2213 | * 0 + I = I 2214 | * N + n = N 2215 | * N + 0 = N 2216 | * N + N = N 2217 | * N + I = N 2218 | * I + n = I 2219 | * I + 0 = I 2220 | * I + N = N 2221 | * I + I = I 2222 | * 2223 | * Return a new BigNumber whose value is the value of this BigNumber plus the value of 2224 | * BigNumber(y, b). 2225 | */ 2226 | P.plus = function (y, b) { 2227 | var t, 2228 | x = this, 2229 | a = x.s; 2230 | 2231 | y = new BigNumber(y, b); 2232 | b = y.s; 2233 | 2234 | // Either NaN? 2235 | if (!a || !b) return new BigNumber(NaN); 2236 | 2237 | // Signs differ? 2238 | if (a != b) { 2239 | y.s = -b; 2240 | return x.minus(y); 2241 | } 2242 | 2243 | var xe = x.e / LOG_BASE, 2244 | ye = y.e / LOG_BASE, 2245 | xc = x.c, 2246 | yc = y.c; 2247 | 2248 | if (!xe || !ye) { 2249 | 2250 | // Return ±Infinity if either ±Infinity. 2251 | if (!xc || !yc) return new BigNumber(a / 0); 2252 | 2253 | // Either zero? 2254 | // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. 2255 | if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0); 2256 | } 2257 | 2258 | xe = bitFloor(xe); 2259 | ye = bitFloor(ye); 2260 | xc = xc.slice(); 2261 | 2262 | // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts. 2263 | if (a = xe - ye) { 2264 | if (a > 0) { 2265 | ye = xe; 2266 | t = yc; 2267 | } else { 2268 | a = -a; 2269 | t = xc; 2270 | } 2271 | 2272 | t.reverse(); 2273 | for (; a--; t.push(0)); 2274 | t.reverse(); 2275 | } 2276 | 2277 | a = xc.length; 2278 | b = yc.length; 2279 | 2280 | // Point xc to the longer array, and b to the shorter length. 2281 | if (a - b < 0) t = yc, yc = xc, xc = t, b = a; 2282 | 2283 | // Only start adding at yc.length - 1 as the further digits of xc can be ignored. 2284 | for (a = 0; b;) { 2285 | a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0; 2286 | xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE; 2287 | } 2288 | 2289 | if (a) { 2290 | xc = [a].concat(xc); 2291 | ++ye; 2292 | } 2293 | 2294 | // No need to check for zero, as +x + +y != 0 && -x + -y != 0 2295 | // ye = MAX_EXP + 1 possible 2296 | return normalise(y, xc, ye); 2297 | }; 2298 | 2299 | 2300 | /* 2301 | * If sd is undefined or null or true or false, return the number of significant digits of 2302 | * the value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN. 2303 | * If sd is true include integer-part trailing zeros in the count. 2304 | * 2305 | * Otherwise, if sd is a number, return a new BigNumber whose value is the value of this 2306 | * BigNumber rounded to a maximum of sd significant digits using rounding mode rm, or 2307 | * ROUNDING_MODE if rm is omitted. 2308 | * 2309 | * sd {number|boolean} number: significant digits: integer, 1 to MAX inclusive. 2310 | * boolean: whether to count integer-part trailing zeros: true or false. 2311 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 2312 | * 2313 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}' 2314 | */ 2315 | P.precision = P.sd = function (sd, rm) { 2316 | var c, n, v, 2317 | x = this; 2318 | 2319 | if (sd != null && sd !== !!sd) { 2320 | intCheck(sd, 1, MAX); 2321 | if (rm == null) rm = ROUNDING_MODE; 2322 | else intCheck(rm, 0, 8); 2323 | 2324 | return round(new BigNumber(x), sd, rm); 2325 | } 2326 | 2327 | if (!(c = x.c)) return null; 2328 | v = c.length - 1; 2329 | n = v * LOG_BASE + 1; 2330 | 2331 | if (v = c[v]) { 2332 | 2333 | // Subtract the number of trailing zeros of the last element. 2334 | for (; v % 10 == 0; v /= 10, n--); 2335 | 2336 | // Add the number of digits of the first element. 2337 | for (v = c[0]; v >= 10; v /= 10, n++); 2338 | } 2339 | 2340 | if (sd && x.e + 1 > n) n = x.e + 1; 2341 | 2342 | return n; 2343 | }; 2344 | 2345 | 2346 | /* 2347 | * Return a new BigNumber whose value is the value of this BigNumber shifted by k places 2348 | * (powers of 10). Shift to the right if n > 0, and to the left if n < 0. 2349 | * 2350 | * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive. 2351 | * 2352 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {k}' 2353 | */ 2354 | P.shiftedBy = function (k) { 2355 | intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); 2356 | return this.times('1e' + k); 2357 | }; 2358 | 2359 | 2360 | /* 2361 | * sqrt(-n) = N 2362 | * sqrt(N) = N 2363 | * sqrt(-I) = N 2364 | * sqrt(I) = I 2365 | * sqrt(0) = 0 2366 | * sqrt(-0) = -0 2367 | * 2368 | * Return a new BigNumber whose value is the square root of the value of this BigNumber, 2369 | * rounded according to DECIMAL_PLACES and ROUNDING_MODE. 2370 | */ 2371 | P.squareRoot = P.sqrt = function () { 2372 | var m, n, r, rep, t, 2373 | x = this, 2374 | c = x.c, 2375 | s = x.s, 2376 | e = x.e, 2377 | dp = DECIMAL_PLACES + 4, 2378 | half = new BigNumber('0.5'); 2379 | 2380 | // Negative/NaN/Infinity/zero? 2381 | if (s !== 1 || !c || !c[0]) { 2382 | return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0); 2383 | } 2384 | 2385 | // Initial estimate. 2386 | s = Math.sqrt(+valueOf(x)); 2387 | 2388 | // Math.sqrt underflow/overflow? 2389 | // Pass x to Math.sqrt as integer, then adjust the exponent of the result. 2390 | if (s == 0 || s == 1 / 0) { 2391 | n = coeffToString(c); 2392 | if ((n.length + e) % 2 == 0) n += '0'; 2393 | s = Math.sqrt(+n); 2394 | e = bitFloor((e + 1) / 2) - (e < 0 || e % 2); 2395 | 2396 | if (s == 1 / 0) { 2397 | n = '1e' + e; 2398 | } else { 2399 | n = s.toExponential(); 2400 | n = n.slice(0, n.indexOf('e') + 1) + e; 2401 | } 2402 | 2403 | r = new BigNumber(n); 2404 | } else { 2405 | r = new BigNumber(s + ''); 2406 | } 2407 | 2408 | // Check for zero. 2409 | // r could be zero if MIN_EXP is changed after the this value was created. 2410 | // This would cause a division by zero (x/t) and hence Infinity below, which would cause 2411 | // coeffToString to throw. 2412 | if (r.c[0]) { 2413 | e = r.e; 2414 | s = e + dp; 2415 | if (s < 3) s = 0; 2416 | 2417 | // Newton-Raphson iteration. 2418 | for (; ;) { 2419 | t = r; 2420 | r = half.times(t.plus(div(x, t, dp, 1))); 2421 | 2422 | if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) { 2423 | 2424 | // The exponent of r may here be one less than the final result exponent, 2425 | // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits 2426 | // are indexed correctly. 2427 | if (r.e < e) --s; 2428 | n = n.slice(s - 3, s + 1); 2429 | 2430 | // The 4th rounding digit may be in error by -1 so if the 4 rounding digits 2431 | // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the 2432 | // iteration. 2433 | if (n == '9999' || !rep && n == '4999') { 2434 | 2435 | // On the first iteration only, check to see if rounding up gives the 2436 | // exact result as the nines may infinitely repeat. 2437 | if (!rep) { 2438 | round(t, t.e + DECIMAL_PLACES + 2, 0); 2439 | 2440 | if (t.times(t).eq(x)) { 2441 | r = t; 2442 | break; 2443 | } 2444 | } 2445 | 2446 | dp += 4; 2447 | s += 4; 2448 | rep = 1; 2449 | } else { 2450 | 2451 | // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact 2452 | // result. If not, then there are further digits and m will be truthy. 2453 | if (!+n || !+n.slice(1) && n.charAt(0) == '5') { 2454 | 2455 | // Truncate to the first rounding digit. 2456 | round(r, r.e + DECIMAL_PLACES + 2, 1); 2457 | m = !r.times(r).eq(x); 2458 | } 2459 | 2460 | break; 2461 | } 2462 | } 2463 | } 2464 | } 2465 | 2466 | return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m); 2467 | }; 2468 | 2469 | 2470 | /* 2471 | * Return a string representing the value of this BigNumber in exponential notation and 2472 | * rounded using ROUNDING_MODE to dp fixed decimal places. 2473 | * 2474 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. 2475 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 2476 | * 2477 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' 2478 | */ 2479 | P.toExponential = function (dp, rm) { 2480 | if (dp != null) { 2481 | intCheck(dp, 0, MAX); 2482 | dp++; 2483 | } 2484 | return format(this, dp, rm, 1); 2485 | }; 2486 | 2487 | 2488 | /* 2489 | * Return a string representing the value of this BigNumber in fixed-point notation rounding 2490 | * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted. 2491 | * 2492 | * Note: as with JavaScript's number type, (-0).toFixed(0) is '0', 2493 | * but e.g. (-0.00001).toFixed(0) is '-0'. 2494 | * 2495 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. 2496 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 2497 | * 2498 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' 2499 | */ 2500 | P.toFixed = function (dp, rm) { 2501 | if (dp != null) { 2502 | intCheck(dp, 0, MAX); 2503 | dp = dp + this.e + 1; 2504 | } 2505 | return format(this, dp, rm); 2506 | }; 2507 | 2508 | 2509 | /* 2510 | * Return a string representing the value of this BigNumber in fixed-point notation rounded 2511 | * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties 2512 | * of the format or FORMAT object (see BigNumber.set). 2513 | * 2514 | * The formatting object may contain some or all of the properties shown below. 2515 | * 2516 | * FORMAT = { 2517 | * prefix: '', 2518 | * groupSize: 3, 2519 | * secondaryGroupSize: 0, 2520 | * groupSeparator: ',', 2521 | * decimalSeparator: '.', 2522 | * fractionGroupSize: 0, 2523 | * fractionGroupSeparator: '\xA0', // non-breaking space 2524 | * suffix: '' 2525 | * }; 2526 | * 2527 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. 2528 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 2529 | * [format] {object} Formatting options. See FORMAT pbject above. 2530 | * 2531 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' 2532 | * '[BigNumber Error] Argument not an object: {format}' 2533 | */ 2534 | P.toFormat = function (dp, rm, format) { 2535 | var str, 2536 | x = this; 2537 | 2538 | if (format == null) { 2539 | if (dp != null && rm && typeof rm == 'object') { 2540 | format = rm; 2541 | rm = null; 2542 | } else if (dp && typeof dp == 'object') { 2543 | format = dp; 2544 | dp = rm = null; 2545 | } else { 2546 | format = FORMAT; 2547 | } 2548 | } else if (typeof format != 'object') { 2549 | throw Error 2550 | (bignumberError + 'Argument not an object: ' + format); 2551 | } 2552 | 2553 | str = x.toFixed(dp, rm); 2554 | 2555 | if (x.c) { 2556 | var i, 2557 | arr = str.split('.'), 2558 | g1 = +format.groupSize, 2559 | g2 = +format.secondaryGroupSize, 2560 | groupSeparator = format.groupSeparator || '', 2561 | intPart = arr[0], 2562 | fractionPart = arr[1], 2563 | isNeg = x.s < 0, 2564 | intDigits = isNeg ? intPart.slice(1) : intPart, 2565 | len = intDigits.length; 2566 | 2567 | if (g2) i = g1, g1 = g2, g2 = i, len -= i; 2568 | 2569 | if (g1 > 0 && len > 0) { 2570 | i = len % g1 || g1; 2571 | intPart = intDigits.substr(0, i); 2572 | for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1); 2573 | if (g2 > 0) intPart += groupSeparator + intDigits.slice(i); 2574 | if (isNeg) intPart = '-' + intPart; 2575 | } 2576 | 2577 | str = fractionPart 2578 | ? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize) 2579 | ? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'), 2580 | '$&' + (format.fractionGroupSeparator || '')) 2581 | : fractionPart) 2582 | : intPart; 2583 | } 2584 | 2585 | return (format.prefix || '') + str + (format.suffix || ''); 2586 | }; 2587 | 2588 | 2589 | /* 2590 | * Return an array of two BigNumbers representing the value of this BigNumber as a simple 2591 | * fraction with an integer numerator and an integer denominator. 2592 | * The denominator will be a positive non-zero value less than or equal to the specified 2593 | * maximum denominator. If a maximum denominator is not specified, the denominator will be 2594 | * the lowest value necessary to represent the number exactly. 2595 | * 2596 | * [md] {number|string|BigNumber} Integer >= 1, or Infinity. The maximum denominator. 2597 | * 2598 | * '[BigNumber Error] Argument {not an integer|out of range} : {md}' 2599 | */ 2600 | P.toFraction = function (md) { 2601 | var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s, 2602 | x = this, 2603 | xc = x.c; 2604 | 2605 | if (md != null) { 2606 | n = new BigNumber(md); 2607 | 2608 | // Throw if md is less than one or is not an integer, unless it is Infinity. 2609 | if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) { 2610 | throw Error 2611 | (bignumberError + 'Argument ' + 2612 | (n.isInteger() ? 'out of range: ' : 'not an integer: ') + valueOf(n)); 2613 | } 2614 | } 2615 | 2616 | if (!xc) return new BigNumber(x); 2617 | 2618 | d = new BigNumber(ONE); 2619 | n1 = d0 = new BigNumber(ONE); 2620 | d1 = n0 = new BigNumber(ONE); 2621 | s = coeffToString(xc); 2622 | 2623 | // Determine initial denominator. 2624 | // d is a power of 10 and the minimum max denominator that specifies the value exactly. 2625 | e = d.e = s.length - x.e - 1; 2626 | d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp]; 2627 | md = !md || n.comparedTo(d) > 0 ? (e > 0 ? d : n1) : n; 2628 | 2629 | exp = MAX_EXP; 2630 | MAX_EXP = 1 / 0; 2631 | n = new BigNumber(s); 2632 | 2633 | // n0 = d1 = 0 2634 | n0.c[0] = 0; 2635 | 2636 | for (; ;) { 2637 | q = div(n, d, 0, 1); 2638 | d2 = d0.plus(q.times(d1)); 2639 | if (d2.comparedTo(md) == 1) break; 2640 | d0 = d1; 2641 | d1 = d2; 2642 | n1 = n0.plus(q.times(d2 = n1)); 2643 | n0 = d2; 2644 | d = n.minus(q.times(d2 = d)); 2645 | n = d2; 2646 | } 2647 | 2648 | d2 = div(md.minus(d0), d1, 0, 1); 2649 | n0 = n0.plus(d2.times(n1)); 2650 | d0 = d0.plus(d2.times(d1)); 2651 | n0.s = n1.s = x.s; 2652 | e = e * 2; 2653 | 2654 | // Determine which fraction is closer to x, n0/d0 or n1/d1 2655 | r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo( 2656 | div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [n1, d1] : [n0, d0]; 2657 | 2658 | MAX_EXP = exp; 2659 | 2660 | return r; 2661 | }; 2662 | 2663 | 2664 | /* 2665 | * Return the value of this BigNumber converted to a number primitive. 2666 | */ 2667 | P.toNumber = function () { 2668 | return +valueOf(this); 2669 | }; 2670 | 2671 | 2672 | /* 2673 | * Return a string representing the value of this BigNumber rounded to sd significant digits 2674 | * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits 2675 | * necessary to represent the integer part of the value in fixed-point notation, then use 2676 | * exponential notation. 2677 | * 2678 | * [sd] {number} Significant digits. Integer, 1 to MAX inclusive. 2679 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. 2680 | * 2681 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}' 2682 | */ 2683 | P.toPrecision = function (sd, rm) { 2684 | if (sd != null) intCheck(sd, 1, MAX); 2685 | return format(this, sd, rm, 2); 2686 | }; 2687 | 2688 | 2689 | /* 2690 | * Return a string representing the value of this BigNumber in base b, or base 10 if b is 2691 | * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and 2692 | * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent 2693 | * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than 2694 | * TO_EXP_NEG, return exponential notation. 2695 | * 2696 | * [b] {number} Integer, 2 to ALPHABET.length inclusive. 2697 | * 2698 | * '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}' 2699 | */ 2700 | P.toString = function (b) { 2701 | var str, 2702 | n = this, 2703 | s = n.s, 2704 | e = n.e; 2705 | 2706 | // Infinity or NaN? 2707 | if (e === null) { 2708 | if (s) { 2709 | str = 'Infinity'; 2710 | if (s < 0) str = '-' + str; 2711 | } else { 2712 | str = 'NaN'; 2713 | } 2714 | } else { 2715 | if (b == null) { 2716 | str = e <= TO_EXP_NEG || e >= TO_EXP_POS 2717 | ? toExponential(coeffToString(n.c), e) 2718 | : toFixedPoint(coeffToString(n.c), e, '0'); 2719 | } else if (b === 10) { 2720 | n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE); 2721 | str = toFixedPoint(coeffToString(n.c), n.e, '0'); 2722 | } else { 2723 | intCheck(b, 2, ALPHABET.length, 'Base'); 2724 | str = convertBase(toFixedPoint(coeffToString(n.c), e, '0'), 10, b, s, true); 2725 | } 2726 | 2727 | if (s < 0 && n.c[0]) str = '-' + str; 2728 | } 2729 | 2730 | return str; 2731 | }; 2732 | 2733 | 2734 | /* 2735 | * Return as toString, but do not accept a base argument, and include the minus sign for 2736 | * negative zero. 2737 | */ 2738 | P.valueOf = P.toJSON = function () { 2739 | return valueOf(this); 2740 | }; 2741 | 2742 | 2743 | P._isBigNumber = true; 2744 | 2745 | P[Symbol.toStringTag] = 'BigNumber'; 2746 | 2747 | // Node.js v10.12.0+ 2748 | P[Symbol.for('nodejs.util.inspect.custom')] = P.valueOf; 2749 | 2750 | if (configObject != null) BigNumber.set(configObject); 2751 | 2752 | return BigNumber; 2753 | } 2754 | 2755 | 2756 | // PRIVATE HELPER FUNCTIONS 2757 | 2758 | // These functions don't need access to variables, 2759 | // e.g. DECIMAL_PLACES, in the scope of the `clone` function above. 2760 | 2761 | 2762 | function bitFloor(n) { 2763 | var i = n | 0; 2764 | return n > 0 || n === i ? i : i - 1; 2765 | } 2766 | 2767 | 2768 | // Return a coefficient array as a string of base 10 digits. 2769 | function coeffToString(a) { 2770 | var s, z, 2771 | i = 1, 2772 | j = a.length, 2773 | r = a[0] + ''; 2774 | 2775 | for (; i < j;) { 2776 | s = a[i++] + ''; 2777 | z = LOG_BASE - s.length; 2778 | for (; z--; s = '0' + s); 2779 | r += s; 2780 | } 2781 | 2782 | // Determine trailing zeros. 2783 | for (j = r.length; r.charCodeAt(--j) === 48;); 2784 | 2785 | return r.slice(0, j + 1 || 1); 2786 | } 2787 | 2788 | 2789 | // Compare the value of BigNumbers x and y. 2790 | function compare(x, y) { 2791 | var a, b, 2792 | xc = x.c, 2793 | yc = y.c, 2794 | i = x.s, 2795 | j = y.s, 2796 | k = x.e, 2797 | l = y.e; 2798 | 2799 | // Either NaN? 2800 | if (!i || !j) return null; 2801 | 2802 | a = xc && !xc[0]; 2803 | b = yc && !yc[0]; 2804 | 2805 | // Either zero? 2806 | if (a || b) return a ? b ? 0 : -j : i; 2807 | 2808 | // Signs differ? 2809 | if (i != j) return i; 2810 | 2811 | a = i < 0; 2812 | b = k == l; 2813 | 2814 | // Either Infinity? 2815 | if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1; 2816 | 2817 | // Compare exponents. 2818 | if (!b) return k > l ^ a ? 1 : -1; 2819 | 2820 | j = (k = xc.length) < (l = yc.length) ? k : l; 2821 | 2822 | // Compare digit by digit. 2823 | for (i = 0; i < j; i++) if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1; 2824 | 2825 | // Compare lengths. 2826 | return k == l ? 0 : k > l ^ a ? 1 : -1; 2827 | } 2828 | 2829 | 2830 | /* 2831 | * Check that n is a primitive number, an integer, and in range, otherwise throw. 2832 | */ 2833 | function intCheck(n, min, max, name) { 2834 | if (n < min || n > max || n !== mathfloor(n)) { 2835 | throw Error 2836 | (bignumberError + (name || 'Argument') + (typeof n == 'number' 2837 | ? n < min || n > max ? ' out of range: ' : ' not an integer: ' 2838 | : ' not a primitive number: ') + String(n)); 2839 | } 2840 | } 2841 | 2842 | 2843 | // Assumes finite n. 2844 | function isOdd(n) { 2845 | var k = n.c.length - 1; 2846 | return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0; 2847 | } 2848 | 2849 | 2850 | function toExponential(str, e) { 2851 | return (str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str) + 2852 | (e < 0 ? 'e' : 'e+') + e; 2853 | } 2854 | 2855 | 2856 | function toFixedPoint(str, e, z) { 2857 | var len, zs; 2858 | 2859 | // Negative exponent? 2860 | if (e < 0) { 2861 | 2862 | // Prepend zeros. 2863 | for (zs = z + '.'; ++e; zs += z); 2864 | str = zs + str; 2865 | 2866 | // Positive exponent 2867 | } else { 2868 | len = str.length; 2869 | 2870 | // Append zeros. 2871 | if (++e > len) { 2872 | for (zs = z, e -= len; --e; zs += z); 2873 | str += zs; 2874 | } else if (e < len) { 2875 | str = str.slice(0, e) + '.' + str.slice(e); 2876 | } 2877 | } 2878 | 2879 | return str; 2880 | } 2881 | 2882 | 2883 | // EXPORT 2884 | 2885 | 2886 | export var BigNumber = clone(); 2887 | 2888 | export default BigNumber; 2889 | -------------------------------------------------------------------------------- /static/js/coinUnit.js: -------------------------------------------------------------------------------- 1 | import util from './util' 2 | 3 | class coin { 4 | constructor() { 5 | this.unit = "USD" 6 | this.webUnit = ["USD", "CNY", "KRW"] 7 | } 8 | 9 | setUnit(unit) { 10 | if (!this.webUnit.includes(unit)) { unit = "USD" } 11 | util.setCookie("coinUnit", unit, { 12 | expires: 30, 13 | path: '/' 14 | }); 15 | this.unit = unit; 16 | return this.unit; 17 | } 18 | 19 | getUnit() { 20 | let unit = util.getCookie("coinUnit"); 21 | if (!this.webUnit.includes(unit)) { unit = "USD" }; 22 | this.unit = unit; 23 | return this.unit 24 | } 25 | } 26 | 27 | 28 | export default new coin; -------------------------------------------------------------------------------- /static/js/common.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | export default new Vue() -------------------------------------------------------------------------------- /static/js/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: process.env.NODE_ENV === 'production' ? '/web' : '', 3 | harmony: { 4 | token: 'ONE', 5 | network: { 6 | blockchain: 'Harmony', 7 | chainId: '' 8 | }, 9 | nodes:[ 10 | { 11 | name:'Harmony', 12 | url:'https://api.s0.t.hmny.io/', 13 | chainId: 1 14 | }, 15 | { 16 | name:'Pangaea', 17 | url:'https://api.s0.pga.hmny.io/', 18 | chainId: 3 19 | }, 20 | { 21 | name:'Harmony Testnet', 22 | url:'https://api.s0.b.hmny.io/', 23 | chainId: 2 24 | }, 25 | { 26 | name:'Localhost', 27 | url:'http://127.0.0.1:9500', 28 | chainId: 2 29 | } 30 | ] 31 | }, 32 | domain: 'http://localhost/' 33 | } 34 | -------------------------------------------------------------------------------- /static/js/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import vueI18n from 'vue-i18n' 3 | import util from './util' 4 | Vue.use(vueI18n) 5 | 6 | /* 7 | 设置一下网站支持的语言种类 8 | */ 9 | var webLanguage = ['cn', 'en', 'ko']; 10 | 11 | /** 12 | * 获取浏览器语言类型 13 | */ 14 | var getNavLanguage = function() { 15 | var navLanguage = (navigator.browserLanguage || navigator.language).toLowerCase(); 16 | switch (navLanguage) { 17 | case 'zh-cn' || 'zh-tw' || 'zh-hk': 18 | navLanguage = 'cn'; 19 | break; 20 | case 'ko': 21 | navLanguage = 'ko' 22 | break; 23 | default: 24 | navLanguage = 'en'; 25 | } 26 | return navLanguage; 27 | } 28 | 29 | let i18n = new vueI18n({ 30 | locale: 'en', // 语言标识 31 | //this.$i18n.locale // 通过切换locale的值来实现语言切换 32 | messages: { 33 | 'cn': require('static/lang/cn'), 34 | 'en': require('static/lang/en'), 35 | 'ko': require('static/lang/ko') 36 | } 37 | }) 38 | 39 | function isJSON(str) { 40 | if (typeof str == 'string') { 41 | try { 42 | var obj = JSON.parse(str); 43 | if (typeof obj == 'object' && obj) { 44 | return true; 45 | } else { 46 | return false; 47 | } 48 | } catch (e) { 49 | return false; 50 | } 51 | } 52 | console.log('It is not a string!') 53 | } 54 | 55 | i18n.setUserLanguage = function(lang) { 56 | if (isJSON(lang)) { 57 | lang = JSON.parse(lang).language; 58 | } 59 | if (!webLanguage.includes(lang)) { 60 | lang = 'en' 61 | } 62 | util.setCookie("userLanguage", lang, { 63 | expires: 30, 64 | path: '/' 65 | }); 66 | i18n.locale = lang; 67 | } 68 | 69 | var cookieLang = util.getCookie('userLanguage') ? util.getCookie('userLanguage') : getNavLanguage(); 70 | i18n.setUserLanguage(cookieLang); 71 | 72 | export default i18n -------------------------------------------------------------------------------- /static/js/util.js: -------------------------------------------------------------------------------- 1 | class Util { 2 | async initMathExtension() { 3 | var tries = 10; 4 | for (var i = 0; i < tries; i++) { 5 | var loaded = await new Promise((resolve, reject) => { 6 | setTimeout(function() { 7 | resolve(typeof window.mathExtension != 'undefined'); 8 | }, 100); 9 | }); 10 | if (loaded) return window.mathExtension; 11 | } 12 | return false; 13 | } 14 | // 时间戳转换日期 (秒) 15 | timestampToDate(timestamp) { 16 | var date = new Date(timestamp); //时间戳为10位需*1000 17 | var Y = date.getFullYear() + '-'; 18 | var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; 19 | var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '; 20 | var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'; 21 | var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'; 22 | var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(); 23 | return Y + M + D + h + m + s; 24 | } 25 | 26 | stringToCapitalize(str) { 27 | var arr = str.toLowerCase().split('_'); 28 | arr = arr.map(function(val) { 29 | if (val == 'new') { 30 | val = 'place' 31 | } 32 | val = val.slice(0, 1).toUpperCase() + val.slice(1); 33 | return val 34 | }) 35 | return arr.join(' ') 36 | } 37 | 38 | /** 39 | * cookie操作 40 | */ 41 | setCookie(name, value, options) { 42 | options = options || {}; 43 | if (value === null) { 44 | value = ''; 45 | options.expires = -1; 46 | } 47 | var expires = ''; 48 | if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { 49 | var date; 50 | if (typeof options.expires == 'number') { 51 | date = new Date(); 52 | date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); 53 | } else { 54 | date = options.expires; 55 | } 56 | expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE 57 | } 58 | var path = options.path ? '; path=' + options.path : ''; 59 | var domain = options.domain ? '; domain=' + options.domain : ''; 60 | var s = [cookie, expires, path, domain, secure].join(''); 61 | var secure = options.secure ? '; secure' : ''; 62 | var c = [name, '=', encodeURIComponent(value)].join(''); 63 | var cookie = [c, expires, path, domain, secure].join('') 64 | document.cookie = cookie; 65 | } 66 | 67 | getCookie(name) { 68 | var cookieValue = null; 69 | if (document.cookie && document.cookie != '') { 70 | var cookies = document.cookie.split(';'); 71 | for (var i = 0; i < cookies.length; i++) { 72 | var cookie = cookies[i].trim(); 73 | // Does this cookie string begin with the name we want? 74 | if (cookie.substring(0, name.length + 1) == (name + '=')) { 75 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 76 | break; 77 | } 78 | } 79 | } 80 | return cookieValue; 81 | } 82 | 83 | // 数字千分位,保留n位小数格式化 84 | addCommas(nStr, n = 2) { 85 | if (typeof(nStr) == 'string') { 86 | nStr = parseFloat(nStr); 87 | } 88 | if (typeof(nStr) == 'number') { 89 | nStr = nStr.toFixed(n); 90 | } 91 | nStr += ''; 92 | let x = nStr.split('.'); 93 | let x1 = x[0]; 94 | let x2 = x.length > 1 ? '.' + x[1] : ''; 95 | let rgx = /(\d+)(\d{3})/; 96 | while (rgx.test(x1)) { 97 | x1 = x1.replace(rgx, '$1' + ',' + '$2'); 98 | } 99 | return x1 + x2; 100 | } 101 | 102 | getFullNum(num) { 103 | //处理非数字 104 | if (isNaN(num)) { return num }; 105 | 106 | //处理不需要转换的数字 107 | var str = '' + num; 108 | if (!/e/i.test(str)) { return num; }; 109 | 110 | return (num).toFixed(18).replace(/\.?0+$/, ""); 111 | } 112 | 113 | // 拉取代币价格 114 | async getTokenPrice(nodeUrl, alias, type){ 115 | 116 | let response = {}; 117 | let url = nodeUrl +'api/tokenListPub?type='+type; 118 | $.ajax({ 119 | url : url, 120 | type : "get", 121 | data : {}, 122 | async : false, 123 | success : function(res) { 124 | let result = JSON.parse(res); 125 | response = result.data; 126 | } 127 | }); 128 | return Util.findToken(response, alias); 129 | } 130 | //查找 token返回 131 | static findToken(tokens, alias){ 132 | for (let i=0; i{ 154 | if (coin.alias == 'CNY'){ 155 | coins.cny = coin.rmb; 156 | } 157 | if (coin.alias == 'USD'){ 158 | coins.usd = coin.rmb; 159 | } 160 | if (coin.alias == 'KRW'){ 161 | coins.krw = coin.rmb; 162 | } 163 | }); 164 | } 165 | } 166 | }); 167 | return coins; 168 | } 169 | 170 | setSession(key, value){ 171 | value = JSON.stringify(value); 172 | sessionStorage.setItem(key, value); 173 | } 174 | 175 | getSession(key){ 176 | if (key == "") return ""; 177 | let value = sessionStorage.getItem(key); 178 | if (value == ""){ 179 | return ""; 180 | } 181 | return value; 182 | } 183 | 184 | delSession(key){ 185 | if (key){ 186 | sessionStorage.removeItem(key); 187 | } 188 | } 189 | } 190 | 191 | let util = new Util; 192 | 193 | export default util; 194 | -------------------------------------------------------------------------------- /static/lang/cn.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | lang: '中文', 3 | webwallet_mobile_app: 'APP', 4 | webwallet_your: '你的', 5 | webwallet_wallet: '钱包', 6 | webwallet_home_des1: '直接从区块链钱包发送,请求和交换', 7 | webwallet_home_des2: '', 8 | webwallet_login: '通过 Math Wallet 浏览器扩展程序登录', 9 | webwallet_copy_address: '复制地址', 10 | webwallet_qr_code: '二维码', 11 | webwallet_estimated_value: '估值', 12 | webwallet_total: '总计', 13 | webwallet_refresh: '刷新', 14 | webwallet_logout: '退出', 15 | webwallet_transactions: '交易记录', 16 | webwallet_erc20_transactions: 'Erc20代币交易', 17 | webwallet_to_address: '接收地址', 18 | webwallet_to_address_pl: '请填写钱包地址', 19 | webwallet_cheap: '慢', 20 | webwallet_fast: '快', 21 | webwallet_simple: '简单设置', 22 | webwallet_advanced: '高级设置', 23 | webwallet_memo_pl: '最多30个字符(可选)', 24 | webwallet_fee: '手续费', 25 | webwallet_txHash: '交易单号', 26 | webwallet_type: '类型', 27 | webwallet_value: '数量', 28 | webwallet_status: '交易状态', 29 | webwallet_block_height: '区块高度', 30 | webwallet_tx_time: '交易时间', 31 | webwallet_refresh_balance: '刷新余额', 32 | transaction_information: '交易详情', 33 | available: '可用', 34 | delegate: '已委托', 35 | undelegate: '解委托', 36 | transfer: '转账', 37 | transfer_amount: '转账金额', 38 | memo: '备注', 39 | noTransaction: '暂无任何交易记录', 40 | noMathExtension: '请先连接麦子钱包扩展程序', 41 | from: '发送方', 42 | to: '接收方', 43 | transfer_account_null: '请填写收款地址', 44 | transfer_amount_null: '请填写转账金额', 45 | copy_success: '复制成功', 46 | copy_fail: '请手动复制', 47 | transfer_success: '转账成功', 48 | transfer_fail: '转账失败', 49 | transfer_amount_min: '转账金额不能低于 ', 50 | back_transactions: '返回交易记录', 51 | gas_limit: 'Gas Limit', 52 | gas_used: 'Gas Used', 53 | gas_price: 'Gas Price', 54 | mathExtensionLock: '请解锁您的麦子钱包', 55 | contract: '合约', 56 | TRC20_transfer: 'TRC20 转账', 57 | check_account: '插件选择的账户和当前账户不一致', 58 | gas_price_min: 'Gas Price不能低于1Gwei', 59 | gas_limit_min: 'Gas Limit不能低于', 60 | prompt: '提示', 61 | input_data: '输入数据', 62 | transfer_input: '请输入十六进制数据(可选)', 63 | locked: '锁定', 64 | submit_success: '提交成功', 65 | gas_limit_null: 'Gas Limit不能为空', 66 | gas_Price_null: 'Gas Price不能为空', 67 | webwallet_harmony_amount_notenough: '可用余额不足', 68 | node_not_available: '当前节点不可用', 69 | webwallet_extrinsicID: '交易ID', 70 | webwallet_module: '模块', 71 | webwallet_signature: '签名', 72 | webwallet_address: '地址', 73 | webwallet_transfers: '转账记录', 74 | noTransfer: '暂无任何转账记录', 75 | Confirm: '确认' 76 | } 77 | -------------------------------------------------------------------------------- /static/lang/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | lang: 'English', 3 | webwallet_mobile_app: 'APP', 4 | webwallet_your: 'Your', 5 | webwallet_wallet: 'Wallet', 6 | webwallet_home_des1: 'Send, Request and Swap', 7 | webwallet_home_des2: 'directly from your Blockchain Wallet.', 8 | webwallet_login: 'Login via Math Wallet Browser Extension', 9 | webwallet_copy_address: 'Copy Address', 10 | webwallet_qr_code: 'QR Code', 11 | webwallet_estimated_value: 'Estimated Value', 12 | webwallet_total: 'Total', 13 | webwallet_refresh: 'Refresh', 14 | webwallet_logout: 'Logout', 15 | webwallet_transactions: 'Transactions', 16 | webwallet_erc20_transactions: 'Erc20 Token Txns', 17 | webwallet_to_address: 'To Address', 18 | webwallet_to_address_pl: 'Recipient Address', 19 | webwallet_cheap: 'Cheap', 20 | webwallet_fast: 'Fast', 21 | webwallet_simple: 'Simple', 22 | webwallet_advanced: 'Advanced', 23 | webwallet_memo_pl: 'Maximum 30 characters (optional)', 24 | webwallet_fee: 'Fee', 25 | webwallet_txHash: 'TxHash', 26 | webwallet_type: 'Type', 27 | webwallet_value: 'Value', 28 | webwallet_status: 'Status', 29 | webwallet_block_height: 'Block Height', 30 | webwallet_tx_time: 'Tx Time', 31 | webwallet_refresh_balance: 'Refresh Balance', 32 | transaction_information: 'Transaction Information', 33 | available: 'Available', 34 | delegate: 'Delegated', 35 | undelegate: 'Undelegating', 36 | transfer: 'Transfer', 37 | transfer_amount: 'Transfer Amount', 38 | memo: 'Memo', 39 | noTransaction: 'No transaction', 40 | noMathExtension: 'Please connect Math Wallet first', 41 | from: 'From', 42 | to: 'To', 43 | transfer_account_null: 'Please enter receive address', 44 | transfer_amount_null: 'Please set transfer amount', 45 | copy_success: 'Copied', 46 | copy_fail: 'Please copy manually', 47 | transfer_success: 'Transferred', 48 | transfer_fail: 'Transfer failed', 49 | transfer_amount_min: 'The transfer amount cannot be lower than ', 50 | back_transactions: 'Back to Transaction Record', 51 | gas_limit: 'Gas Limit', 52 | gas_used: 'Gas Used', 53 | gas_price: 'Gas Price', 54 | mathExtensionLock: 'Please unlock your Math Wallet', 55 | contract: 'Contract', 56 | TRC20_transfer: 'TRC20 Transfers', 57 | check_account: 'The current account is not the account selected by extension', 58 | gas_price_min: 'Gas Price cannot be lower than 1Gwei', 59 | gas_limit_min: 'Gas Limit cannot be lower than ', 60 | prompt: 'Prompt', 61 | input_data: 'Input Data', 62 | transfer_input: 'Please enter hexadecimal data (optional)', 63 | locked: 'Locked', 64 | submit_success: 'Submit success', 65 | gas_limit_null: 'Gas Limit is null', 66 | gas_Price_null: 'Gas Price is null', 67 | webwallet_harmony_amount_notenough: 'Have no enough available balance', 68 | node_not_available: 'Current node is not available', 69 | webwallet_extrinsicID: 'Extrinsic ID', 70 | webwallet_module: 'Module', 71 | webwallet_signature: 'Signature', 72 | webwallet_address: 'Address', 73 | webwallet_transfers: 'Transfers', 74 | noTransfer: 'No transfer', 75 | Confirm: 'Confirm' 76 | } 77 | -------------------------------------------------------------------------------- /static/lang/ko.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | lang: '한국어', 3 | webwallet_mobile_app: 'APP', 4 | webwallet_your: '당신의', 5 | webwallet_wallet: '지갑', 6 | webwallet_home_des1: '블록체인 지갑에서 직접 발송, 요청 및 교환', 7 | webwallet_home_des2: '', 8 | webwallet_login: 'Math Wallet 브라우저를 통해 로그인', 9 | webwallet_copy_address: '주소 복사', 10 | webwallet_qr_code: 'QR코드', 11 | webwallet_estimated_value: 'Estimated Value', 12 | webwallet_total: 'Total', 13 | webwallet_refresh: 'Refresh', 14 | webwallet_logout: 'Logout', 15 | webwallet_transactions: '거래 기록', 16 | webwallet_erc20_transactions: 'Erc20 토큰 거래', 17 | webwallet_to_address: '접수 주소', 18 | webwallet_to_address_pl: '지갑 주소 입력', 19 | webwallet_cheap: 'Cheap', 20 | webwallet_fast: 'Fast', 21 | webwallet_simple: '기분 설치', 22 | webwallet_advanced: '고급 설치', 23 | webwallet_memo_pl: '최대한 30개자(필수 아님)', 24 | webwallet_fee: '수수료', 25 | webwallet_txHash: '거래 번호', 26 | webwallet_type: '종류', 27 | webwallet_value: '수량', 28 | webwallet_status: '거래 상태', 29 | webwallet_block_height: 'Block Height', 30 | webwallet_tx_time: '거래 시간', 31 | webwallet_refresh_balance: '잔액을 새로 고침 하다', 32 | transaction_information: '거래 내역', 33 | available: 'Available', 34 | delegate: 'Delegated', 35 | undelegate: 'Undelegating', 36 | transfer: '이체', 37 | transfer_amount: '이체 금액', 38 | memo: '비고', 39 | noTransaction: '거래 기록이 없습니다', 40 | noMathExtension: 'Math Wallet 브라우저를 접속하세요', 41 | from: '발송자', 42 | to: '접수자', 43 | transfer_account_null: '입금 주소를 입력하세요', 44 | transfer_amount_null: '금액을 입력하세요', 45 | copy_success: '복사 완료', 46 | copy_fail: '복사하세요', 47 | transfer_success: '이체 완료', 48 | transfer_fail: '이체 실패', 49 | transfer_amount_min: '이체 금액이 최소한 ', 50 | back_transactions: '거래 기록으로 돌아가기', 51 | gas_limit: 'Gas Limit', 52 | gas_used: 'Gas Used', 53 | gas_price: 'Gas Price', 54 | contract: '컨트랙트', 55 | mathExtensionLock: 'Math Wallet unlock', 56 | TRC20_transfer: 'TRC20 이체', 57 | check_account: '선택된 계정과 현재 계정이 일치하지 않음', 58 | gas_price_min: 'Gas Price 최소한 1Gwei', 59 | gas_limit_min: 'Gas Limit 최소한', 60 | prompt: 'Prompt', 61 | input_data: '데이터 입력', 62 | transfer_input: '16진수 데이터 입력(필수 아님)', 63 | locked: 'Locked', 64 | submit_success: '제출 완료', 65 | gas_limit_null: 'Gas Limit is null', 66 | gas_Price_null: 'Gas Price is null', 67 | webwallet_harmony_amount_notenough: ' 잔액이 부족합니다', 68 | node_not_available: '유효하지 않은 노드', 69 | webwallet_extrinsicID: '거래ID', 70 | webwallet_module: '모듈', 71 | webwallet_signature: '사인', 72 | webwallet_address: '주소', 73 | webwallet_transfers: '이체 기록', 74 | noTransfer: '이체 기록이 없습니다', 75 | Confirm: 'Confirm' 76 | } 77 | --------------------------------------------------------------------------------