diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..a6d1da957 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +db-internal.js +gulpfile.js +*.min.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..c3a515b80 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,164 @@ +module.exports = { + "env": { + "browser": true, + "es6": true + }, + "extends": "airbnb-base", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "array-bracket-spacing": 2, + "block-scoped-var": 2, + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "comma-spacing": [2, { "before": false, "after": true }], + "comma-style": [2, "last"], + "complexity": 0, + "consistent-return": 1, + "consistent-this": 0, + "curly": [2, "multi-line"], + "default-case": 0, + "dot-location": [2, "property"], + "dot-notation": 0, + "eol-last": 2, + "eqeqeq": [2, "allow-null"], + "func-names": 0, + "func-style": 0, + "generator-star-spacing": [2, "both"], + "guard-for-in": 0, + "handle-callback-err": [2, "^(err|error|anySpecificError)$" ], + "indent": [2, 2, { "SwitchCase": 1 }], + "key-spacing": [2, { "beforeColon": false, "afterColon": true }], + "linebreak-style": 0, + "max-depth": 0, + "max-len": [2, 1550, 4], + "max-nested-callbacks": 0, + "max-params": 0, + "max-statements": 0, + "new-cap": [2, { "newIsCap": true, "capIsNew": false }], + "newline-after-var": [0, "never"], + "new-parens": 2, + "no-alert": 0, + "no-array-constructor": 2, + "no-bitwise": 0, + "no-caller": 2, + "no-catch-shadow": 0, + "no-cond-assign": 2, + "no-console": 0, + "no-constant-condition": 0, + "no-continue": 0, + "no-control-regex": 2, + "no-debugger": 0, + "no-delete-var": 2, + "no-div-regex": 0, + "no-dupe-args": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-else-return": 2, + "no-empty": 0, + "no-empty-character-class": 2, + "no-labels": 2, + "no-eq-null": 0, + "no-eval": 2, + "no-ex-assign": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-extra-boolean-cast": 2, + "no-extra-parens": 0, + "no-extra-semi": 0, + "no-extra-strict": 0, + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-func-assign": 2, + "no-implied-eval": 2, + "no-inline-comments": 0, + "no-inner-declarations": [2, "functions"], + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-iterator": 2, + "no-label-var": 2, + "no-lone-blocks": 0, + "no-lonely-if": 0, + "no-loop-func": 0, + "no-mixed-requires": 0, + "no-mixed-spaces-and-tabs": [2, false], + "no-multi-spaces": 2, + "no-multi-str": 0, + "no-multiple-empty-lines": [2, { "max": 1 }], + "no-native-reassign": 2, + "no-negated-in-lhs": 2, + "no-nested-ternary": 0, + "no-new": 2, + "no-new-func": 2, + "no-new-object": 2, + "no-new-require": 2, + "no-new-wrappers": 2, + "no-obj-calls": 2, + "no-octal": 2, + "no-octal-escape": 2, + "no-path-concat": 0, + "no-plusplus": 0, + "no-process-env": 0, + "no-process-exit": 0, + "no-proto": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-reserved-keys": 0, + "no-restricted-modules": 0, + "no-script-url": 0, + "no-self-compare": 2, + "no-sequences": 2, + "no-shadow": 0, + "no-shadow-restricted-names": 2, + "no-spaced-func": 2, + "no-sparse-arrays": 2, + "no-sync": 0, + "no-ternary": 0, + "no-throw-literal": 2, + "no-trailing-spaces": 2, + "no-undef": 0, + "no-undef-init": 2, + "no-undefined": 0, + "no-underscore-dangle": 0, + "no-unneeded-ternary": 2, + "no-unreachable": 2, + "no-unused-expressions": 0, + "no-unused-vars": [2, { "vars": "all", "args": "none" }], + "no-var": 2, + "no-void": 0, + "no-warning-comments": 0, + "no-with": 2, + "object-curly-spacing": [2, "always"], + "one-var": 0, + "operator-assignment": 0, + "operator-linebreak": [2, "after"], + "padded-blocks": 0, + "prefer-const": 2, + "quote-props": 0, + "quotes": [2, "single", "avoid-escape"], + "radix": 2, + "jsx-quotes": [2, "prefer-single"], + "semi-spacing": 0, + "sort-vars": 0, + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "keyword-spacing": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "spaced-comment": [0, "always"], + "strict": 0, + "use-isnan": 2, + "valid-jsdoc": 0, + "valid-typeof": 2, + "vars-on-top": 2, + "wrap-iife": [2, "any"], + "wrap-regex": 0, + "yoda": [2, "never"] + } +}; diff --git a/.gitignore b/.gitignore index 465b204cb..14dc2ca81 100644 --- a/.gitignore +++ b/.gitignore @@ -38,8 +38,6 @@ jspm_packages # local data data/ -package-lock.json -public/js/stats/The_bomb_chart.js config.json .node-xmlhttprequest-* -/nbproject/private/ \ No newline at end of file +/nbproject/private/ diff --git a/.travis.yml b/.travis.yml index d688b091c..fbb5cafa8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,32 @@ language: node_js sudo: required -dist: trusty -node_js: '7' -env: CXX=g++-4.8 -services: - - docker -before_install: - - docker pull trufflesuite/ganache-cli - - docker run -d -p 8545:8545 -p 27017:27017 trufflesuite/ganache-cli - - varA=`docker ps --no-trunc -q | cut -c 1-12` - - docker pull mongo - - docker run -d --network="container:$varA" mongo - - docker build -t ethereumclassic/explorer . - - docker run -d --network="container:$varA" ethereumclassic/explorer app.js -script: -- npm run test +matrix: + include: + # This builder checks explorer build + - os: linux + dist: xenial + node_js: '8' + services: + - docker + before_install: + - docker pull trufflesuite/ganache-cli + - docker run -d -p 8546:8546 -p 27017:27017 trufflesuite/ganache-cli -p 8546 + - varA=`docker ps --no-trunc -q | cut -c 1-12` + - docker pull mongo + - docker run -d --network="container:$varA" mongo + - docker build -t ethereumclassic/explorer . + - docker run -d --network="container:$varA" ethereumclassic/explorer app.js + script: + - npm run test + + # This builder only tests code linters + - os: linux + dist: xenial + node_js: '8' + env: lint + script: + - npm run lint:check + + # Temporary allow failures for eslint until the code is done. + allow_failures: + - env: lint diff --git a/Dockerfile b/Dockerfile index 3d95fcafd..c3ed81157 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:latest +FROM node:8 COPY . / diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..200cde813 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2019 Ethereum Classic, and contributors to this project + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 3a19cd14d..000000000 --- a/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -## Ethereum Classic Explorer License - -Copyright (c) 2016 Ethereum Classic, and contributors to this project - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index efc1c5837..91a8a4f97 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ -# ETCExplorer +# ETC Explorer + +ETC Explorer logo Live Version: [etherhub.io](http://etherhub.io) -Follow the project progress at: [ETC Block Explorer Development](https://github.com/ethereumproject/explorer) +Follow the project progress at: [ETC Block Explorer Development](https://github.com/ethereumclassic/explorer) ## Local installation Clone the repo -`git clone https://github.com/ethereumproject/explorer` +`git clone https://github.com/ethereumclassic/explorer` Download [Nodejs and npm](https://docs.npmjs.com/getting-started/installing-node "Nodejs install") if you don't have them @@ -34,7 +36,7 @@ Basic settings: ```json { "nodeAddr": "localhost", - "gethPort": 8545, + "wsPort": 8546, "startBlock": 0, "endBlock": "latest", "quiet": true, @@ -53,12 +55,12 @@ Basic settings: "linkedin": "https://www.linkedin.com/company/ethereum-classic", "github": "https://github.com/ethereumclassic", "logo": "/img/explorer-logo.png", - "customCss": "green-haze.min.css", - "copyright": "2018 © Ethereum Classic.", - "useEthFiat": false, + "copyright": "2019 © Ethereum Classic.", "poweredbyCustom": false, "poweredbyEtcImage": "/img/powered-by-etcexplorer-w.png", "poweredbyEtc": true, + "useRichList": true, + "useFiat": true, "miners": { "0xdf7d7e053933b5cc24372f878c90e62dadad5d42": "EtherMine", "0xc91716199ccde49dc4fafaeb68925127ac80443f": "F2Pool", @@ -92,32 +94,105 @@ Basic settings: ``` -```nodeAddr``` Your node API RPC address. +| Name | Explanation | +|-------------|-----| +| `nodeAddr` | Your node API RPC address. | +| `wsPort` | Your node API WS (Websocket) port. (RPC HTTP port is deprecated on Web3 1.0 see https://web3js.readthedocs.io/en/1.0/web3.html#value) | +| `startBlock` | This is the start block of the blockchain, should always be 0 if you want to sync the whole ETC blockchain. | +| `endBlock` | This is usually the 'latest'/'newest' block in the blockchain, this value gets updated automatically, and will be used to patch missing blocks if the whole app goes down. | +| `quiet` | Suppress some messages. (admittedly still not quiet) | +| `syncAll` | If this is set to true at the start of the app, the sync will start syncing all blocks from lastSync, and if lastSync is 0 it will start from whatever the endBlock or latest block in the blockchain is. | +| `patch` | If set to true and below value is set, sync will iterated through the # of blocks specified. | +| `patchBlocks` | If `patch` is set to true, the amount of block specified will be check from the latest one. | +| `useRichList` | If `useRichList` is set to true, explorer will update account balance for richlist page. | +| `useFiat` | If `useFiat` is set to true, explorer will show price for account & tx page. ( Disable for testnets )| + +### Mongodb Auth setting. + +#### Configure MongoDB + +In view of system security, most of mongoDB Admin has setup security options, So, You need to setup mongodb auth informations. +Switch to the built-in admin database: + +``` +$ mongo +$ > use admin +``` + +1. Create an administrative user (if you have already admin or root of mongodb account, then skip it) + +``` +# make admin auth and role setup +$ > db.createUser( { user: "admin", pwd: "", roles: ["root"] } ) +``` + +And, You can make Explorer's "explorerDB" database with db user accounts "explorer" and password "some_pass_code". + +``` +$ > use explorerDB +$ > db.createUser( { user: "explorer", pwd: "", roles: ["dbOwner"] } ) +$ > quit() +``` + +Above dbuser explorer will full access explorerDB and clustor setting will be well used on monitoring the multiple sharding and replication of multiple mongodb instances. +Enable database authorization in the MongoDB configuration file /etc/mongodb.conf by appending the following lines: + +``` +auth=true +``` + +Restart MongoDB and verify the administrative user created earlier can connect: -```gethPort``` Your node API RPC port. +``` +$ sudo service mongodb restart +$ mongo -u admin -p your_password --authenticationDatabase=admin +``` -```startBlock``` This is the start block of the blockchain, should always be 0 if you want to sync the whole ETC blockchain. +If everything is configured correctly the Mongo Shell will connect and -```endBlock``` This is usually the 'latest'/'newest' block in the blockchain, this value gets updated automatically, and will be used to patch missing blocks if the whole app goes down. +``` +$ > show dbs +``` -```quiet``` Suppress some messages. (admittedly still not quiet) +will show db informations. +and You can add modified from ./db.js:103 lines, add auth information and mongodb connect options. -```syncAll``` If this is set to true at the start of the app, the sync will start syncing all blocks from lastSync, and if lastSync is 0 it will start from whatever the endBlock or latest block in the blockchain is. +``` +mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost/explorerDB', { + useMongoClient: true + // poolSize: 5, + // rs_name: 'myReplicaSetName', + // user: 'explorer', + // pass: 'yourdbpasscode' +}); +``` -```patch``` If set to true and below value is set, sync will iterated through the # of blocks specified. +And explore it. -```patchBlocks``` If `patch` is set to true, the amount of block specified will be check from the latest one. +### Run +The below will start both the web-gui and sync.js (which populates MongoDB with blocks/transactions). -### Run: -The below will start both the web-gui and sync.js (which populates MongoDV with blocks/transactions). `npm start` You can leave sync.js running without app.js and it will sync and grab blocks based on config.json parameters -`node ./tools/sync.js` + +`npm run sync` Enabling stats requires running a separate process: -`node ./tools/stats.js` + +`npm run stats` + +Enabling richlist requires running a separate process: + +`npm run rich` You can configure intervals (how often a new data point is pulled) and range (how many blocks to go back) with the following: -`RESCAN=100:7400000 node tools/stats.js` (New data point every 100 blocks. Go back 7,400,000 blocks). + +`RESCAN=100:7700000 node tools/stats.js` (New data point every 100 blocks. Go back 7,700,000 blocks). + +## Docker installation + +Set `nodeAddr` in `config.json` to `host.docker.internal` + +Run `docker-compose up` diff --git a/app.js b/app.js index 525636497..a0ffb12b7 100644 --- a/app.js +++ b/app.js @@ -1,17 +1,17 @@ #!/usr/bin/env node -require( './db' ); +require('./db'); -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var bodyParser = require('body-parser'); +const express = require('express'); +const path = require('path'); +const favicon = require('serve-favicon'); +const logger = require('morgan'); +const bodyParser = require('body-parser'); -var config = {}; +let config = {}; try { config = require('./config.json'); -} catch(e) { +} catch (e) { if (e.code == 'MODULE_NOT_FOUND') { console.log('No config file found. Using default configuration... (config.example.json)'); config = require('./config.example.json'); @@ -21,37 +21,36 @@ try { } } -var app = express(); +const app = express(); app.set('port', process.env.PORT || 3000); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); -app.use(favicon(__dirname + '/public/favicon.ico')); +app.use(favicon(`${__dirname}/public/favicon.ico`)); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static(path.join(__dirname, 'public'))); // app libraries -global.__lib = __dirname + '/lib/'; - +global.__lib = `${__dirname}/lib/`; // client -app.get('/', function(req, res) { +app.get('/', (req, res) => { res.render('index', config); }); -app.get('/config', function(req, res) { +app.get('/config', (req, res) => { res.json(config.settings); }); require('./routes')(app); // let angular catch them -app.use(function(req, res) { +app.use((req, res) => { res.render('index', config); }); @@ -60,31 +59,27 @@ app.use(function(req, res) { // development error handler // will print stacktrace if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); + app.use((err, req, res, next) => { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: err, }); + }); } - // production error handler // no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); +app.use((err, req, res, next) => { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: {}, + }); }); -var http = require('http').Server(app); -//var io = require('socket.io')(http); +const http = require('http').Server(app); -// web3socket(io); - -http.listen(app.get('port'), '0.0.0.0', function() { - console.log('Express server listening on port ' + app.get('port')); -}); \ No newline at end of file +http.listen(app.get('port'), '0.0.0.0', () => { + console.log(`Express server listening on port ${app.get('port')}`); +}); diff --git a/app/app.js b/app/app.js deleted file mode 100644 index 2f962efd9..000000000 --- a/app/app.js +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env node - -require( './db' ); - -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var bodyParser = require('body-parser'); - -var config = {}; -try { - config = require('./config.json'); -} catch(e) { - if (e.code == 'MODULE_NOT_FOUND') { - console.log('No config file found. Using default configuration... (tools/config.json)'); - config = require('./tools/config.json'); - } else { - throw e; - process.exit(1); - } -} - -var app = express(); -app.set('port', process.env.PORT || 3000); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'ejs'); - -app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: true })); -app.use(express.static(path.join(__dirname, 'public'))); - -// app libraries -global.__lib = __dirname + '/lib/'; - - -// client - -app.get('/', function(req, res) { - res.render('index', config); -}); - -app.get('/config', function(req, res) { - res.json(config.settings); -}); - -require('./routes')(app); - -// let angular catch them -app.use(function(req, res) { - res.render('index', config); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - -var http = require('http').Server(app); -//var io = require('socket.io')(http); - -// web3socket(io); - -http.listen(app.get('port'), '0.0.0.0', function() { - console.log('Express server listening on port ' + app.get('port')); -}); \ No newline at end of file diff --git a/config.example.json b/config.example.json index 52e825157..53673ef53 100644 --- a/config.example.json +++ b/config.example.json @@ -1,7 +1,8 @@ { "nodeAddr": "localhost", - "gethPort": 8545, + "wsPort": 8546, "startBlock": 0, + "endBlock": "latest", "quiet": true, "syncAll": true, "patch": true, @@ -18,42 +19,14 @@ "reddit": "https://www.reddit.com/r/EthereumClassic", "twitter": "https://twitter.com/eth_classic", "linkedin": "https://www.linkedin.com/company/ethereum-classic", - "github": "https://github.com/ethereumproject", + "github": "https://github.com/ethereumclassic", "logo": "/img/explorer-logo.png", - "customCss": "green-haze.min.css", - "copyright": "2018 © Ethereum Classic.", - "useEthFiat": false, + "copyright": "2019 © Ethereum Classic.", "poweredbyCustom": false, "poweredbyEtcImage": "/img/powered-by-etcexplorer-w.png", "poweredbyEtc": true, "tokenList": "tokens.json", - "miners": { - "0xdf7d7e053933b5cc24372f878c90e62dadad5d42": "EtherMine", - "0xc91716199ccde49dc4fafaeb68925127ac80443f": "F2Pool", - "0x9eab4b0fc468a7f5d46228bf5a76cb52370d068d": "NanoPool", - "0x1C0FA194a9d3B44313DCD849F3C6be6Ad270a0A4": "MiningPoolHub", - "0x4750e296949b747df1585aa67beee8be903dd560": "UUPool", - "0xef224fa5fad302b51f38898f4df499d7af127af0": "91pool", - "0x0073Cf1B9230cF3EE8Cab1971B8DbeF21eA7B595": "2miners", - "0x4c2b4e716883a2c3f6b980b70b577e54b9441060": "ETCPool PL", - "0xd144e30a0571aaf0d0c050070ac435deba461fab": "Clona Network", - "0x568f58bf1667504fdf5aa02d776c156f940178a5": "Whalesburg", - "0x3b2d2613ad66d66ee0cb518aeeccc98e9e3b19c0": "private(0x3b2d2613)", - "0x919973eb38844313dc31c41e140700d6e333f8d5": "private(0x919973eb)", - "0xb205f337bad80e28351c7540b741c81470c4927f": "private(0xb205f337)", - "0x232cad0429e653ab610fbcf7e7ebee2f05f28410": "private(0x232cad04)", - "0x999c2944807874d3677ee3c6065c8a8a92721ac5": "NinjaPool.jp", - "0x39cd14977601184b7da518fd352261aad0cb9fd3": "91pool", - "0xf35074bbd0a9aee46f4ea137971feec024ab704e": "Solo Mining Pools", - "0xa97ed75172773ec705c2c78d999d3203199101bd": "epool", - "0x58b3cabd0c5c777da2c1c4d4f7ecc8afe5674f20": "private(0x58b3cabd0)", - "0x87cfd09c483fe65352456bb26c784a0e4c4ba389": "ArsMine", - "0x5bc9ccbd3115cefb6f382d33e8ce2a0aba084da4": "private(0x5bc9ccbd3)", - "0x4924414988feb1ee16e29298509f96317400eb57": "private(0x492441498)", - "0xa9a926bed50dc038b20bb20de361e4c35aae51fc": "private(0xa9a926bed)", - "0x0073cf1b9230cf3ee8cab1971b8dbef21ea7b595": "2miners", - "0x004730417cd2b1d19f6be2679906ded4fa8a64e2": "2miners", - "0x1c0fa194a9d3b44313dcd849f3c6be6ad270a0a4": "MiningPoolHub" - } + "useRichList": true, + "useFiat": true } } diff --git a/db-dao.js b/db-dao.js deleted file mode 100644 index 7d563f1d9..000000000 --- a/db-dao.js +++ /dev/null @@ -1,26 +0,0 @@ -var mongoose = require( 'mongoose' ); -var Schema = mongoose.Schema; - -var DAOCreatedToken = new Schema( -{ - "transactionHash": {type: String, index: {unique: true}}, - "blockNumber": {type: Number, index: {unique: false}}, - "amount": String, - "to": String, - "timestamp": Number -}); - -var DAOTransferToken = new Schema( -{ - "transactionHash": {type: String, index: {unique: true}}, - "blockNumber": {type: Number, index: {unique: false}}, - "amount": String, - "to": String, - "from": String, - "timestamp": Number -}); - -mongoose.model('DAOCreatedToken', DAOCreatedToken); -mongoose.model('DAOTransferToken', DAOTransferToken); -module.exports.DAOCreatedToken = mongoose.model('DAOCreatedToken'); -module.exports.DAOTransferToken = mongoose.model('DAOTransferToken'); \ No newline at end of file diff --git a/db.js b/db.js index e9ec2c670..34880e69e 100644 --- a/db.js +++ b/db.js @@ -1,105 +1,156 @@ -var mongoose = require( 'mongoose' ); -var Schema = mongoose.Schema; - -var Block = new Schema( -{ - "number": {type: Number, index: {unique: true}}, - "hash": String, - "parentHash": String, - "nonce": String, - "sha3Uncles": String, - "logsBloom": String, - "transactionsRoot": String, - "stateRoot": String, - "receiptRoot": String, - "miner": String, - "difficulty": String, - "totalDifficulty": String, - "size": Number, - "extraData": String, - "gasLimit": Number, - "gasUsed": Number, - "timestamp": Number, - "blockTime": Number, - "uncles": [String] -}); - -var Account = new Schema( -{ - "address": {type: String, index: {unique: true}}, - "balance": Number, - "blockNumber": Number, - "type": {type: Number, default: 0} // address: 0x0, contract: 0x1 -}); - -var Contract = new Schema( -{ - "address": {type: String, index: {unique: true}}, - "creationTransaction": String, - "contractName": String, - "compilerVersion": String, - "optimization": Boolean, - "sourceCode": String, - "abi": String, - "byteCode": String -}, {collection: "Contract"}); - -var Transaction = new Schema( -{ - "hash": {type: String, index: {unique: true}}, - "nonce": Number, - "blockHash": String, - "blockNumber": Number, - "transactionIndex": Number, - "from": String, - "to": String, - "creates": String, - "value": String, - "gas": Number, - "gasPrice": String, - "timestamp": Number, - "input": String -}, {collection: "Transaction"}); - -var BlockStat = new Schema( -{ - "number": {type: Number, index: {unique: true}}, - "timestamp": Number, - "difficulty": String, - "hashrate": String, - "txCount": Number, - "gasUsed": Number, - "gasLimit": Number, - "miner": String, - "blockTime": Number, - "uncleCount": Number -}); - -// create indices -Transaction.index({blockNumber:-1}); -Transaction.index({from:1, blockNumber:-1}); -Transaction.index({to:1, blockNumber:-1}); -Transaction.index({creates:1, blockNumber:-1}); -Account.index({balance:-1}); -Account.index({balance:-1, blockNumber:-1}); -Account.index({type:-1, balance:-1}); -Block.index({miner:1}); -Block.index({miner:1, blockNumber:-1}); - -mongoose.model('BlockStat', BlockStat); -mongoose.model('Block', Block); -mongoose.model('Account', Account); -mongoose.model('Contract', Contract); -mongoose.model('Transaction', Transaction); -module.exports.BlockStat = mongoose.model('BlockStat'); -module.exports.Block = mongoose.model('Block'); -module.exports.Contract = mongoose.model('Contract'); -module.exports.Transaction = mongoose.model('Transaction'); -module.exports.Account = mongoose.model('Account'); - -mongoose.Promise = global.Promise; -mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost/blockDB', { - useMongoClient: true -}); - -// mongoose.set('debug', true); +const mongoose = require('mongoose'); + +const { Schema } = mongoose; + +const Block = new Schema( + { + 'number': { type: Number, index: { unique: true } }, + 'hash': String, + 'parentHash': String, + 'nonce': String, + 'sha3Uncles': String, + 'logsBloom': String, + 'transactionsRoot': String, + 'stateRoot': String, + 'receiptRoot': String, + 'miner': { type: String, lowercase: true }, + 'difficulty': String, + 'totalDifficulty': String, + 'size': Number, + 'extraData': String, + 'gasLimit': Number, + 'gasUsed': Number, + 'timestamp': Number, + 'blockTime': Number, + 'uncles': [String], + }, { collection: 'Block' }, +); + +const Account = new Schema( + { + 'address': { type: String, index: { unique: true } }, + 'balance': Number, + 'blockNumber': Number, + 'type': { type: Number, default: 0 }, // address: 0x0, contract: 0x1 + }, { collection: 'Account' }, +); + +const Contract = new Schema( + { + 'address': { type: String, index: { unique: true } }, + 'blockNumber': Number, + 'ERC': { type: Number, index: true }, //0:normal contract, 2:ERC20, 3:ERC223 + 'creationTransaction': String, + 'contractName': String, + 'tokenName': String, + 'symbol': String, + 'owner': String, + 'decimals': Number, + 'totalSupply': Number, + 'compilerVersion': String, + 'optimization': Boolean, + 'sourceCode': String, + 'abi': String, + 'byteCode': String, + }, { collection: 'Contract' }, +); + +const Transaction = new Schema( + { + 'hash': { type: String, index: { unique: true }, lowercase: true }, + 'nonce': Number, + 'blockHash': String, + 'blockNumber': Number, + 'transactionIndex': Number, + 'status': Number, + 'from': { type: String, lowercase: true }, + 'to': { type: String, lowercase: true }, + 'creates': { type: String, lowercase: true }, + 'value': String, + 'gas': Number, + 'gasUsed': Number, + 'gasPrice': String, + 'timestamp': Number, + 'input': String, + }, { collection: 'Transaction' }, +); + +const TokenTransfer = new Schema( + { + 'hash': { type: String, index: { unique: true }, lowercase: true }, + 'blockNumber': Number, + 'method': String, + 'from': { type: String, lowercase: true }, + 'to': { type: String, lowercase: true }, + 'contract': { type: String, lowercase: true }, + 'value': String, + 'timestamp': Number, + }, { collection: 'TokenTransfer' }, +); + +const BlockStat = new Schema( + { + 'number': { type: Number, index: { unique: true } }, + 'timestamp': Number, + 'difficulty': String, + 'hashrate': String, + 'txCount': Number, + 'gasUsed': Number, + 'gasLimit': Number, + 'miner': String, + 'blockTime': Number, + 'uncleCount': Number, + }, { collection: 'BlockStat' }, +); + +const Market = new Schema( + { + 'symbol': String, + 'timestamp': Number, + 'quoteBTC': Number, + 'quoteUSD': Number, + }, { collection: 'Market' }, +); + +// create indices +Transaction.index({ blockNumber: -1 }); +Transaction.index({ from: 1, blockNumber: -1 }); +Transaction.index({ to: 1, blockNumber: -1 }); +Transaction.index({ creates: 1, blockNumber: -1 }); +Account.index({ balance: -1 }); +Account.index({ balance: -1, blockNumber: -1 }); +Account.index({ type: -1, balance: -1 }); +Block.index({ miner: 1 }); +Block.index({ miner: 1, blockNumber: -1 }); +Block.index({ hash: 1, number: -1 }); +Market.index({ timestamp: -1 }); +TokenTransfer.index({ blockNumber: -1 }); +TokenTransfer.index({ from: 1, blockNumber: -1 }); +TokenTransfer.index({ to: 1, blockNumber: -1 }); +TokenTransfer.index({ contract: 1, blockNumber: -1 }); + +mongoose.model('BlockStat', BlockStat); +mongoose.model('Block', Block); +mongoose.model('Account', Account); +mongoose.model('Contract', Contract); +mongoose.model('Transaction', Transaction); +mongoose.model('Market', Market); +mongoose.model('TokenTransfer', TokenTransfer); +module.exports.BlockStat = mongoose.model('BlockStat'); +module.exports.Block = mongoose.model('Block'); +module.exports.Contract = mongoose.model('Contract'); +module.exports.Transaction = mongoose.model('Transaction'); +module.exports.Account = mongoose.model('Account'); +module.exports.Market = mongoose.model('Market'); +module.exports.TokenTransfer = mongoose.model('TokenTransfer'); + +mongoose.Promise = global.Promise; +mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost/explorerDB', { + useMongoClient: true + // poolSize: 5, + // rs_name: 'myReplicaSetName', + // user: 'explorer', + // pass: 'yourdbpasscode' +}); + +// mongoose.set('debug', true); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..08df876a1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,46 @@ +version: '3' +services: + app: + build: . + command: ./app.js + restart: always + environment: + MONGO_URI: 'mongodb://db/explorerDB' + ports: + - '3000:3000' + depends_on: + - db + sync: + build: . + command: ./tools/sync.js + restart: always + environment: + MONGO_URI: 'mongodb://db/explorerDB' + depends_on: + - db + stats: + build: . + command: ./tools/stats.js + restart: always + environment: + MONGO_URI: 'mongodb://db/explorerDB' + depends_on: + - db + price: + build: . + command: ./tools/price.js + restart: always + environment: + MONGO_URI: 'mongodb://db/explorerDB' + depends_on: + - db + richlist: + build: . + command: ./tools/richlist.js + restart: "no" + environment: + MONGO_URI: 'mongodb://db/explorerDB' + depends_on: + - db + db: + image: mongo diff --git a/html-linter.json b/html-linter.json new file mode 100644 index 000000000..bc560efb3 --- /dev/null +++ b/html-linter.json @@ -0,0 +1,16 @@ +{ + "files": [ + "./public/tpl/*.html", + "./public/views/*.html", + "./public/views/stats/*.html" + ], + "indentation": { + "char": "space", + "number": 2 + }, + "attributes": { + "quotes": "double", + "whitespace": 0, + "vertical-align": true + } +} diff --git a/lib/etherUnits.js b/lib/etherUnits.js index cf598f98d..519641f27 100644 --- a/lib/etherUnits.js +++ b/lib/etherUnits.js @@ -1,59 +1,56 @@ -'use strict'; -var BigNumber = require('bignumber.js'); +'use strict'; -var etherUnits = function() {} +const BigNumber = require('bignumber.js'); + +const etherUnits = function () {}; etherUnits.unitMap = { - 'wei': '1', - 'kwei': '1000', - 'ada': '1000', - 'femtoether': '1000', - 'mwei': '1000000', - 'babbage': '1000000', - 'picoether': '1000000', - 'gwei': '1000000000', - 'shannon': '1000000000', - 'nanoether': '1000000000', - 'nano': '1000000000', - 'szabo': '1000000000000', - 'microether': '1000000000000', - 'micro': '1000000000000', - 'finney': '1000000000000000', - 'milliether': '1000000000000000', - 'milli': '1000000000000000', - 'ether': '1000000000000000000', - 'kether': '1000000000000000000000', - 'grand': '1000000000000000000000', - 'einstein': '1000000000000000000000', - 'mether': '1000000000000000000000000', - 'gether': '1000000000000000000000000000', - 'tether': '1000000000000000000000000000000' + 'wei': '1', + 'kwei': '1000', + 'ada': '1000', + 'femtoether': '1000', + 'mwei': '1000000', + 'babbage': '1000000', + 'picoether': '1000000', + 'gwei': '1000000000', + 'shannon': '1000000000', + 'nanoether': '1000000000', + 'nano': '1000000000', + 'szabo': '1000000000000', + 'microether': '1000000000000', + 'micro': '1000000000000', + 'finney': '1000000000000000', + 'milliether': '1000000000000000', + 'milli': '1000000000000000', + 'ether': '1000000000000000000', + 'kether': '1000000000000000000000', + 'grand': '1000000000000000000000', + 'einstein': '1000000000000000000000', + 'mether': '1000000000000000000000000', + 'gether': '1000000000000000000000000000', + 'tether': '1000000000000000000000000000000', +}; +etherUnits.getValueOfUnit = function (unit) { + unit = unit ? unit.toLowerCase() : 'ether'; + const unitValue = this.unitMap[unit]; + if (unitValue === undefined) { + throw new Error(globalFuncs.errorMsgs[4] + JSON.stringify(this.unitMap, null, 2)); + } + return new BigNumber(unitValue, 10); }; -etherUnits.getValueOfUnit = function(unit) { - unit = unit ? unit.toLowerCase() : 'ether'; - var unitValue = this.unitMap[unit]; - if (unitValue === undefined) { - throw new Error(globalFuncs.errorMsgs[4] + JSON.stringify(this.unitMap, null, 2)); - } - return new BigNumber(unitValue, 10); -} -etherUnits.fiatToWei = function(number, pricePerEther) { - var returnValue = new BigNumber(String(number)).div(pricePerEther).times(this.getValueOfUnit('ether')).round(0); - return returnValue.toString(10); -} -etherUnits.toFiat = function(number, unit, multi) { - var returnValue = new BigNumber(this.toEther(number, unit)).times(multi).round(5); - return returnValue.toString(10); -} +etherUnits.toEther = function (number, unit) { + const returnValue = new BigNumber(this.toWei(number, unit)).div(this.getValueOfUnit('ether')); + return returnValue.toString(10); +}; -etherUnits.toEther = function(number, unit) { - var returnValue = new BigNumber(this.toWei(number, unit)).div(this.getValueOfUnit('ether')); - return returnValue.toString(10); -} +etherUnits.toGwei = function (number, unit) { + const returnValue = new BigNumber(this.toWei(number, unit)).div(this.getValueOfUnit('gwei')); + return returnValue.toString(10); +}; -etherUnits.toWei = function(number, unit) { - var returnValue = new BigNumber(String(number)).times(this.getValueOfUnit(unit)); - return returnValue.toString(10); -} +etherUnits.toWei = function (number, unit) { + const returnValue = new BigNumber(String(number)).times(this.getValueOfUnit(unit)); + return returnValue.toString(10); +}; -module.exports = etherUnits; \ No newline at end of file +module.exports = etherUnits; diff --git a/lib/trace.js b/lib/trace.js deleted file mode 100644 index 3feb4590c..000000000 --- a/lib/trace.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @author Alexis Roussel - * @author Peter Pratscher - * @date 2017 - * @license LGPL - * @changelog 2018/05/19 - modified for web3.js 0.20.x using _extend() method. (by hackyminer ) - */ -module.exports = function(web3) { - /** - * @file trace.js - * @author Alexis Roussel - * @date 2017 - * @license LGPL - */ - web3._extend({ - property: 'trace', - methods: [ - new web3._extend.Method({ - name: 'call', - call: 'trace_call', - params: 3, - inputFormatter: [web3._extend.formatters.inputCallFormatter, null, web3._extend.formatters.inputDefaultBlockNumberFormatter] - }), - - new web3._extend.Method({ - name: 'rawTransaction', - call: 'trace_rawTransaction', - params: 2 - }), - - new web3._extend.Method({ - name: 'replayTransaction', - call: 'trace_replayTransaction', - params: 2 - }), - - new web3._extend.Method({ - name: 'block', - call: 'trace_block', - params: 1, - inputFormatter: [web3._extend.formatters.inputDefaultBlockNumberFormatter] - }), - - new web3._extend.Method({ - name: 'filter', - call: 'trace_filter', - params: 1 - }), - - new web3._extend.Method({ - name: 'get', - call: 'trace_get', - params: 2 - }), - - new web3._extend.Method({ - name: 'transaction', - call: 'trace_transaction', - params: 1 - }) - ] - }); - - /** - * @file parity.js - * @author Peter Pratscher - * @date 2017 - * @license LGPL - */ - web3._extend({ - property: 'parity', - methods: [ - new web3._extend.Method({ - name: 'pendingTransactions', - call: 'parity_pendingTransactions', - params: 0, - outputFormatter: web3._extend.formatters.outputTransactionFormatter - }), - - new web3._extend.Method({ - name: 'pendingTransactionsStats', - call: 'parity_pendingTransactionsStats', - params: 0 - }), - - new web3._extend.Method({ - name: 'listAccounts', - call: 'parity_listAccounts', - params: 3, - inputFormatter: [null, null, web3._extend.formatters.inputDefaultBlockNumberFormatter] - }), - - new web3._extend.Method({ - name: 'phraseToAddress', - call: 'parity_phraseToAddress', - params: 1 - }) - ] - }); - return web3; -}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..cbb785150 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5897 @@ +{ + "name": "etc-explorer", + "version": "0.2.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@types/node": { + "version": "10.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.1.tgz", + "integrity": "sha512-Rymt08vh1GaW4vYB6QP61/5m/CFLGnFZP++bJpWbiNxceNa6RBipDmb413jvtSf/R1gg5a/jQVl2jY4XVRscEA==" + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "requires": { + "lodash": "^4.14.0" + } + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bignumber.js": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.1.1.tgz", + "integrity": "sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sha3": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.4.tgz", + "integrity": "sha1-CGxHuMgjFsnUcCLCYYWVRXbdjiY=", + "requires": { + "js-sha3": "^0.6.1", + "safe-buffer": "^5.1.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "bson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + }, + "camelcase": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" + }, + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concurrently": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-4.1.0.tgz", + "integrity": "sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg==", + "requires": { + "chalk": "^2.4.1", + "date-fns": "^1.23.0", + "lodash": "^4.17.10", + "read-pkg": "^4.0.1", + "rxjs": "^6.3.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^4.5.0", + "tree-kill": "^1.1.0", + "yargs": "^12.0.1" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", + "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.15.3.tgz", + "integrity": "sha512-vMGi0PjCHSokZxE0NLp2VneGw5sio7SSiDNgIUn2tC0XkWJRNOIoHIg3CliLVfXnJsiHxGAYrkw0PieAu8+KYQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "eslint-config-airbnb-base": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz", + "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==", + "dev": true, + "requires": { + "eslint-restricted-globals": "^0.1.1", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", + "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz", + "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==", + "dev": true, + "requires": { + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.3.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.9.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + }, + "dependencies": { + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + } + } + }, + "eth-lib": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", + "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "keccakjs": "^0.2.1", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "ethers": { + "version": "4.0.0-beta.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.0-beta.1.tgz", + "integrity": "sha512-SoYhktEbLxf+fiux5SfCEwdzWENMvgIbMZD90I62s4GZD9nEjgEWy8ZboI3hck193Vs0bDoTohDISx84f2H2tw==", + "requires": { + "@types/node": "^10.3.2", + "aes-js": "3.0.0", + "bn.js": "^4.4.0", + "elliptic": "6.3.3", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.3", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "elliptic": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", + "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + }, + "setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=" + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" + } + } + }, + "ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "eventemitter3": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", + "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + } + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "fs-promise": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", + "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", + "requires": { + "any-promise": "^1.3.0", + "fs-extra": "^2.0.0", + "mz": "^2.6.0", + "thenify-all": "^1.6.0" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "requires": { + "min-document": "^2.19.0", + "process": "~0.5.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + } + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hooks-fixed": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.2.tgz", + "integrity": "sha512-YurCM4gQSetcrhwEtpQHhQ4M7Zo7poNGqY4kQGeBS6eZtOcT3tnNs01ThFa0jYBByAiYt1MjMjP/YApG0EnAvQ==" + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + }, + "html-linter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-linter/-/html-linter-1.1.1.tgz", + "integrity": "sha512-DJfLevdq+YmY4R7yMdD0zaCAJOvWihg+eCe5o/jeTw86grvgmvSCIwBv1mDi+UdeJP9mDoi5rB6KtcFOn8StrA==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "commander": "^2.12.2", + "glob": "^7.1.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-standard-token-abi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/human-standard-token-abi/-/human-standard-token-abi-2.0.0.tgz", + "integrity": "sha512-m1f5DiIvqaNmpgphNqx2OziyTCj4Lvmmk28uMSxGWrOc9/lMpAKH8UcMPhvb13DMNZPzxn07WYFhxOGKuPLryg==" + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + } + } + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", + "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" + }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "js-sha3": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz", + "integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kareem": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz", + "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg=" + }, + "keccak": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", + "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", + "requires": { + "bindings": "^1.2.1", + "inherits": "^2.0.3", + "nan": "^2.2.1", + "safe-buffer": "^5.1.0" + } + }, + "keccakjs": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.3.tgz", + "integrity": "sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg==", + "requires": { + "browserify-sha3": "^0.0.4", + "sha3": "^1.2.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "requires": { + "mime-db": "~1.38.0" + } + }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "requires": { + "mkdirp": "*" + } + }, + "mocha": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.2.tgz", + "integrity": "sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "findup-sync": "2.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.12.0", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "ms": "2.1.1", + "node-environment-flags": "1.0.4", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "12.0.5", + "yargs-parser": "11.1.1", + "yargs-unparser": "1.5.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "mock-fs": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.8.0.tgz", + "integrity": "sha512-Gwj4KnJOW15YeTJKO5frFd/WDO5Mc0zxXqL9oHx3+e9rBqW8EVARqQHSaIXznUdljrD6pvbNGW2ZGXKPEfYJfw==" + }, + "mongodb": { + "version": "2.2.34", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", + "integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.18", + "readable-stream": "2.2.7" + } + }, + "mongodb-core": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", + "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "mongoose": { + "version": "4.13.18", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.13.18.tgz", + "integrity": "sha512-pPZlVID+/9xl0pyBibr7CZbjYKzpJZuw58TdWwIxr3ydO/OUZqhX1kUEAQIzsOJVSsL6GnD1fb54reO35jvLtw==", + "requires": { + "async": "2.6.0", + "bson": "~1.0.4", + "hooks-fixed": "2.0.2", + "kareem": "1.5.0", + "lodash.get": "4.4.2", + "mongodb": "2.2.34", + "mpath": "0.5.1", + "mpromise": "0.5.5", + "mquery": "2.3.3", + "ms": "2.0.0", + "muri": "1.3.0", + "regexp-clone": "0.0.1", + "sliced": "1.0.1" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "mout": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", + "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=" + }, + "mpath": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz", + "integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg==" + }, + "mpromise": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz", + "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" + }, + "mquery": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.3.tgz", + "integrity": "sha512-NC8L14kn+qxJbbJ1gbcEMDxF0sC3sv+1cbRReXXwVvowcwY1y9KoVZFq0ebwARibsadu8lx8nWGvm3V0Pf0ZWQ==", + "requires": { + "bluebird": "3.5.0", + "debug": "2.6.9", + "regexp-clone": "0.0.1", + "sliced": "0.0.5" + }, + "dependencies": { + "sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "muri": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/muri/-/muri-1.3.0.tgz", + "integrity": "sha512-FiaFwKl864onHFFUV/a2szAl7X0fxVlSKNdhTf+BM8i8goEgYut8u5P9MqQqIYwvaMxjzVESsoEm/2kfkFH1rg==" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nan": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.1.tgz", + "integrity": "sha512-I6YB/YEuDeUZMmhscXKxGgZlFnhsn5y0hgOZBadkzfTRrZBtJDZeg6eQf7PYMIEclwmorTKK8GztsyOUSVBREA==" + }, + "nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-environment-flags": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.4.tgz", + "integrity": "sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "oboe": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", + "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", + "requires": { + "http-https": "^1.0.0" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==" + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==" + }, + "parent-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", + "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-headers": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz", + "integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==", + "requires": { + "for-each": "^0.3.3", + "string.prototype.trim": "^1.1.2" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "randomhex": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz", + "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.3.tgz", + "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==", + "requires": { + "bn.js": "^4.11.1", + "safe-buffer": "^5.1.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scrypt": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", + "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", + "requires": { + "nan": "^2.0.8" + } + }, + "scrypt-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz", + "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=" + }, + "scrypt.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", + "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", + "requires": { + "scrypt": "^6.0.2", + "scryptsy": "^1.2.1" + } + }, + "scryptsy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", + "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", + "requires": { + "pbkdf2": "^3.0.3" + } + }, + "seek-bzip": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", + "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", + "requires": { + "commander": "~2.8.1" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=", + "requires": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "requires": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "sha3": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", + "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", + "requires": { + "nan": "2.10.0" + }, + "dependencies": { + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "solc": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.5.6.tgz", + "integrity": "sha512-BuvrLwOSAGEUbE4jffLBcO9Vm8OVgxImE5qFTHzjH2n+RqBHeqDDOY0gU4LvGWsA6ttjADJyRriF9Pp0vjIq2g==", + "requires": { + "command-exists": "^1.2.8", + "fs-extra": "^0.30.0", + "keccak": "^1.0.2", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33", + "yargs": "^11.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "requires": { + "is-natural-number": "^4.0.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + } + } + }, + "swarm-js": { + "version": "0.1.37", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", + "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "decompress": "^4.0.0", + "eth-lib": "^0.1.26", + "fs-extra": "^2.1.2", + "fs-promise": "^2.0.0", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar.gz": "^1.0.5", + "xhr-request-promise": "^0.1.2" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" + } + } + } + }, + "table": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", + "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "tar.gz": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", + "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", + "requires": { + "bluebird": "^2.9.34", + "commander": "^2.8.1", + "fstream": "^1.0.8", + "mout": "^0.11.0", + "tar": "^2.1.1" + }, + "dependencies": { + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "thenify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", + "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "unbzip2-stream": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", + "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + } + }, + "url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "utf8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "web3": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.37.tgz", + "integrity": "sha512-8XLgUspdzicC/xHG82TLrcF/Fxzj2XYNJ1KTYnepOI77bj5rvpsxxwHYBWQ6/JOjk0HkZqoBfnXWgcIHCDhZhQ==", + "requires": { + "web3-bzz": "1.0.0-beta.37", + "web3-core": "1.0.0-beta.37", + "web3-eth": "1.0.0-beta.37", + "web3-eth-personal": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-shh": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-bzz": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.37.tgz", + "integrity": "sha512-E+dho49Nsm/QpQvYWOF35YDsQrMvLB19AApENxhlQsu6HpWQt534DQul0t3Y/aAh8rlKD6Kanxt8LhHDG3vejQ==", + "requires": { + "got": "7.1.0", + "swarm-js": "0.1.37", + "underscore": "1.8.3" + } + }, + "web3-core": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.37.tgz", + "integrity": "sha512-cIwEqCj7OJyefQNauI0HOgW4sSaOQ98V99H2/HEIlnCZylsDzfw7gtQUdwnRFiIyIxjbWy3iWsjwDPoXNPZBYg==", + "requires": { + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-requestmanager": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-core-helpers": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.37.tgz", + "integrity": "sha512-efaLOzN28RMnbugnyelgLwPWWaSwElQzcAJ/x3PZu+uPloM/lE5x0YuBKvIh7/PoSMlHqtRWj1B8CpuQOUQ5Ew==", + "requires": { + "underscore": "1.8.3", + "web3-eth-iban": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-core-method": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.37.tgz", + "integrity": "sha512-pKWFUeqnVmzx3VrZg+CseSdrl/Yrk2ioid/HzolNXZE6zdoITZL0uRjnsbqXGEzgRRd1Oe/pFndpTlRsnxXloA==", + "requires": { + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-promievent": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-core-promievent": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.37.tgz", + "integrity": "sha512-GTF2r1lP8nJBeA5Gxq5yZpJy9l8Fb9CXGZPfF8jHvaRdQHtm2Z+NDhqYmF833lcdkokRSyfPcXlz1mlWeClFpg==", + "requires": { + "any-promise": "1.3.0", + "eventemitter3": "1.1.1" + } + }, + "web3-core-requestmanager": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.37.tgz", + "integrity": "sha512-66VUqye5BGp1Zz1r8psCxdNH+GtTjaFwroum2Osx+wbC5oRjAiXkkadiitf6wRb+edodjEMPn49u7B6WGNuewQ==", + "requires": { + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37", + "web3-providers-http": "1.0.0-beta.37", + "web3-providers-ipc": "1.0.0-beta.37", + "web3-providers-ws": "1.0.0-beta.37" + } + }, + "web3-core-subscriptions": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.37.tgz", + "integrity": "sha512-FdXl8so9kwkRRWziuCSpFsAuAdg9KvpXa1fQlT16uoGcYYfxwFO/nkwyBGQzkZt7emShI2IRugcazyPCZDwkOA==", + "requires": { + "eventemitter3": "1.1.1", + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37" + } + }, + "web3-eth": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.37.tgz", + "integrity": "sha512-Eb3aGtkz3G9q+Z9DKgSQNbn/u8RtcZQQ0R4sW9hy5KK47GoT6vab5c6DiD3QWzI0BzitHzR5Ji+3VHf/hPUGgw==", + "requires": { + "underscore": "1.8.3", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-eth-abi": "1.0.0-beta.37", + "web3-eth-accounts": "1.0.0-beta.37", + "web3-eth-contract": "1.0.0-beta.37", + "web3-eth-ens": "1.0.0-beta.37", + "web3-eth-iban": "1.0.0-beta.37", + "web3-eth-personal": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-eth-abi": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.37.tgz", + "integrity": "sha512-g9DKZGM2OqwKp/tX3W/yihcj7mQCtJ6CXyZXEIZfuDyRBED/iSEIFfieDOd+yo16sokLMig6FG7ADhhu+19hdA==", + "requires": { + "ethers": "4.0.0-beta.1", + "underscore": "1.8.3", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-eth-accounts": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.37.tgz", + "integrity": "sha512-uvbHL62/zwo4GDmwKdqH9c/EgYd8QVnAfpVw8D3epSISpgbONNY7Hr4MRMSd/CqAP12l2Ls9JVQGLhhC83bW6g==", + "requires": { + "any-promise": "1.3.0", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.7", + "scrypt.js": "0.2.0", + "underscore": "1.8.3", + "uuid": "2.0.1", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "eth-lib": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", + "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" + } + } + }, + "web3-eth-contract": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.37.tgz", + "integrity": "sha512-h1B3A8Z/C7BlnTCHkrWbXZQTViDxfR12lKMeTkT8Sqj5phFmxrBlPE4ORy4lf1Dk5b23mZYE0r/IRACx4ThCrQ==", + "requires": { + "underscore": "1.8.3", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-promievent": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-eth-abi": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-eth-ens": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.37.tgz", + "integrity": "sha512-dR3UkrVzdRrJhfP57xBPx0CMiVnCcYFvh+u2XMkGydrhHgupSUkjqGr89xry/j1T0BkuN9mikpbyhdCVMXqMbg==", + "requires": { + "eth-ens-namehash": "2.0.8", + "underscore": "1.8.3", + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-promievent": "1.0.0-beta.37", + "web3-eth-abi": "1.0.0-beta.37", + "web3-eth-contract": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-eth-iban": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.37.tgz", + "integrity": "sha512-WQRniGJFxH/XCbd7miO6+jnUG+6bvuzfeufPIiOtCbeIC1ypp1kSqER8YVBDrTyinU1xnf1U5v0KBZ2yiWBJxQ==", + "requires": { + "bn.js": "4.11.6", + "web3-utils": "1.0.0-beta.37" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "web3-eth-personal": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.37.tgz", + "integrity": "sha512-B4dZpGbD+nGnn48i6nJBqrQ+HB7oDmd+Q3wGRKOsHSK5HRWO/KwYeA7wgwamMAElkut50lIsT9EJl4Apfk3G5Q==", + "requires": { + "web3-core": "1.0.0-beta.37", + "web3-core-helpers": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-explorer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/web3-explorer/-/web3-explorer-1.0.2.tgz", + "integrity": "sha512-CeaUVJVJBxX8nyblgchEo6EIl8snf+pq26vimiEz12IHvO2wTYXKWYH6fC3m3Mkp+fsdCQ6O24KIo8x92jO54w==" + }, + "web3-net": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.37.tgz", + "integrity": "sha512-xG/uBtMdDa1UMXw9KjDUgf3fXA/fDEJUYUS0TDn+U9PMgngA+UVECHNNvQTrVVDxEky38V3sahwIDiopNsQdsw==", + "requires": { + "web3-core": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-utils": "1.0.0-beta.37" + } + }, + "web3-providers-http": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.37.tgz", + "integrity": "sha512-FM/1YDB1jtZuTo78habFj7S9tNHoqt0UipdyoQV29b8LkGKZV9Vs3is8L24hzuj1j/tbwkcAH+ewIseHwu0DTg==", + "requires": { + "web3-core-helpers": "1.0.0-beta.37", + "xhr2-cookies": "1.1.0" + } + }, + "web3-providers-ipc": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.37.tgz", + "integrity": "sha512-NdRPRxYMIU0C3u18NI8u4bwbhI9pCg5nRgDGYcmSAx5uOBxiYcQy+hb0WkJRRhBoyIXJmy+s26FoH8904+UnPg==", + "requires": { + "oboe": "2.1.3", + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37" + } + }, + "web3-providers-ws": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.37.tgz", + "integrity": "sha512-8p6ZLv+1JYa5Vs8oBn33Nn3VGFBbF+wVfO+b78RJS1Qf1uIOzjFVDk3XwYDD7rlz9G5BKpxhaQw+6EGQ7L02aw==", + "requires": { + "underscore": "1.8.3", + "web3-core-helpers": "1.0.0-beta.37", + "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" + }, + "dependencies": { + "websocket": { + "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "from": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible", + "requires": { + "debug": "^2.2.0", + "nan": "^2.3.3", + "typedarray-to-buffer": "^3.1.2", + "yaeti": "^0.0.6" + } + } + } + }, + "web3-shh": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.37.tgz", + "integrity": "sha512-h5STG/xqZNQWtCLYOu7NiMqwqPea8SfkKQUPUFxXKIPVCFVKpHuQEwW1qcPQRJMLhlQIv17xuoUe1A+RzDNbrw==", + "requires": { + "web3-core": "1.0.0-beta.37", + "web3-core-method": "1.0.0-beta.37", + "web3-core-subscriptions": "1.0.0-beta.37", + "web3-net": "1.0.0-beta.37" + } + }, + "web3-utils": { + "version": "1.0.0-beta.37", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.37.tgz", + "integrity": "sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ==", + "requires": { + "bn.js": "4.11.6", + "eth-lib": "0.1.27", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randomhex": "0.1.5", + "underscore": "1.8.3", + "utf8": "2.1.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xhr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", + "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", + "requires": { + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", + "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", + "requires": { + "xhr-request": "^1.0.1" + } + }, + "xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "requires": { + "cookiejar": "^2.1.1" + } + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", + "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.11", + "yargs": "^12.0.5" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/package.json b/package.json index 57417f9aa..8b32edca9 100644 --- a/package.json +++ b/package.json @@ -1,35 +1,44 @@ { - "name": "EthereumClassicExplorer", - "private": false, + "name": "etc-explorer", "version": "0.2.0", "description": "A lightweight ethereum classic block explorer", - "repository": "https://github.com/ethereumproject/explorer", + "repository": "https://github.com/ethereumclassic/explorer", "license": "MIT", "scripts": { "start": "concurrently \"node tools/sync.js \" \"node app.js\" ", - "pretest": "copyfiles app.js app/ ", - "test": "mocha --exit" + "app": "node app.js", + "sync": "node tools/sync.js", + "stats": "node tools/stats.js", + "rich": "node tools/richlist.js", + "test": "mocha --exit", + "lint:check": "concurrently \"eslint *.js ./lib/*.js ./test/*.js ./test/units/*.js ./routes/*.js ./tools/*.js \" \"html-linter --config html-linter.json\" ", + "lint:fix": "eslint *.js ./lib/*.js ./test/*.js ./test/units/*.js ./routes/*.js ./tools/*.js --fix" }, "dependencies": { + "bignumber.js": "^8.1.1", + "body-parser": "^1.18.3", + "concurrently": "4.1.0", + "ejs": "2.6.1", + "express": "^4.16.4", + "human-standard-token-abi": "^2.0.0", + "mongoose": "^4.13.18", + "morgan": "^1.9.1", + "node-fetch": "^2.3.0", + "rlp": "^2.2.3", + "serve-favicon": "~2.5.0", + "solc": "^0.5.6", + "web3": "1.0.0-beta.37", + "web3-explorer": "1.0.2", "abi-decoder": "^1.1.0", - "bignumber.js": "^5.0.0", - "body-parser": "^1.12.2", - "concurrently": "^3.5.1", - "ejs": "~2.5.7", - "express": "^4.16.0", - "mongoose": "^4.10.8", - "morgan": "^1.9.0", - "rlp": "^2.0.0", - "serve-favicon": "~2.4.5", - "socket.io": "^2.0.4", - "solc": "^0.4.19", - "web3": "~0.19.0" + "socket.io": "^2.0.4" }, "devDependencies": { - "chai": "^4.1.2", - "copyfiles": "^1.2.0", - "ethereumjs-testrpc": "^6.0.3", - "mocha": "^4.1.0", - "request": "^2.83.0" + "chai": "^4.2.0", + "eslint": "^5.15.3", + "eslint-config-airbnb-base": "^13.1.0", + "eslint-plugin-import": "^2.16.0", + "html-linter": "^1.1.1", + "mocha": "^6.0.2", + "request": "^2.88.0" } } diff --git a/public/css/custom.css b/public/css/custom.css index 9acefc60f..0f145a73e 100755 --- a/public/css/custom.css +++ b/public/css/custom.css @@ -5,13 +5,13 @@ img.logo-default { } .create{background-color:#36c6d3} .truncate-txhash, .truncate-addrhash{ - white-space:nowrap; + white-space:nowrap; overflow:hidden; text-overflow: ellipsis; max-width:220px; } .truncate-addrhash { - max-width:200px; + max-width:200px; } .scrollable { max-height: 400px; @@ -20,7 +20,7 @@ img.logo-default { } #table_txs td, #table_internal_txs td { font-size: 12px; - white-space:nowrap; + white-space:nowrap; overflow:hidden; text-overflow: ellipsis; } @@ -34,6 +34,14 @@ img.logo-default { font-size: 25px; text-align: center; } +.eth-stat-title2 { + font-size: 20px; + text-align: center; +} +.eth-stat-subtitle { + font-size: 14px; + text-align: center; +} .eth-stat-text { color: #5b9bd1; font-size: 13px; @@ -53,7 +61,7 @@ img.logo-default { } .home-tx{ font-size: 12px; - white-space:nowrap; + white-space:nowrap; overflow:hidden; text-overflow: ellipsis; } @@ -81,7 +89,7 @@ pre { word-wrap: break-word; } pre.code-js, .verified{ - max-height: 200px; + max-height: 200px; } .code { font-family: Menlo,Monaco,Consolas,"Courier New",monospace; @@ -102,7 +110,7 @@ li.ng-scope { .table-scrollable { margin: 0 !important; } -@media(max-width: 487px) { +@media (max-width: 487px) { .container { margin: 0 !important; } @@ -130,4 +138,13 @@ li.ng-scope { ::-webkit-scrollbar-track { background-color: transparent; } -.page-spinner-bar{margin-top:-84px;margin-left:-98px;top:50%;left:50%;} \ No newline at end of file +@media (max-width: 480px) { + .page-header .page-header-top .top-menu .navbar-nav, + .search-form, .page-header .page-header-top .top-menu .navbar-nav>li.dropdown, + .page-header .search-form .input-group .form-control{width:100%;} + .search-form.open{width:100%!important;} +} +.page-spinner-bar{margin-top:-84px;margin-left:-98px;top:50%;left:50%;} +.mini-logo { + height: 1.2em; +} diff --git a/public/css/font-awesome.css b/public/css/font-awesome.css index 46958c5a0..ee906a819 100755 --- a/public/css/font-awesome.css +++ b/public/css/font-awesome.css @@ -1,28 +1,27 @@ /*! - * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* FONT PATH * -------------------------- */ @font-face { font-family: 'FontAwesome'; - src: url('../fonts/fontawesome/fontawesome-webfont.eot?v=4.0.3'); - src: url('../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('../fonts/fontawesome/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('../fonts/fontawesome/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('../fonts/fontawesome/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } .fa { display: inline-block; - font-family: FontAwesome; - font-style: normal; - font-weight: normal; - line-height: 1; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* makes the font 33% larger relative to the icon container */ .fa-lg { - font-size: 1.3333333333333333em; + font-size: 1.33333333em; line-height: 0.75em; vertical-align: -15%; } @@ -39,12 +38,12 @@ font-size: 5em; } .fa-fw { - width: 1.2857142857142858em; + width: 1.28571429em; text-align: center; } .fa-ul { padding-left: 0; - margin-left: 2.142857142857143em; + margin-left: 2.14285714em; list-style-type: none; } .fa-ul > li { @@ -52,19 +51,32 @@ } .fa-li { position: absolute; - left: -2.142857142857143em; - width: 2.142857142857143em; - top: 0.14285714285714285em; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; text-align: center; } .fa-li.fa-lg { - left: -1.8571428571428572em; + left: -1.85714286em; } .fa-border { padding: .2em .25em .15em; border: solid 0.08em #eeeeee; border-radius: .1em; } +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ .pull-right { float: right; } @@ -78,91 +90,70 @@ margin-left: .3em; } .fa-spin { - -webkit-animation: spin 2s infinite linear; - -moz-animation: spin 2s infinite linear; - -o-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } -@-moz-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - } - 100% { - -moz-transform: rotate(359deg); - } +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } -@-webkit-keyframes spin { +@-webkit-keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); + transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } -@-o-keyframes spin { - 0% { - -o-transform: rotate(0deg); - } - 100% { - -o-transform: rotate(359deg); - } -} -@-ms-keyframes spin { - 0% { - -ms-transform: rotate(0deg); - } - 100% { - -ms-transform: rotate(359deg); - } -} -@keyframes spin { +@keyframes fa-spin { 0% { + -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { + -webkit-transform: rotate(359deg); transform: rotate(359deg); } } .fa-rotate-90 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; -webkit-transform: rotate(90deg); - -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); - -o-transform: rotate(90deg); transform: rotate(90deg); } .fa-rotate-180 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; -webkit-transform: rotate(180deg); - -moz-transform: rotate(180deg); -ms-transform: rotate(180deg); - -o-transform: rotate(180deg); transform: rotate(180deg); } .fa-rotate-270 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; -webkit-transform: rotate(270deg); - -moz-transform: rotate(270deg); -ms-transform: rotate(270deg); - -o-transform: rotate(270deg); transform: rotate(270deg); } .fa-flip-horizontal { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; -webkit-transform: scale(-1, 1); - -moz-transform: scale(-1, 1); -ms-transform: scale(-1, 1); - -o-transform: scale(-1, 1); transform: scale(-1, 1); } .fa-flip-vertical { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; -webkit-transform: scale(1, -1); - -moz-transform: scale(1, -1); -ms-transform: scale(1, -1); - -o-transform: scale(1, -1); transform: scale(1, -1); } +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} .fa-stack { position: relative; display: inline-block; @@ -228,6 +219,8 @@ .fa-check:before { content: "\f00c"; } +.fa-remove:before, +.fa-close:before, .fa-times:before { content: "\f00d"; } @@ -369,6 +362,8 @@ .fa-video-camera:before { content: "\f03d"; } +.fa-photo:before, +.fa-image:before, .fa-picture-o:before { content: "\f03e"; } @@ -555,7 +550,8 @@ .fa-arrows-h:before { content: "\f07e"; } -.fa-bar-chart-o:before { +.fa-bar-chart-o:before, +.fa-bar-chart:before { content: "\f080"; } .fa-twitter-square:before { @@ -631,6 +627,7 @@ .fa-twitter:before { content: "\f099"; } +.fa-facebook-f:before, .fa-facebook:before { content: "\f09a"; } @@ -643,6 +640,7 @@ .fa-credit-card:before { content: "\f09d"; } +.fa-feed:before, .fa-rss:before { content: "\f09e"; } @@ -732,6 +730,8 @@ .fa-square:before { content: "\f0c8"; } +.fa-navicon:before, +.fa-reorder:before, .fa-bars:before { content: "\f0c9"; } @@ -791,11 +791,11 @@ content: "\f0dc"; } .fa-sort-down:before, -.fa-sort-asc:before { +.fa-sort-desc:before { content: "\f0dd"; } .fa-sort-up:before, -.fa-sort-desc:before { +.fa-sort-asc:before { content: "\f0de"; } .fa-envelope:before { @@ -985,12 +985,10 @@ .fa-code:before { content: "\f121"; } +.fa-mail-reply-all:before, .fa-reply-all:before { content: "\f122"; } -.fa-mail-reply-all:before { - content: "\f122"; -} .fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before { @@ -1280,7 +1278,8 @@ .fa-male:before { content: "\f183"; } -.fa-gittip:before { +.fa-gittip:before, +.fa-gratipay:before { content: "\f184"; } .fa-sun-o:before { @@ -1336,3 +1335,1003 @@ .fa-plus-square-o:before { content: "\f196"; } +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/public/css/fonts/fontawesome-webfont.ttf b/public/css/fonts/fontawesome-webfont.ttf index 96a3639cd..35acda2fa 100644 Binary files a/public/css/fonts/fontawesome-webfont.ttf and b/public/css/fonts/fontawesome-webfont.ttf differ diff --git a/public/css/fonts/fontawesome-webfont.woff b/public/css/fonts/fontawesome-webfont.woff index 628b6a52a..400014a4b 100644 Binary files a/public/css/fonts/fontawesome-webfont.woff and b/public/css/fonts/fontawesome-webfont.woff differ diff --git a/public/fonts/fontawesome/FontAwesome.otf b/public/fonts/fontawesome/FontAwesome.otf index 8b0f54e47..401ec0f36 100755 Binary files a/public/fonts/fontawesome/FontAwesome.otf and b/public/fonts/fontawesome/FontAwesome.otf differ diff --git a/public/fonts/fontawesome/fontawesome-webfont.eot b/public/fonts/fontawesome/fontawesome-webfont.eot index 7c79c6a6b..e9f60ca95 100755 Binary files a/public/fonts/fontawesome/fontawesome-webfont.eot and b/public/fonts/fontawesome/fontawesome-webfont.eot differ diff --git a/public/fonts/fontawesome/fontawesome-webfont.svg b/public/fonts/fontawesome/fontawesome-webfont.svg index 45fdf3383..855c845e5 100755 --- a/public/fonts/fontawesome/fontawesome-webfont.svg +++ b/public/fonts/fontawesome/fontawesome-webfont.svg @@ -1,414 +1,2671 @@ - - + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/fonts/fontawesome/fontawesome-webfont.ttf b/public/fonts/fontawesome/fontawesome-webfont.ttf index e89738de5..35acda2fa 100755 Binary files a/public/fonts/fontawesome/fontawesome-webfont.ttf and b/public/fonts/fontawesome/fontawesome-webfont.ttf differ diff --git a/public/fonts/fontawesome/fontawesome-webfont.woff b/public/fonts/fontawesome/fontawesome-webfont.woff index 8c1748aab..400014a4b 100755 Binary files a/public/fonts/fontawesome/fontawesome-webfont.woff and b/public/fonts/fontawesome/fontawesome-webfont.woff differ diff --git a/public/img/etc-mini-logo.svg b/public/img/etc-mini-logo.svg new file mode 100644 index 000000000..2c272644b --- /dev/null +++ b/public/img/etc-mini-logo.svg @@ -0,0 +1,289 @@ + + + + + Ethereum Classic Logo + + + + + + image/svg+xml + + Ethereum Classic Logo + + + + Ethereum Classic + + + + + Ethereum Classic + + + + + Ethereum Classic + + + Ethereum Classic Logo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/js/controllers/AddressController.js b/public/js/controllers/AddressController.js index 280f7f9ea..5347a6ccc 100755 --- a/public/js/controllers/AddressController.js +++ b/public/js/controllers/AddressController.js @@ -31,16 +31,6 @@ angular.module('BlocksApp').controller('AddressController', function($stateParam fetchInternalTxs(); }); - // fetch ethf balance - if ($scope.settings.useEthFiat) - $http({ - method: 'POST', - url: '/fiat', - data: {"addr": $scope.addrHash} - }).then(function(resp) { - $scope.addr.ethfiat = resp.data.balance; - }); - //fetch transactions var fetchTxs = function() { var table = $("#table_txs").DataTable({ @@ -84,7 +74,7 @@ angular.module('BlocksApp').controller('AddressController', function($stateParam [10, 20, 50, 100, 150, 500], [10, 20, 50, 100, 150, 500] // change per page values here ], - "pageLength": 20, + "pageLength": 20, "order": [ [6, "desc"] ], @@ -94,7 +84,7 @@ angular.module('BlocksApp').controller('AddressController', function($stateParam "infoEmpty": ":(", "infoFiltered": "(filtered from _MAX_ total txs)" }, - "columnDefs": [ + "columnDefs": [ { "targets": [ 5 ], "visible": false, "searchable": false }, {"type": "date", "targets": 6}, {"orderable": false, "targets": [0,2,3,4]}, @@ -149,7 +139,6 @@ angular.module('BlocksApp').controller('AddressController', function($stateParam }); }; $scope.fetchInternalTxs = fetchInternalTxs; - }) .directive('contractSource', function($http) { return { diff --git a/public/js/controllers/DAOController.js b/public/js/controllers/DAOController.js deleted file mode 100755 index 067a1204f..000000000 --- a/public/js/controllers/DAOController.js +++ /dev/null @@ -1,100 +0,0 @@ -angular.module('BlocksApp').controller('DAOController', function($stateParams, $rootScope, $scope, $http, $location) { - $scope.$on('$viewContentLoaded', function() { - // initialize core components - App.initAjax(); - }); - var activeTab = $location.url().split('#'); - if (activeTab.length > 1) - $scope.activeTab = activeTab[1]; - - $scope.settings = $rootScope.setup; - $scope.dao = {"balance": 0, "extra_balance": 0}; - - //fetch dao stuff - $http({ - method: 'POST', - url: '/daorelay', - data: {"action": "info"} - }).then(function(resp) { - $scope.dao = resp.data; - }); - - $scope.form = {}; - $scope.errors = {}; - $scope.showTokens = false; - $scope.getBalance = function(a) { - var addr = a.toLowerCase(); - - $scope.form.addrInput=""; - $scope.errors = {}; - - $scope.form.tokens.$setPristine(); - $scope.form.tokens.$setUntouched(); - if (isAddress(addr)) { - $http({ - method: 'POST', - url: '/daorelay', - data: {"action": "balanceOf", "addr": addr} - }).then(function(resp) { - console.log(resp.data) - $scope.showTokens = true; - $scope.dao.tokens = resp.data.tokens; - }); - } else - $scope.errors.address = "Invalid Address"; - - } - -}) -.directive('createdTokens', function($http) { - return { - restrict: 'E', - templateUrl: '/views/created-tokens.html', - scope: false, - link: function(scope, elem, attrs){ - // fetch created tokens - scope.getCreatedTokens = function(last) { - var data = {"action": "createdTokens"}; - if (last) - data.last_id = last; - - $http({ - method: 'POST', - url: '/daorelay', - data: data - }).then(function(resp) { - scope.created_tokens = resp.data; - }); - } - - scope.getCreatedTokens(); - } - - } -}) -.directive('transferTokens', function($http) { - return { - restrict: 'E', - templateUrl: '/views/transfer-tokens.html', - scope: false, - link: function(scope, elem, attrs){ - // fetch created tokens - scope.getTransferTokens = function(last) { - var data = {"action": "transferTokens"}; - if (last) - data.last_id = last; - - $http({ - method: 'POST', - url: '/daorelay', - data: data - }).then(function(resp) { - scope.transfer_tokens = resp.data; - }); - } - - scope.getTransferTokens(); - } - - } -}) diff --git a/public/js/controllers/HomeController.js b/public/js/controllers/HomeController.js index 7e79eb58a..847e511b5 100755 --- a/public/js/controllers/HomeController.js +++ b/public/js/controllers/HomeController.js @@ -60,43 +60,4 @@ angular.module('BlocksApp').controller('HomeController', function($rootScope, $s restrict: 'E', templateUrl: '/views/site-notes.html' } -}) -//OLD CODE DONT USE -.directive('summaryStats', function($http) { - return { - restrict: 'E', - templateUrl: '/views/summary-stats.html', - scope: true, - link: function(scope, elem, attrs){ - scope.stats = {}; - - var etcEthURL = "/stats"; - var etcPriceURL = "https://api.coinmarketcap.com/v1/ticker/ethereum-classic/"; - var ethPriceURL = "https://api.coinmarketcap.com/v1/ticker/ethereum/" - scope.stats.ethDiff = 1; - scope.stats.ethHashrate = 1; - scope.stats.usdEth = 1; - $http.post(etcEthURL, {"action": "etceth"}) - .then(function(res){ - scope.stats.etcHashrate = res.data.etcHashrate; - scope.stats.ethHashrate = res.data.ethHashrate; - scope.stats.etcEthHash = res.data.etcEthHash; - scope.stats.ethDiff = res.data.ethDiff; - scope.stats.etcDiff = res.data.etcDiff; - scope.stats.etcEthDiff = res.data.etcEthDiff; - }); - $http.get(etcPriceURL) - .then(function(res){ - scope.stats.usdEtc = parseFloat(res.data[0]["price_usd"]); - scope.stats.usdEtcEth = parseInt(100*scope.stats.usdEtc/scope.stats.usdEth); - }); - $http.get(ethPriceURL) - .then(function(res){ - scope.stats.usdEth = parseFloat(res.data[0]["price_usd"]); - scope.stats.usdEtcEth = parseInt(100*scope.stats.usdEtc/scope.stats.usdEth); - scope.stats.ethChange = parseFloat(res.data.change); - }); - - } - } }); diff --git a/public/js/controllers/StatsController.js b/public/js/controllers/StatsController.js index 5fc5b2582..3196d492e 100755 --- a/public/js/controllers/StatsController.js +++ b/public/js/controllers/StatsController.js @@ -2,16 +2,16 @@ angular.module('BlocksApp').controller('StatsController', function($stateParams, $rootScope.isHome = false; $scope.settings = $rootScope.setup; - + /* - Chart types: + Chart types: hashrate: Hashrate Growth miner_hashrate: Miner Hashrate Distribution */ const CHART_TYPES = { "hashrate": { - "title": "Hashrate Growth" + "title": "Hashrate chart" }, "blocktime": { "title": "Blocktime chart" @@ -20,10 +20,7 @@ angular.module('BlocksApp').controller('StatsController', function($stateParams, "title": "Difficulty chart" }, "miner_hashrate": { - "title": "Miner Hashrate Distribution" - }, - "The_bomb_chart": { - "title": "The bomb chart" + "title": "Miner distribution" } } @@ -895,969 +892,6 @@ angular.module('BlocksApp').controller('StatsController', function($stateParams, // arg1 now equals 'three' callback(null, 'done'); } - } - } - } -}) -.directive('etcTheBombChartOrig', function($http) { - return { - restrict: 'E', - template: '', - scope: true, - link: function(scope, elem, attrs) { - $http.post("/stats", {"action": "hashrates"}) - .then(function(res) { - //console.log(res.data); - - scope.init(res.data, '#bombchart'); - }); - - /** - * Created by chenxiangyu on 2016/8/5. - */ - scope.init = function(dataset, chartid) { - async.waterfall([ - myFirstFunction, - mySecondFunction, - myLastFunction - ], function (err, result) { - // result now equals 'done' - //console.log("all done1"); - - return result; - }); - - function myFirstFunction(callback) { - /* - request('http://drawpie.com/etc_hash_rate_api', function (error, response, body) { - if (!error && response.statusCode == 200) { - - var hashrate = JSON.parse(body); - //console.log(hashrate); - callback(null, hashrate, 'two'); - } - }); - */ - - callback(null, dataset, 'two'); - //callback(null, 'one', 'two'); - } - - function mySecondFunction(arg1, arg2, callback) { - // arg1 now equals 'one' and arg2 now equals 'two' - - //console.log(112); - //console.log(arg1); - var day = moment("2016-08-10"); - - var bomb_array =[]; - for(i=2000000;i<4500000;i = i +50000){ - console.log(i); - //Math.pow(2, (block_number/100000)-2); - console.log(Math.pow(2, (i/100000)-2)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000)-2)+8000000000000}); - - day.add(14*50000, 's'); - //console.log(day.format()) - } - - //console.log(bomb_array); - - - //console.log(window.screen.availWidth); - var width1 = parseInt(d3.select(chartid).style("width")); - - var margin = {top: 0, right: 50, bottom: 50, left: 100}, - //var margin = {top: 30, right: 0, bottom: 0, left: 0}, - // For Responsive web design, get window.innerWidth - //width = window.innerWidth - margin.left - margin.right, - width = width1 - margin.left - margin.right, - //width = window.screen.availWidth - margin.left - margin.right, - height = 400 - margin.top - margin.bottom; - - var x = d3.time.scale().range([0, width]); - var y = d3.scale.linear().range([height, 0]); - - // For Responsive web design - //When window.innerWidth < 800 , Reduce the ticks to 2 - - - var xAxis = d3.svg.axis() - .scale(x) - .orient("bottom") - //.tickFormat(d3.time.format("%x %H:%M")) - .tickFormat(d3.time.format("%x")) - .ticks(8); - - - var yAxis = d3.svg.axis() - .scale(y) - .orient("left") - .tickFormat(d3.format("s")) - .tickFormat(function(d){return d3.format("s")(d) +'H/s';}) - .ticks(5); - - - var area = d3.svg.area() - .x(function(d) { return x(d.timestamp*1000); }) - .y0(height) - .y1(function(d) { return y(d.difficulty); }); - - var valueline = d3.svg.line() - .x(function(d) { return x(d.timestamp*1000); }) - .y(function(d) { return y(d.difficulty); }); - - /* - var valueline_bomb = d3.svg.line() - .x(function(d) { return x(d.Date*1000); }) - .y(function(d) { return y(d.Value); }); - */ - - var svg = d3.select(chartid) - //.append("svg") - .attr("width", width + margin.left + margin.right) - - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", - "translate(" + margin.left + "," + margin.top + ")"); - - - - - - // function for the x grid lines - function make_x_axis() { - return d3.svg.axis() - .scale(x) - .orient("bottom") - .ticks(8) - } - - // function for the y grid lines - function make_y_axis() { - return d3.svg.axis() - .scale(y) - .orient("left") - .ticks(8) - } - - - - var data = arg1.hashrates; - - // Scale the range of the data - //x.domain(d3.extent(data, function(d) { return d.timestamp*1000; })); - x.domain([1470009600*1000,1504224000*1000]); - y.domain([d3.min(data, function(d) { return d.difficulty; }), d3.max(data, function(d) { return d.difficulty; })]); - - // Add the filled area - svg.append("path") - .datum(data) - .attr("class", "area") - .attr("d", area); - - // Draw the x Grid lines - svg.append("g") - .attr("class", "grid") - .attr("transform", "translate(0," + height + ")") - .call(make_x_axis() - .tickSize(-height, 0, 0) - .tickFormat("") - ); - - // Draw the y Grid lines - svg.append("g") - .attr("class", "grid") - .call(make_y_axis() - .tickSize(-width, 0, 0) - .tickFormat("") - ); - - // Add the valueline path. - svg.append("path") - .attr("d", valueline(data)); - - svg.selectAll("circle") - .data(bomb_array) - .enter() - .append("circle") - .attr("cx", function (d) { return x(new Date(d.Date*1000)) }) - .attr("cy", function (d) { return y(d.Value); }) - .attr("r", function (d) { return 3; }) - .style("fill", function(d) { - if(d.Value < 8250000000000){ - return "black"; - } - else{ - return "red"; - } - - - }); - - // Add the X Axis - svg.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + height + ")") - .call(xAxis); - - // Add the Y Axis - svg.append("g") - .attr("class", "y axis") - .call(yAxis); - - - - // Add Tooltip - var focus = svg.append("g") - .attr("class", "focus") - .style("display", "none"); - - focus.append("circle") - .attr("r", 4.5); - - focus.append("text") - .attr("x", 9) - .attr("dy", ".35em"); - - - svg.append("rect") - .attr("class", "overlay") - .attr("width", width) - .attr("height", height) - .on("mouseover", function() { focus.style("display", null); }) - .on("mouseout", function() { focus.style("display", "none"); }) - .on("mousemove", mousemove); - - - function mousemove() { - var x0 = x.invert(d3.mouse(this)[0]); - //console.log(moment(x0).unix()); - - - var s1 = _.minBy(data, function(d) { - //console.log(d.unixtime); - return Math.abs(moment(x0).unix()-d.unixtime); - }); - - //console.log(moment(s1.unixtime*1000).format()); - //console.log(s1.instantHashrate); - - - - //focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")"); - focus.attr("transform", "translate(" + x(moment(x0).unix()*1000) + "," + y(s1.difficulty) + ")"); - } - - - - - callback(null, 'three'); - } - - function myLastFunction(arg1, callback) { - // arg1 now equals 'three' - callback(null, 'done'); - } - - - } - } - } -}) -.directive('etcTheBombChart', function($http) { - return { - restrict: 'E', - template: '', - scope: true, - link: function(scope, elem, attrs) { - $http.post("/stats", {"action": "hashrates", "range": 12 * 30 * 24 * 60 * 60 }) - .then(function(res) { - //console.log(res.data); - - res.data.hashrates.forEach(function(d) { d.difficulty = d.difficulty / d.blockTime; }); // FIXME - scope.init(res.data, '#bombchartwithecip1010'); - }); - - /** - * Created by chenxiangyu on 2016/8/5. - */ - scope.init = function(dataset, chartid) { - async.waterfall([ - myFirstFunction, - get_ave_block_time, - mySecondFunction, - myLastFunction - ], function (err, result) { - // result now equals 'done' - //console.log("all done1"); - - return result; - }); - - function myFirstFunction(callback) { - - /* - request('http://drawpie.com/etc_hash_rate_api', function (error, response, body) { - if (!error && response.statusCode == 200) { - - var hashrate = JSON.parse(body); - //console.log(hashrate); - callback(null, hashrate); - } - }); - */ - //callback(null, hashrate); - callback(null, dataset); - - - - //callback(null, 'one', 'two'); - } - - function get_ave_block_time(arg1, callback) { - - - /* - request('http://drawpie.com/etc_avg_block_time', function (error, response, body) { - if (!error && response.statusCode == 200) { - - var ave_block_time = JSON.parse(body); - //console.log(hashrate); - callback(null, arg1, ave_block_time); - } - }); - */ - //callback(null, arg1, ave_block_time); - callback(null, arg1, 'three'); - - - - //callback(null, 'one', 'two'); - } - - function mySecondFunction(arg1, arg2, callback) { - // arg1 now equals 'one' and arg2 now equals 'two' - - //console.log(112); - //console.log(arg2.base_diff); - //console.log(arg2.etc_avg_block_time[0].array); - ////var ave_block_time_array = arg2.etc_avg_block_time[0].array; - ////ave_block_time_array.reverse(); - ////var ave_block_time_array_sliced = _.slice(ave_block_time_array,0,15); - //console.log(ave_block_time_array_sliced); - - ////var ave_block_time_array_sliced_lodashed = _.meanBy(ave_block_time_array_sliced, function(d) { return d.avg_block_time; }); - var ave_block_time_array_sliced_lodashed = _.meanBy(arg1.hashrates, function(d) { return d.blockTime; }); // FIXME - //console.log("ave_block_time_array_sliced_lodashed"); - //console.log(ave_block_time_array_sliced_lodashed); - - var start_count_block = 2250000; // 1473790866 - var day = moment.unix(1473790866); - var day_with_ECIP_1010 = moment.unix(1473790866); - - // var day = moment("2016-08-10"); - //var day_with_ECIP_1010 = moment("2016-08-10"); - - var bomb_array =[]; - var bomb_array_with_ECIP_1010 =[]; - - //var base_diff = arg2.base_diff; - var base_diff = 7580000000000.00; // FIXME - - - - for(i=start_count_block;i<4500000;i = i +50000){ - //console.log(i); - //Math.pow(2, (block_number/100000)-2); - //console.log(Math.pow(2, (i/100000)-2)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - - switch (true) { - case (i<3000000): - - - //console.log(i); - //Math.pow(2, (block_number/100000)-2); - //console.log(Math.pow(2, (i/100000)-2)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - bomb_array.push({ - Date :day.unix(), - Value : Math.pow(2, (i/100000)-2)+base_diff, - number : i - }); - - break; - - case (i>=3000000): - - if (i == 3000000){ - //console.log("Block 3000000 time "); - //console.log(day.format()); - } - //console.log(i); - //Math.pow(2, (block_number/100000)-2); - //console.log(Math.pow(2, 28)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - bomb_array.push({ - Date :day.unix(), - Value : Math.pow(2, (i/100000)-2)+base_diff+100000000000, - number : i - }); - - break; - - } - - /* - bomb_array.push({ - Date :day.unix(), - Value : Math.pow(2, (i/100000)-2)+base_diff, - number : i - }); - */ - - day.add(ave_block_time_array_sliced_lodashed*50000, 's'); - //console.log(day.format()) - } - - for(i=start_count_block;i<6500000;i = i +50000){ - - - //console.log(1123); - - switch (true) { - case (i<3000000): - day = "Sunday"; - - //console.log(i); - //Math.pow(2, (block_number/100000)-2); - //console.log(Math.pow(2, (i/100000)-2)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - bomb_array_with_ECIP_1010.push({ - Date :day_with_ECIP_1010.unix(), - Value : Math.pow(2, (i/100000)-2)+base_diff, - number : i - }); - - break; - - case (i>=3000000 && i<5000000 ): - day = "Monday"; - - //console.log(i); - //Math.pow(2, (block_number/100000)-2); - //console.log(Math.pow(2, 28)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - bomb_array_with_ECIP_1010.push({ - Date :day_with_ECIP_1010.unix(), - Value : Math.pow(2, 28)+base_diff-100000000000, - number : i - }); - - break; - - case (i>=5000000): - day = "Monday"; - - //console.log(i); - //Math.pow(2, (block_number/100000)-2); - //console.log(Math.pow(2, (i/100000)-2-20)); - - //bomb_array.push({Date :day.unix(), Value : Math.pow(2, (i/100000000000)-2) + 10677580591563}); - bomb_array_with_ECIP_1010.push({ - Date :day_with_ECIP_1010.unix(), - Value : Math.pow(2, (i/100000)-2-20)+base_diff-100000000000, - number : i - }); - - break; - - } - - - - day_with_ECIP_1010.add(ave_block_time_array_sliced_lodashed*50000, 's'); - //console.log(day.format()) - } - - - //console.log(bomb_array); - - - //console.log(window.screen.availWidth); - var width1 = parseInt(d3.select(chartid).style("width")); - - var margin = {top: 0, right: 50, bottom: 50, left: 100}, - //var margin = {top: 30, right: 0, bottom: 0, left: 0}, - // For Responsive web design, get window.innerWidth - //width = window.innerWidth - margin.left - margin.right, - width = width1 - margin.left - margin.right, - //width = window.screen.availWidth - margin.left - margin.right, - height = 400 - margin.top - margin.bottom; - - // FIXME - if (width < 0) { - width = 1000; - } - - var x = d3.time.scale().range([0, width]); - var y = d3.scale.linear().range([height, 0]); - - // For Responsive web design - //When window.innerWidth < 800 , Reduce the ticks to 2 - - - var xAxis = d3.svg.axis() - .scale(x) - .orient("bottom") - //.tickFormat(d3.time.format("%x %H:%M")) - .tickFormat(d3.time.format("%x")) - .ticks(8); - - - var yAxis = d3.svg.axis() - .scale(y) - .orient("left") - .tickFormat(d3.format("s")) - .tickFormat(function(d){return d3.format("s")(d) +'H/s';}) - .ticks(5); - - - var area = d3.svg.area() - .x(function(d) { return x(d.timestamp*1000); }) - .y0(height) - .y1(function(d) { return y(d.difficulty); }); - - var valueline = d3.svg.line() - .x(function(d) { return x(d.timestamp*1000); }) - .y(function(d) { return y(d.difficulty); }); - - - var valueline_bomb = d3.svg.line() - .x(function(d) { return x(d.Date*1000); }) - .y(function(d) { return y(d.Value); }); - - var valueline_bomb_with_ECIP_1010 = d3.svg.line() - .x(function(d) { return x(d.Date*1000); }) - .y(function(d) { return y(d.Value); }); - - - - - var svg = d3.select(chartid) - //.append("svg") - .attr("width", width + margin.left + margin.right) - - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", - "translate(" + margin.left + "," + margin.top + ")"); - - - - - - // function for the x grid lines - function make_x_axis() { - return d3.svg.axis() - .scale(x) - .orient("bottom") - .ticks(8) - } - - // function for the y grid lines - function make_y_axis() { - return d3.svg.axis() - .scale(y) - .orient("left") - .ticks(8) - } - - - - var data = arg1.hashrates; - - // Scale the range of the data - //x.domain(d3.extent(data, function(d) { return d.timestamp*1000; })); - //x.domain([1470009600*1000,1504224000*1000]); - x.domain([1470009600*1000,1535760000*1000]); - y.domain([d3.min(data, function(d) { return d.difficulty; }), d3.max(data, function(d) { return d.difficulty; })]); - - // Add the filled area - svg.append("path") - .datum(data) - .attr("class", "area") - .attr("d", area); - - // Draw the x Grid lines - svg.append("g") - .attr("class", "grid") - .attr("transform", "translate(0," + height + ")") - .call(make_x_axis() - .tickSize(-height, 0, 0) - .tickFormat("") - ); - - // Draw the y Grid lines - svg.append("g") - .attr("class", "grid") - .call(make_y_axis() - .tickSize(-width, 0, 0) - .tickFormat("") - ); - - // Add the valueline path. - svg.append("path") - .attr("d", valueline(data)); - - svg.append("path") - .attr("d", valueline_bomb(bomb_array)); - - svg.append("path") - .attr("d", valueline_bomb_with_ECIP_1010(bomb_array_with_ECIP_1010)); - - - - - svg.selectAll("circle") - .data(bomb_array) - .enter() - .append("circle") - .attr("cx", function (d) { return x(new Date(d.Date*1000)) }) - .attr("cy", function (d) { - - if(d.number < 3000000){ - return y(d.Value); - } - else{ - return y(d.Value); - } - //return y(d.Value)-10; - - }) - .attr("r", function (d) { return 3; }) - .style("fill", function(d) { - /* - if(d.Value < 8250000000000){ - return "black"; - } - else{ - return "red"; - } - */ - return "red"; - - }); - - svg.selectAll("circle_with_ECIP_1010") - .data(bomb_array_with_ECIP_1010) - .enter() - .append("circle") - .attr("cx", function (d) { return x(new Date(d.Date*1000)) }) - .attr("cy", function (d) { - - if(d.number < 3000000){ - return y(d.Value); - } - else{ - return y(d.Value); - } - //return y(d.Value)-10; - - }) - .attr("r", function (d) { return 3; }) - .style("fill", function(d) { - - if(d.number < 3000000){ - return "red"; - } - else{ - return "green"; - } - - }); - - // Add the X Axis - svg.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + height + ")") - .call(xAxis); - - // Add the Y Axis - svg.append("g") - .attr("class", "y axis") - .call(yAxis); - - //append label - svg.append("rect") - .attr("x", 50) - .attr("y", 10) - .style("fill","lightsteelblue") - .attr("stroke-width", 2) - .attr("stroke", "steelblue") - .attr("width", 10) - .attr("height", 10); - - //console.log(_.last(arg1.etc_hashrate).difficulty); - //console.log(d3.format(".3s")(_.last(arg1.etc_hashrate).difficulty)); - //d3.format("s")(d) +'H/s' - //console.log(_.last(arg1.etc_hashrate).unixtime); - - - svg.append("text") - .attr("x", 70) - .attr("y", 10) - .text("Current difficulty : " + d3.format(".3s")(_.last(arg1.hashrates).difficulty)+" , " +new Date(_.last(arg1.hashrates).unixtime*1000)) - //.attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - svg.append("circle") - .attr("cx", 50+4) - .attr("cy", 10+30) - .style("fill","red") - .attr("r", 5); - - svg.append("text") - .attr("x", 50+20) - .attr("y", 35) - .text("Prediction of future difficulty, without ECIP-1010") - //.attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - svg.append("circle") - .attr("cx", 50+4) - .attr("cy", 10+30+25) - .style("fill","green") - .attr("r", 5); - - svg.append("text") - .attr("x", 50+20) - .attr("y", 35+25) - .text("Prediction of future difficulty, with ECIP-1010") - //.attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - //add mark - - //console.log(bomb_array_with_ECIP_1010); - - - var block_3000000_time = _.find(bomb_array_with_ECIP_1010, function(d) { return d.number == 3000000; }); - - //console.log(block_3000000_time); - //console.log(block_3000000_time.Date); - - svg.append("line") - .attr("x1", x(new Date(_.last(arg1.hashrates).unixtime*1000))+10) - .attr("y1", 0+270) - .attr("x2", x(new Date(_.last(arg1.hashrates).unixtime*1000))+10) - .attr("y2", 10+270) - .attr("stroke-width", 1) - .attr("stroke", "black"); - - svg.append("line") - .attr("x1", x(new Date(block_3000000_time.Date*1000))) - .attr("y1", 0+270) - .attr("x2", x(new Date(block_3000000_time.Date*1000))) - .attr("y2", 10+270) - .attr("stroke-width", 1) - //.style("stroke-dasharray", ("3, 3")) - .attr("stroke", "black"); - - svg.append("line") - .attr("x1", x(new Date(block_3000000_time.Date*1000))) - .attr("y1", 0+270-80) - .attr("x2", x(new Date(block_3000000_time.Date*1000))) - .attr("y2", 10+270) - .attr("stroke-width", 1) - .style("stroke-dasharray", ("3, 3")) - .attr("stroke", "black"); - - svg.append("text") - .attr("x", x(new Date(block_3000000_time.Date*1000))) - //.attr("x", x(new Date(_.last(arg1.etc_hashrate).unixtime*1000))+10) - .attr("y", 0+260-80-10-15) - .text("ECIP-1010 Deploy, Block 3000000") - .attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - svg.append("text") - .attr("x", x(new Date(block_3000000_time.Date*1000))) - //.attr("x", x(new Date(_.last(arg1.etc_hashrate).unixtime*1000))+10) - .attr("y", 0+260-80-10) - .text(new Date(block_3000000_time.Date*1000)+" (expected)") - .attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - - - svg.append("line") - .attr("x1", x(new Date(_.last(arg1.hashrates).unixtime*1000))+10) - .attr("y1", 5+270) - .attr("x2", x(new Date(block_3000000_time.Date*1000))) - .attr("y2", 5+270) - .attr("stroke-width", 1) - .attr("stroke", "black"); - - var duration = block_3000000_time.Date - _.last(arg1.hashrates).unixtime; - //console.log(duration); - //console.log(moment.duration(duration, 'seconds').humanize()); - - - - svg.append("text") - .attr("x", x(new Date(( duration/2 + _.last(arg1.hashrates).unixtime ) *1000))+0) - //.attr("x", x(new Date(_.last(arg1.etc_hashrate).unixtime*1000))+10) - .attr("y", 0+260) - .text(moment.duration(duration, 'seconds').humanize()) - .attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - - var block_4000000_time = _.find(bomb_array_with_ECIP_1010, function(d) { return d.number == 4000000; }); - - var duration_30_40 = block_4000000_time.Date - block_3000000_time.Date; - //console.log(duration_30_40); - //console.log(moment.duration(duration_30_40, 'seconds').humanize()); - - svg.append("line") - .attr("x1", x(new Date(block_3000000_time.Date*1000))) - .attr("y1", 5+270) - .attr("x2", x(new Date(block_4000000_time.Date*1000))) - .attr("y2", 5+270) - .attr("stroke-width", 1) - .attr("stroke", "black"); - - //((block_4000000_time.Date-block_3000000_time.Date)/2+block_3000000_time.Date) - - svg.append("text") - .attr("x", x(new Date(((block_4000000_time.Date-block_3000000_time.Date)/2+block_3000000_time.Date)*1000))) - .attr("y", 0+260) - .text(moment.duration(duration_30_40, 'seconds').humanize()) - .attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - svg.append("line") - .attr("x1", x(new Date(block_4000000_time.Date*1000))) - .attr("y1", 0+270) - .attr("x2", x(new Date(block_4000000_time.Date*1000))) - .attr("y2", 10+270) - .attr("stroke-width", 1) - .attr("stroke", "black"); - - - var block_6000000_time = _.find(bomb_array_with_ECIP_1010, function(d) { return d.number == 6000000; }); - - var duration_40_60 = block_6000000_time.Date - block_4000000_time.Date; - //console.log(duration_40_60); - //console.log(moment.duration(duration_40_60, 'seconds').humanize()); - - svg.append("line") - .attr("x1", x(new Date(block_4000000_time.Date*1000))) - .attr("y1", 5+270) - .attr("x2", x(new Date(block_6000000_time.Date*1000))) - .attr("y2", 5+270) - .attr("stroke-width", 1) - .attr("stroke", "black"); - - svg.append("line") - .attr("x1", x(new Date(block_6000000_time.Date*1000))) - .attr("y1", 0+270) - .attr("x2", x(new Date(block_6000000_time.Date*1000))) - .attr("y2", 10+270) - .attr("stroke-width", 1) - .attr("stroke", "black"); - - // ((block_6000000_time.Date-block_4000000_time.Date)/2+block_4000000_time.Date); - - svg.append("text") - //.attr("x", x(new Date((block_4000000_time.Date*1000)))) - .attr("x", x(new Date(( ((block_6000000_time.Date-block_4000000_time.Date)/2+block_4000000_time.Date)*1000)))) - .attr("y", 0+260) - .text(moment.duration(duration_40_60, 'seconds').humanize()) - .attr("text-anchor", "middle") - .attr("dy", "10px") - .attr("font-family", "sans-serif") - .attr("font-size", "20px"); - - - - - // Add Tooltip - var focus = svg.append("g") - .attr("class", "focus") - .style("display", "none"); - - focus.append("circle") - .attr("r", 4.5); - - focus.append("text") - .attr("x", 9) - .attr("dy", ".35em"); - - - svg.append("rect") - .attr("class", "overlay") - .attr("width", width) - .attr("height", height) - .on("mouseover", function() { focus.style("display", null); }) - .on("mouseout", function() { focus.style("display", "none"); }) - .on("mousemove", mousemove); - - - function mousemove() { - var x0 = x.invert(d3.mouse(this)[0]); - //console.log(moment(x0).unix()); - - - var s1 = _.minBy(data, function(d) { - //console.log(d.unixtime); - return Math.abs(moment(x0).unix()-d.unixtime); - }); - - //console.log(moment(s1.unixtime*1000).format()); - //console.log(s1.instantHashrate); - - - - //focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")"); - focus.attr("transform", "translate(" + x(moment(x0).unix()*1000) + "," + y(s1.difficulty) + ")"); - } - - - - - callback(null, 'four'); - } - function myLastFunction(arg1, callback) { - // arg1 now equals 'three' - callback(null, 'done'); - } - - } } } diff --git a/public/js/controllers/TokenListController.js b/public/js/controllers/TokenListController.js index 5f18f2692..01647821e 100755 --- a/public/js/controllers/TokenListController.js +++ b/public/js/controllers/TokenListController.js @@ -1,19 +1,19 @@ -angular.module('BlocksApp').controller('TokenListController', function($stateParams, $rootScope, $scope, $http) { - $scope.$on('$viewContentLoaded', function() { - // initialize core components - App.initAjax(); - }); - $scope.settings = $rootScope.setup; - - var tokenList = '/' + ($scope.settings.tokenList || 'tokens.json'); - $http.get(tokenList) - .then(function(res){ - var contentType = res.headers('Content-Type'); - if (contentType.indexOf('/json') > 0) { - $scope.tokens = res.data; - } else { - $scope.tokens = []; - } - }) - +angular.module('BlocksApp').controller('TokenListController', function($stateParams, $rootScope, $scope, $http) { + $scope.$on('$viewContentLoaded', function() { + // initialize core components + App.initAjax(); + }); + $scope.settings = $rootScope.setup; + + var tokenList = '/' + ($scope.settings.tokenList || 'tokens.json'); + $http.get(tokenList) + .then(function(res){ + var contentType = res.headers('Content-Type'); + if (contentType.indexOf('/json') > 0) { + $scope.tokens = res.data; + } else { + $scope.tokens = []; + } + }) + }) \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index 5a4d09544..670f9f458 100755 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,11 +1,11 @@ var BlocksApp = angular.module("BlocksApp", [ - "ui.router", - "ui.bootstrap", - "oc.lazyLoad", + "ui.router", + "ui.bootstrap", + "oc.lazyLoad", "ngSanitize" -]); +]); BlocksApp.constant('_', window._); // loadsh -BlocksApp.config(['$ocLazyLoadProvider', '$locationProvider', +BlocksApp.config(['$ocLazyLoadProvider', '$locationProvider', function($ocLazyLoadProvider, $locationProvider) { $ocLazyLoadProvider.config({ cssFilesInsertBefore: 'ng_load_plugins_before' // load the above css files before a LINK element with this ID. Dynamic CSS files must be loaded between core and theme css files @@ -44,7 +44,7 @@ BlocksApp.factory('setupObj', ['$rootScope', '$http', function($rootScope, $http BlocksApp.controller('MainController', ['$scope', '$rootScope', function($scope, $rootScope) { $scope.$on('$viewContentLoaded', function() { //App.initComponents(); // init core components - //Layout.init(); // Init entire layout(header, footer, sidebar, etc) on page load if the partials included in server side instead of loading with ng-include directive + //Layout.init(); // Init entire layout(header, footer, sidebar, etc) on page load if the partials included in server side instead of loading with ng-include directive }); }]); @@ -64,13 +64,13 @@ BlocksApp.controller('HeaderController', ['$scope', '$location', 'setupObj', fun $scope.form.searchInput=""; $scope.form.searchForm.$setPristine(); $scope.form.searchForm.$setUntouched(); - if (isAddress(search)) + if (isAddress(search)) $location.path("/addr/" + search); else if (isTransaction(search)) $location.path("/tx/" + search); else if (!isNaN(search)) $location.path("/block/" + search); - else + else $scope.form.searchInput = search; } setupObj.then(function(res) { @@ -79,8 +79,8 @@ BlocksApp.controller('HeaderController', ['$scope', '$location', 'setupObj', fun }]); /* Search Bar */ BlocksApp.controller('PageHeadController', ['$scope', 'setupObj', function($scope, setupObj) { - $scope.$on('$includeContentLoaded', function() { - + $scope.$on('$includeContentLoaded', function() { + }); setupObj.then(function(res) { $scope.settings = res; @@ -98,19 +98,19 @@ BlocksApp.controller('FooterController', ['$scope', 'setupObj', function($scope, /* Setup Rounting For All Pages */ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { // Redirect any unmatched url - $urlRouterProvider.otherwise("home"); + $urlRouterProvider.otherwise("home"); $stateProvider // Dashboard .state('home', { url: "/home", - templateUrl: "views/home.html", + templateUrl: "views/home.html", data: {pageTitle: 'Blockchain Explorer'}, controller: "HomeController", resolve: { deps: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load([{ name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', + insertBefore: '#ng_load_plugins_before', files: [ '/js/controllers/HomeController.js', '/css/todo-2.min.css' @@ -240,7 +240,7 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide deps: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load({ name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', + insertBefore: '#ng_load_plugins_before', files: [ '/js/controllers/ContractController.js', '/js/custom.js' @@ -277,7 +277,7 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide deps: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load({ name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', + insertBefore: '#ng_load_plugins_before', files: [ '/js/controllers/TokenListController.js' ] @@ -294,7 +294,7 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide deps: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load({ name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', + insertBefore: '#ng_load_plugins_before', files: [ '/js/controllers/TokenController.js' ] @@ -302,23 +302,6 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide }] } }) - .state('dao', { - url: "/dao", - templateUrl: "views/dao.html", - data: {pageTitle: 'theDAO'}, - controller: "DAOController", - resolve: { - deps: ['$ocLazyLoad', function($ocLazyLoad) { - return $ocLazyLoad.load({ - name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', - files: [ - '/js/controllers/DAOController.js' - ] - }); - }] - } - }) .state('err404', { url: "/err404/{thing}/{hash}", templateUrl: "views/err_404.html", @@ -328,7 +311,7 @@ BlocksApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvide deps: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load({ name: 'BlocksApp', - insertBefore: '#ng_load_plugins_before', + insertBefore: '#ng_load_plugins_before', files: [ '/js/controllers/ErrController.js' ] @@ -346,7 +329,7 @@ BlocksApp.filter('timeDuration', function() { return function(hashes) { return getDifficulty(hashes); }; -}) +}) .filter('teraHashes', function() { return function(hashes) { var result = hashes / Math.pow(1000, 4); diff --git a/public/js/web3utils.js b/public/js/web3utils.js index ce9b6e977..47538be8c 100644 --- a/public/js/web3utils.js +++ b/public/js/web3utils.js @@ -38,4 +38,5 @@ var isTransaction = function (tx) { // Otherwise check each case return false; } -}; \ No newline at end of file +}; + diff --git a/public/plugins/font-awesome/css/font-awesome.css b/public/plugins/font-awesome/css/font-awesome.css index 880eb8250..ee906a819 100755 --- a/public/plugins/font-awesome/css/font-awesome.css +++ b/public/plugins/font-awesome/css/font-awesome.css @@ -1,13 +1,13 @@ /*! - * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* FONT PATH * -------------------------- */ @font-face { font-family: 'FontAwesome'; - src: url('../fonts/fontawesome-webfont.eot?v=4.4.0'); - src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg'); + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } @@ -118,31 +118,31 @@ } } .fa-rotate-90 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .fa-rotate-180 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; -webkit-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } .fa-rotate-270 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); } .fa-flip-horizontal { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; -webkit-transform: scale(-1, 1); -ms-transform: scale(-1, 1); transform: scale(-1, 1); } .fa-flip-vertical { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; -webkit-transform: scale(1, -1); -ms-transform: scale(1, -1); transform: scale(1, -1); @@ -1383,7 +1383,7 @@ .fa-digg:before { content: "\f1a6"; } -.fa-pied-piper:before { +.fa-pied-piper-pp:before { content: "\f1a7"; } .fa-pied-piper-alt:before { @@ -1509,6 +1509,7 @@ content: "\f1ce"; } .fa-ra:before, +.fa-resistance:before, .fa-rebel:before { content: "\f1d0"; } @@ -1831,6 +1832,7 @@ content: "\f23e"; } .fa-battery-4:before, +.fa-battery:before, .fa-battery-full:before { content: "\f240"; } @@ -2024,3 +2026,312 @@ .fa-fonticons:before { content: "\f280"; } +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/public/plugins/font-awesome/css/font-awesome.min.css b/public/plugins/font-awesome/css/font-awesome.min.css index ee4e9782b..540440ce8 100755 --- a/public/plugins/font-awesome/css/font-awesome.min.css +++ b/public/plugins/font-awesome/css/font-awesome.min.css @@ -1,4 +1,4 @@ /*! - * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.4.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/public/plugins/font-awesome/fonts/FontAwesome.otf b/public/plugins/font-awesome/fonts/FontAwesome.otf index 681bdd4d4..401ec0f36 100755 Binary files a/public/plugins/font-awesome/fonts/FontAwesome.otf and b/public/plugins/font-awesome/fonts/FontAwesome.otf differ diff --git a/public/plugins/font-awesome/fonts/fontawesome-webfont.eot b/public/plugins/font-awesome/fonts/fontawesome-webfont.eot index a30335d74..e9f60ca95 100755 Binary files a/public/plugins/font-awesome/fonts/fontawesome-webfont.eot and b/public/plugins/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/public/plugins/font-awesome/fonts/fontawesome-webfont.svg b/public/plugins/font-awesome/fonts/fontawesome-webfont.svg index 6fd19abcb..855c845e5 100755 --- a/public/plugins/font-awesome/fonts/fontawesome-webfont.svg +++ b/public/plugins/font-awesome/fonts/fontawesome-webfont.svg @@ -1,640 +1,2671 @@ - - + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/plugins/font-awesome/fonts/fontawesome-webfont.ttf b/public/plugins/font-awesome/fonts/fontawesome-webfont.ttf index d7994e130..35acda2fa 100755 Binary files a/public/plugins/font-awesome/fonts/fontawesome-webfont.ttf and b/public/plugins/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/public/plugins/font-awesome/fonts/fontawesome-webfont.woff b/public/plugins/font-awesome/fonts/fontawesome-webfont.woff index 6fd4ede0f..400014a4b 100755 Binary files a/public/plugins/font-awesome/fonts/fontawesome-webfont.woff and b/public/plugins/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/public/plugins/font-awesome/fonts/fontawesome-webfont.woff2 b/public/plugins/font-awesome/fonts/fontawesome-webfont.woff2 index 5560193cc..4d13fc604 100755 Binary files a/public/plugins/font-awesome/fonts/fontawesome-webfont.woff2 and b/public/plugins/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/public/tokens.json b/public/tokens.json index 6258d50f2..a823d87ba 100644 --- a/public/tokens.json +++ b/public/tokens.json @@ -18,5 +18,13 @@ "symbol":"SATURN", "name": "Saturn Classic", "decimal":4, - "abi": [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"_data","type":"bytes"}],"name":"ERC223Transfer","type":"event"}] } + "abi": [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"_data","type":"bytes"}],"name":"ERC223Transfer","type":"event"}] + }, + { + "address":"0x085b0fdf115aa9e16ae1bddd396ce1f993c52220", + "symbol":"ONEX", + "name": "ONEX Network", + "decimal":18, + "abi": [{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_name"}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"mint","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_totalSupply"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"maxTotalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":"_decimals"}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"blockNumber"}],"name":"getBlockNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"chainStartTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"balance"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeStartTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_symbol"}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalInitialSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"transfer","inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"coinAge","inputs":[{"type":"address","name":"staker"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"interest"}],"name":"annualInterest","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"transfer","inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"},{"type":"bytes","name":"_data"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeMinAge","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"chainStartBlockNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeMaxAge","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"maxMintProofOfStake","inputs":[],"constant":true},{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[]},{"type":"event","name":"Mint","inputs":[{"type":"address","name":"_address","indexed":true},{"type":"uint256","name":"_reward","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"_from","indexed":true},{"type":"address","name":"_to","indexed":true},{"type":"uint256","name":"_value","indexed":false}],"anonymous":false},{"type":"event","name":"ERC223Transfer","inputs":[{"type":"address","name":"_from","indexed":true},{"type":"address","name":"_to","indexed":true},{"type":"uint256","name":"_value","indexed":false},{"type":"bytes","name":"_data","indexed":false}],"anonymous":false}] + } ] diff --git a/public/tpl/footer.html b/public/tpl/footer.html index c376ec70a..42380fdd6 100755 --- a/public/tpl/footer.html +++ b/public/tpl/footer.html @@ -1,51 +1,51 @@
-
-
- - - -
+
+
+ + +
+
- +
diff --git a/public/tpl/header.html b/public/tpl/header.html index c0ebd436e..aae17b0fd 100755 --- a/public/tpl/header.html +++ b/public/tpl/header.html @@ -1,181 +1,136 @@
diff --git a/public/tpl/page-head.html b/public/tpl/page-head.html index 03f0a6d4e..0a2355423 100755 --- a/public/tpl/page-head.html +++ b/public/tpl/page-head.html @@ -1,10 +1,10 @@
- -
-

- - -

-
- -
\ No newline at end of file + +
+

+ + +

+
+ + diff --git a/public/views/address.html b/public/views/address.html index 3b2034342..91fdb7841 100644 --- a/public/views/address.html +++ b/public/views/address.html @@ -1,31 +1,24 @@
-
-
Contract Overview
-
-
-
-
-
- - {{ addr.balance | number: 10 }}
- - {{ settings.symbol }} Balance -
-
- {{ addr.ethfiat | number: 10 }} ETH-F balance - -
-
- {{ addr.mined }} Mined -
-
- {{ addr.count }} Transactions -
-
+
+
Contract Overview
+
+
+
+
+
+ + {{ addr.balance | number: 4 }} {{ settings.symbol }}
+ + {{ settings.symbol }} Balance +
+
+ {{ addr.balanceUSD | currency : "$" : 4 }} USD balance +
+
+ {{ addr.mined }} Mined
-
@@ -48,89 +41,91 @@
- -
-
-
- +
+
+
+ +
+ Token Address
+ {{addr.address}} +
+
+
+ +
+ +
+
-
-
- -
-
- - - - - - - - - - - - - - -
TxHash Block From To {{ settings.symbol }} gas Age
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
TxHash Block From To Amount gas call
No more transactions
{{t.transactionHash}} {{t.blockNumber}} - {{t.from}} {{t.to}} {{t.amount | number: 4}} {{t.tokenInfo.symbol}} {{t.gas}} {{t.type}} {{t.error}}
- -
-
- -
+
+
+ +
+
+ + + + + + + + + + + + + + +
TxHash Block From To {{ settings.symbol }} gas Age
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
TxHash Block From To {{ settings.symbol }} gas
{{t.transactionHash}} {{t.blockNumber}} + {{t.from}} {{t.to}} {{t.amount | number: 4}} {{t.tokenInfo.symbol}} {{t.gas}} {{t.type}} {{t.error}}
+
+
+
-
-
+
+
+
diff --git a/public/views/block.html b/public/views/block.html index 5f808091b..b8067f691 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -1,52 +1,64 @@
-
- - - - - - - - - - - - - - - - - +
+
height<Prev {{block.number | number}} Next>
Time{{block.datetime | date:'yyyy-MM-dd HH:mm:ss Z' }} ({{block.timestamp | timeDuration}} ago)
Hash{{block.hash}}
parentHash{{block.parentHash}}
sha3 Uncles{{block.sha3Uncles}}
Mined By{{block.miner}}
Difficulty{{block.difficulty | totalDifficulty}}
Total Difficulty{{block.totalDifficulty | totalDifficulty}}
Gas Limit{{block.gasLimit | number}}
Gas Used{{block.gasUsed | number}}
nonce{{block.nonce}}
Extra Data{{block.extraData}}
Uncles{{block.uncles.length}} uncles - - - - - - -
{{u}}
-
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Block Height<Prev {{block.number | number}} Next>
TimeStamp{{block.timestamp | timeDuration}} ago ({{block.datetime | date:'yyyy-MM-dd HH:mm:ss Z' }})
Hash{{block.hash}}
Parent Hash + + {{block.parentHash}} +
Sha3Uncles{{block.sha3Uncles}}
Mined by{{block.miner}}
Difficulty{{block.difficulty | totalDifficulty}}
Total Difficulty{{block.totalDifficulty | totalDifficulty}}
Gas Limit{{block.gasLimit | number}}
Gas Used{{block.gasUsed | number}}
Nonce{{block.nonce}}
Extra Data{{block.extraData}} (Hex: {{block.extraDataHex}})
Uncles{{block.uncles.length}} uncles + + + + + +
{{u}}
+
-
- +
-
- +
+
- - - + + + - - - + + + -
Transactions
Transactions
{{t}}
{{t}}
-
-
+ +
+
+
diff --git a/public/views/contract-source.html b/public/views/contract-source.html index 76fb6f7f1..8f3c4d22b 100644 --- a/public/views/contract-source.html +++ b/public/views/contract-source.html @@ -5,40 +5,40 @@
Verify And Publish Source Code. -

- Contract Source Code Verified + Contract Source Code Verified

-
+
Contract Name: {{contract.contractName}} -
-
+
+
Compiler Version: {{contract.compilerVersion}} -
-
+
+
Optimization Enabled: {{contract.optimization}} -
+
-
+ +
Contract Source Code
{{contract.sourceCode}}

Contract ABI -
{{contract.abi}}

+
{{contract.abi}}
+
-
Contract Bytecode
{{addr.bytecode}}
- \ No newline at end of file + diff --git a/public/views/contract.html b/public/views/contract.html index 30650d682..2367a04bf 100644 --- a/public/views/contract.html +++ b/public/views/contract.html @@ -1,132 +1,117 @@
-
-
- -
- -
-
- -

Verify and Publish Contract Source Code

-
- Enter Contract Source Code below.
- If the compiled bytecode matches the Creation Address bytecode, the contract is then Verified and will be published online.
+
+
+
+ +
+
+ +

Verify and Publish Contract Source Code

+
+ Enter Contract Source Code below.
+ If the compiled bytecode matches the Creation Address bytecode, the contract is then Verified and will be published online.
+
+
+
+
+
+ Contract Address +
+ +
-
-
- -
- Contract Address -
- - -
- {{errors.address}} -
- -
- Contract Name -
- - -
- {{errors.name}} -
- - -
- Compiler -
- -
- {{errors.version}} -
-
- Optimization Enabled - -
- -
- -
-
- Contract Code: - {{errors.code}} - -
-
- -
-
- Constructor Arguments ABI-encoded (OPTIONAL - Required for certain contracts only): - {{errors.abi}} - -
-
-
- - - - -
- -
- -
- -
-
-

Contract Source Code Verified

-

- - View the verified result at {{contract.address}}. -

-
-
-

Unable to Verify Code

-

- - The compiled result does not match the input creation bytecode located at {{contract.address}}. -

+ {{errors.address}} +
+
+ Contract Name +
+ +
+ {{errors.name}}
-
-
-
- Compiler Version: {{contract.compilerVersion}}
- Optimization Enabled: {{contract.optimization}}
- -
-
ContractName:
-
{{v.name}}
- ContractBytecode:
-
{{v.bytecode}}
- ContractABI:
-
{{v.abi}}
-
-
- - +
+ Compiler +
+
+ {{errors.version}}
- +
+ Optimization Enabled + +
+
+
+
+ Contract Code: + {{errors.code}} + +
+
+
+
+ Constructor Arguments ABI-encoded (OPTIONAL - Required for certain contracts only): + {{errors.abi}} + +
+
+
+ + +
+ +
+ +
+
+
+

Contract Source Code Verified

+

+ + View the verified result at {{contract.address}}. +

+
+
+

Unable to Verify Code

+

+ + The compiled result does not match the input creation bytecode located at {{contract.address}}. +

+
+
+
+
+
+ Compiler Version: {{contract.compilerVersion}}
+ Optimization Enabled: {{contract.optimization}}
+
+
ContractName:
+
{{v.name}}
+ ContractBytecode:
+
{{v.bytecode}}
+ ContractABI:
+
{{v.abi}}
+
- - -
-
- - -
\ No newline at end of file + +
+
+
+
+ +
+ +
diff --git a/public/views/created-tokens.html b/public/views/created-tokens.html index 031a9cde9..e52a4a04a 100644 --- a/public/views/created-tokens.html +++ b/public/views/created-tokens.html @@ -1,33 +1,32 @@ -
- - - - - - - - - - - - - - - - - - - - - -
TxHash Age Block To Amount
{{t.transactionHash}} {{t.timestamp | timeDuration}} ago {{t.blockNumber}} {{t.to}} {{t.amount | number}} Created
- -
\ No newline at end of file + + + + + + + + + + + + + + + + + + + + + +
TxHash Age Block To Amount
{{t.transactionHash}} {{t.timestamp | timeDuration}} ago {{t.blockNumber}} {{t.to}} {{t.amount | number}} Created
+ +
diff --git a/public/views/dao.html b/public/views/dao.html deleted file mode 100644 index 86abe1cad..000000000 --- a/public/views/dao.html +++ /dev/null @@ -1,99 +0,0 @@ - -
-
-
-
-
-
- - {{ dao.balance | number: 10 }}
- - TheDAO Balance -
-
- {{ dao.extra_balance | number: 10 }} TheDAO Extra Balance - -
-
- {{ dao.total_supply | number:1 }} Total Tokens -
-
- Token Holders -
-
- {{ dao.count }} Transactions -
-
-
- -
-
-
- - WATCH - WATCHING -
- {{ dao.follow_count }}0 - WATCHING -
- -
-
-
- -
- -
-
- - -
-
- -
- -
-
-

Get DAO-C Token Balance

-
-
- Enter Your Address -
- - - - -
- {{errors.address}} -
-
-
-
-

You have 0{{dao.tokens | number}} DAO-C tokens.

-
-
-
-
- -
-
- -
-
-
-
-
\ No newline at end of file diff --git a/public/views/err_404.html b/public/views/err_404.html index 6ae220f52..b559687af 100755 --- a/public/views/err_404.html +++ b/public/views/err_404.html @@ -1,13 +1,14 @@
-
-
404
-
-

Oops! You're lost.

-

We can not find the {{thing}} you are looking for. -

- If you believe your {{thing}} is correct,
- please report this error. -

-
+
+
404
+
+

Oops! You're lost.

+

We can not find the {{thing}} you are looking for. +

+

+ If you believe your {{thing}} is correct,
+ please report this error. +

-
\ No newline at end of file +
+
diff --git a/public/views/home.html b/public/views/home.html index f69af5d78..60f6b7c88 100755 --- a/public/views/home.html +++ b/public/views/home.html @@ -1,78 +1,74 @@ - + - -
-
- -
-
-
- - Blocks -
-
-
- - -
-
-
-
-
-
- -
- {{t.number}}
- - {{t.timestamp | timeDuration }} ago -
-
-
{{t.extraData}}
- by {{t.miner}}
- {{t.txn}} txns -
-
-
-
-
+
+ +
+
+
+ + Blocks +
+
+
+ +
- +
-
- -
-
-
- - Transactions -
-
-
- - -
-
+
+
+
+ +
+ {{t.number}}
+ + {{t.timestamp | timeDuration }} ago +
+
+
{{t.extraData}}
+ by {{t.miner}}
+ {{t.txn}} txns
-
-
-
-
-
- TX {{t.hash}} -
-
{{t.timestamp | timeDuration }} ago
-
-
- From {{t.from.substr(0,24)}}... - To {{t.to.substr(0,24)}}...
-
{{t.value}} {{settings.symbol}}
-
-
- +
+
+
+
+
+ +
+
+ +
+
+
+ + Transactions +
+
+
+ + +
+
+
+
+
+
+
+
+ TX {{t.hash}}
+
{{t.timestamp | timeDuration }} ago
+
+
+ From {{t.from.substr(0,24)}}... + To {{t.to.substr(0,24)}}...
+
{{t.value}} {{settings.symbol}}
+
- +
+ +
- diff --git a/public/views/simple-summary-stats.html b/public/views/simple-summary-stats.html index 537ef48c7..9d25c6e80 100644 --- a/public/views/simple-summary-stats.html +++ b/public/views/simple-summary-stats.html @@ -1,63 +1,63 @@
-
-
-
-
- -
-
-

- # - {{stats.blockHeight | number: 0 }} -

- Block Height -
-
+
+
+
+
+
+
+

+ # + {{stats.blockHeight | number: 0 }} +

+ Block Height +
+
-
-
-
-
- -
-
-

- {{stats.blockTime | number: 2}} s -

- Block Time -
-
+
+
+
+
+
+ +
+
+

+ {{stats.blockTime | number: 2}} s +

+ Block Time
+
-
-
-
-
- -
-
-

- {{stats.hashrate | totalDifficulty}}/s -

- Network Hashrate -
-
+
+
+
+
+
+
+
+

+ {{stats.hashrate | totalDifficulty}}/s +

+ Network Hashrate +
+
-
-
-
-
- -
-
-

- {{stats.difficulty | totalDifficulty}} -

- DIFFICULTY -
-
+
+
+
+
+
+ +
+
+

+ {{stats.difficulty | totalDifficulty}} +

+ DIFFICULTY
+
+
diff --git a/public/views/site-notes.html b/public/views/site-notes.html index 808f569a2..34212195c 100644 --- a/public/views/site-notes.html +++ b/public/views/site-notes.html @@ -1,7 +1,7 @@
-
-
-

This Explorer is under construction

-
+
+
+

Welcome to ETC Explorer!

+
diff --git a/public/views/stats/index.html b/public/views/stats/index.html index 26a8ead76..c5d87d2ca 100644 --- a/public/views/stats/index.html +++ b/public/views/stats/index.html @@ -1,14 +1,13 @@
-
- -
-
- - - - - -
-
+
+ +
+
+ + + + +
+
diff --git a/public/views/summary-stats.html b/public/views/summary-stats.html deleted file mode 100644 index 78c1a1219..000000000 --- a/public/views/summary-stats.html +++ /dev/null @@ -1,105 +0,0 @@ -
-
-
-
-
-

- $ - {{stats.usdEtc}} -

- ETC Price -
-
- -
-
-
-
- - {{stats.usdEtcEth}}% ETC/ETH USD price - -
-
-
ETC/ETH USD Price
-
{{stats.usdEtcEth}}%
-
-
-
-
-
-
-
-
-

- {{stats.etcHashrate | totalDifficulty}}/s -

- ETC Avg Hashrate -
-
-
-
- - {{stats.etcEthHash}}% - -
-
-
ETC/ETH Hashrate
-
{{stats.etcEthHash}}%
-
-
-
-
-
-
-
-
-

- {{stats.etcDiff | totalDifficulty}} -

- DIFFICULTY -
-
- -
-
-
-
- - {{stats.etcEthDiff}}% etc/eth difficulty - -
-
-
ETC/ETH difficulty
-
{{stats.etcEthDiff}}%
-
-
-
-
-
-
-
-
-

- $ - {{stats.usdEth}} -

- ETH PRICE -
-
- -
-
-
-
- - {{stats.ethChange}}% change - -
-
-
change
-
{{stats.ethChange}}%
-
-
-
-
-
\ No newline at end of file diff --git a/public/views/token.html b/public/views/token.html index 740c2cc8f..c82fcd833 100644 --- a/public/views/token.html +++ b/public/views/token.html @@ -1,144 +1,115 @@
-
-
-
-
-
- - {{ token.balance | number: 10 }}
- - {{ token.name }} Address Balance ({{ settings.symbol }}) -
-
- {{ token.total_supply | number:1 }} Total {{ token.symbol }} Tokens -
-
- Decimals {{ token.decimals }} -
- {{ token.total_holders | number:1 }}
- Token Holders -
-
- {{ token.count }} Transactions -
-
-
- -
-
-
- - WATCH - WATCHING -
- {{ token.follow_count }}0 - WATCHING -
- -
- Token Address
- {{token.address}} -
-
+
+
+
+
+
+ + {{ token.balance | number: 10 }}
+ + {{ token.name }} Address Balance ({{ settings.symbol }}) +
+
+ {{ token.total_supply | number:1 }} Total {{ token.symbol }} Tokens +
+ {{ token.total_holders | number:1 }} +
+ Token Holders +
+
+ {{ token.count }} Transactions +
+
+
+
+ +
+ Contract Address
+ {{token.address}} +
+
+
+ +
+ +
+ + +
+
+
+ +
+
+

Get {{ token.name }} Token Balance

+
+ +
+ Enter Your Address +
+ + + +
+ {{errors.address}} +
+
+ +
+ +
+

You have {{userTokens | number}} {{ token.symbol }} tokens.

- -
- -
-
- - -
-
- -
- -
-
-

Get {{ token.name }} Token Balance

-
-
- Enter Your Address -
- - - - -
- {{errors.address}} -
-
-
-
-

You have {{userTokens | number}} {{ token.symbol }} tokens.

-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
TxHash Block From To Amount gas call
No more transactions
{{t.transactionHash}} {{t.blockNumber}} - {{t.from}} {{t.to}} {{t.amount | number: 4}} {{t.gas}} {{t.type}} {{t.error}}
- -
- -
- -
-
+
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + +
TxHash Block From To {{ settings.symbol }} gas Age
+
+ +
+ +
-
-
\ No newline at end of file + +
+
+ +
diff --git a/public/views/tokenlist.html b/public/views/tokenlist.html index 44cd5bbf5..29e8cf403 100755 --- a/public/views/tokenlist.html +++ b/public/views/tokenlist.html @@ -1,25 +1,24 @@
-
-
- - - - - - - - - - - - - - - - - - -
# Token (Symbol) Address Decimals
{{$index + 1}} {{t.name}} ({{t.symbol}}) {{t.address}} {{t.decimal}}
-
+
+
+ + + + + + + + + + + + + + + + + +
# Token (Symbol) Address Decimals
{{$index + 1}} {{t.name}} ({{t.symbol}}) {{t.address}} {{t.decimal}}
-
\ No newline at end of file +
+
diff --git a/public/views/transfer-tokens.html b/public/views/transfer-tokens.html index ef3fb2751..22cc05f66 100644 --- a/public/views/transfer-tokens.html +++ b/public/views/transfer-tokens.html @@ -1,45 +1,44 @@ -
- - - - - - - - - - - - - - - - - - - - - - - -
TxHash Age Block From To Amount ({{token.symbol}})
{{t.transactionHash}} {{t.timestamp | timeDuration}} ago {{t.blockNumber}} {{t.from}} {{t.to}} {{t.amount | number}} transfer {{t.error}}
+ + + + + + + + + + + + + + + + + + + + + + + +
TxHash Age Block From To Amount ({{token.symbol}})
{{t.transactionHash}} {{t.timestamp | timeDuration}} ago {{t.blockNumber}} {{t.from}} {{t.to}} {{t.amount | number}} transfer {{t.error}}
- - + +
diff --git a/public/views/tx.html b/public/views/tx.html index 13e0a33c3..3fca393a2 100644 --- a/public/views/tx.html +++ b/public/views/tx.html @@ -1,53 +1,84 @@
-
- - - - - - - - - - - - - - - - - - - - - -
hash{{tx.hash}}
blockNumber{{tx.blockNumber}}
Time{{tx.datetime | date:'yyyy-MM-dd HH:mm:ss Z' }} ({{tx.timestamp | timeDuration}} ago)
from{{tx.from}}
toContract {{tx.to}}
creates{{tx.creates}}
value{{tx.value}} {{ settings.symbol }}
gas Provided{{tx.gas | number}}
gasPrice{{tx.gasPrice | number}}
nonce{{tx.nonce}}
Input Data
{{tx.input}}
- - - - - - - - - - - - - - - - - - - - - - -
From To Amount Gas GasUsed
{{t.from}} {{t.to}} {{t.value}} {{settings.symbol}}{{t.amount | number}} {{t.gas}} {{t.gasUsed}} {{t.type}} {{t.error}}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Transaction Hash:{{tx.hash}}
Status: + Failed (Error encountered during transaction !) + Success +
Block: + {{tx.blockNumber | number}} + + +
TimeStamp: {{tx.timestamp | timeDuration}} ago ({{tx.datetime | date:'yyyy-MM-dd HH:mm:ss Z' }})
From: + {{tx.from}} + {{tx.tokenFrom}} +
To: + {{tx.to}} + {{tx.tokenTo}} +
Creates:{{tx.creates}}
Value: {{tx.value | number: 8}} {{ settings.symbol }} => {{ tx.valueUSD | currency : "USD $" : 4 }}
Token Value:{{tx.tokenValue | number: 8}} {{ tx.tokenSymbol }}
Transaction fee:{{tx.txFee | number : 6}} {{ settings.symbol }} => {{ tx.txFeeUSD | currency : "USD $" : 10 }}
Gas Limit:{{tx.gas | number}}
Gas Used by Transaction:{{tx.gasUsed | number}}
Gas Price:{{tx.gasPriceEther | number:9}} {{ settings.symbol }} ({{tx.gasPriceGwei | number}} Gwei)
Nonce:{{tx.nonce}}
Input Data +
{{tx.input}}
+
-
diff --git a/routes/compiler.js b/routes/compiler.js index e9d1c8833..3111148c8 100644 --- a/routes/compiler.js +++ b/routes/compiler.js @@ -1,66 +1,58 @@ -var solc = require('solc'); +const solc = require('solc'); +const { eth } = require('./web3relay'); +const Contract = require('./contracts'); -// var eth = require('./web3dummy').eth; -var eth = require('./web3relay').eth; - -var Contract = require('./contracts'); - -/* +/* TODO: support other languages */ -module.exports = function(req, res) { +module.exports = function (req, res) { console.log(req.body); - if (!("action" in req.body)) - res.status(400).send(); - if (req.body.action=="compile") { + if (!('action' in req.body)) res.status(400).send(); + if (req.body.action == 'compile') { compileSolc(req, res); - } else if (req.body.action=="find") { + } else if (req.body.action == 'find') { Contract.findContract(req.body.addr, res); } -} - +}; -var compileSolc = function(req, res) { +var compileSolc = async (req, res) => { // get bytecode at address - var address = req.body.address; - var version = req.body.version; - var name = req.body.name; - var input = req.body.code; - var optimization = (req.body.optimization) ? true : false; - var optimise = (optimization) ? 1 : 0; - - var bytecode = eth.getCode(address); - if (bytecode.substring(0,2)=="0x") - bytecode = bytecode.substring(2); - - var data = { - "address": address, - "creationTransaction": "", // deal with this later - "compilerVersion": version, - "optimization": optimization, - "contractName": name, - "sourceCode": input - } - - console.log(version) + const { address } = req.body; + const { version } = req.body; + const { name } = req.body; + const input = req.body.code; + const optimization = !!(req.body.optimization); + const optimise = (optimization) ? 1 : 0; + + let bytecode = await eth.getCode(address); + if (bytecode.substring(0, 2) == '0x') bytecode = bytecode.substring(2); + + const data = { + 'address': address, + 'compilerVersion': version, + 'optimization': optimization, + 'contractName': name, + 'sourceCode': input, + }; + + console.log(version); try { // latest version doesn't need to be loaded remotely - if (version == "latest") { - var output = solc.compile(input, optimise); - testValidCode(output, data, bytecode, res); + if (version == 'latest') { + const output = solc.compile(input, optimise); + testValidCode(output, data, bytecode, res); } else { - solc.loadRemoteVersion(version, function(err, solcV) { + solc.loadRemoteVersion(version, (err, solcV) => { if (err) { console.error(err); - res.write(JSON.stringify({"valid": false})); + res.write(JSON.stringify({ 'valid': false })); res.end(); - } - else { - var output = solcV.compile(input, optimise); + } else { + const output = solcV.compile(input, optimise); testValidCode(output, data, bytecode, res); } }); @@ -70,30 +62,31 @@ var compileSolc = function(req, res) { console.error(e.stack); } -} +}; -var testValidCode = function(output, data, bytecode, response) { - var verifiedContracts = []; +var testValidCode = function (output, data, bytecode, response) { + const verifiedContracts = []; for (var contractName in output.contracts) { // code and ABI that are needed by web3 - console.log(contractName + ': ' + output.contracts[contractName].bytecode); - verifiedContracts.push({"name": contractName, - "abi": output.contracts[contractName].interface, - "bytecode": output.contracts[contractName].bytecode}); + console.log(`${contractName}: ${output.contracts[contractName].bytecode}`); + verifiedContracts.push({ + 'name': contractName, + 'abi': output.contracts[contractName].interface, + 'bytecode': output.contracts[contractName].bytecode, + }); } // Remove swarm hash - var bytecodeClean = bytecode.replace(/a165627a7a72305820.{64}0029$/gi, ""); + const bytecodeClean = bytecode.replace(/a165627a7a72305820.{64}0029$/gi, ''); - var contractName = ':' + data.contractName; // XXX + var contractName = `:${data.contractName}`; // XXX // compare to bytecode at address - if (!output.contracts || !output.contracts[contractName]) - data.valid = false; - else if (output.contracts[contractName].bytecode.indexOf(bytecodeClean) > -1){ - var contractBytecodeClean = output.contracts[contractName].bytecode.replace(/a165627a7a72305820.{64}0029$/gi, ""); - constructorArgs = contractBytecodeClean.replace(bytecodeClean, ""); - contractBytecodeClean = contractBytecodeClean.replace(constructorArgs, ""); + if (!output.contracts || !output.contracts[contractName]) data.valid = false; + else if (output.contracts[contractName].bytecode.indexOf(bytecodeClean) > -1) { + let contractBytecodeClean = output.contracts[contractName].bytecode.replace(/a165627a7a72305820.{64}0029$/gi, ''); + constructorArgs = contractBytecodeClean.replace(bytecodeClean, ''); + contractBytecodeClean = contractBytecodeClean.replace(constructorArgs, ''); if (contractBytecodeClean == bytecodeClean) { data.valid = true; @@ -104,10 +97,9 @@ var testValidCode = function(output, data, bytecode, response) { } else { data.valid = false; } - } else - data.valid = false; + } else data.valid = false; - data["verifiedContracts"] = verifiedContracts; + data['verifiedContracts'] = verifiedContracts; response.write(JSON.stringify(data)); response.end(); -} \ No newline at end of file +}; diff --git a/routes/contracts.js b/routes/contracts.js index a239386c1..ec6bf5e66 100644 --- a/routes/contracts.js +++ b/routes/contracts.js @@ -1,36 +1,37 @@ /* - Stuff to deal with verified contracts in DB + Stuff to deal with verified contracts in DB */ -require( '../db.js' ); -var mongoose = require( 'mongoose' ); -var Contract = mongoose.model( 'Contract' ); +require('../db.js'); +const mongoose = require('mongoose'); -exports.addContract = function(contract) { +const Contract = mongoose.model('Contract'); + +exports.addContract = function (contract) { Contract.update( - {address: contract.address}, - {$setOnInsert: contract}, - {upsert: true}, - function (err, data) { + { address: contract.address }, + { $setOnInsert: contract }, + { upsert: true }, + (err, data) => { console.log(data); - } + }, ); -} +}; -exports.findContract = function(address, res) { - var contractFind = Contract.findOne({ address : address}).lean(true); - contractFind.exec(function(err, doc) { +exports.findContract = function (address, res) { + const contractFind = Contract.findOne({ address }).lean(true); + contractFind.exec((err, doc) => { if (err) { - console.error("ContractFind error: " + err); - console.error("bad address: " + address); - res.write(JSON.stringify({"error": true, "valid": false})); - } else if (!doc) { - res.write(JSON.stringify({"valid": false})); + console.error(`ContractFind error: ${err}`); + console.error(`bad address: ${address}`); + res.write(JSON.stringify({ 'error': true, 'valid': false })); + } else if (!doc || !doc.sourceCode) { + res.write(JSON.stringify({ 'valid': false })); } else { - var data = doc; + const data = doc; data.valid = true; res.write(JSON.stringify(data)); } res.end(); - }) -} \ No newline at end of file + }); +}; diff --git a/routes/dao.js b/routes/dao.js deleted file mode 100644 index 037ecbd4a..000000000 --- a/routes/dao.js +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env node - -/* - Endpoint for client to talk to node about DAO stuff -*/ - -var eth = require('./web3relay').eth; -require( '../db-dao' ); - -var mongoose = require( 'mongoose' ); -var DAOCreatedToken = mongoose.model('DAOCreatedToken'); -var DAOTransferToken = mongoose.model('DAOTransferToken'); - -var BigNumber = require('bignumber.js'); -var etherUnits = require(__lib + "etherUnits.js") - -var extraBalanceAddr = "0x807640a13483f8ac783c557fcdf27be11ea4ac7a"; -var daoABI = [{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"open","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"proposalHash","type":"bytes32"},{"name":"proposalDeposit","type":"uint256"},{"name":"newCurator","type":"bool"},{"name":"yea","type":"uint256"},{"name":"nay","type":"uint256"},{"name":"creator","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"minTokensToCreate","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"rewardAccount","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"daoCreator","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"divisor","outputs":[{"name":"divisor","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"extraBalance","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_transactionData","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"unblockMe","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalRewardToken","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"actualBalance","outputs":[{"name":"_actualBalance","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"closingTime","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"allowedRecipients","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferWithoutReward","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"refund","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_description","type":"string"},{"name":"_transactionData","type":"bytes"},{"name":"_debatingPeriod","type":"uint256"},{"name":"_newCurator","type":"bool"}],"name":"newProposal","outputs":[{"name":"_proposalID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"DAOpaidOut","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minQuorumDivisor","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_newContract","type":"address"}],"name":"newContract","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_allowed","type":"bool"}],"name":"changeAllowedRecipients","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"halveMinQuorum","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"paidOut","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_newCurator","type":"address"}],"name":"splitDAO","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"DAOrewardAccount","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"proposalDeposit","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numberOfProposals","outputs":[{"name":"_numberOfProposals","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"lastTimeMinQuorumMet","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_toMembers","type":"bool"}],"name":"retrieveDAOReward","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"receiveEther","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"isFueled","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_tokenHolder","type":"address"}],"name":"createTokenProxy","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_proposalID","type":"uint256"}],"name":"getNewDAOAddress","outputs":[{"name":"_newDAO","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_supportsProposal","type":"bool"}],"name":"vote","outputs":[{"name":"_voteID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"getMyReward","outputs":[{"name":"_success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"rewardToken","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFromWithoutReward","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_proposalDeposit","type":"uint256"}],"name":"changeProposalDeposit","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"blocked","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"curator","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_proposalID","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_transactionData","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"_codeChecksOut","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"privateCreation","outputs":[{"name":"","type":"address"}],"type":"function"},{"inputs":[{"name":"_curator","type":"address"},{"name":"_daoCreator","type":"address"},{"name":"_proposalDeposit","type":"uint256"},{"name":"_minTokensToCreate","type":"uint256"},{"name":"_closingTime","type":"uint256"},{"name":"_privateCreation","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"FuelingToDate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"CreatedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"newCurator","type":"bool"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":true,"name":"voter","type":"address"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"bool"},{"indexed":false,"name":"quorum","type":"uint256"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_newCurator","type":"address"}],"name":"NewCurator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_recipient","type":"address"},{"indexed":false,"name":"_allowed","type":"bool"}],"name":"AllowedRecipientChanged","type":"event"}] -var daoContract = eth.contract(daoABI); -var DAO = daoContract.at("0xbb9bc244d798123fde783fcc1c72d3bb8c189413"); - -module.exports = function(req, res){ - console.log(req.body) - - if (!("action" in req.body)) - res.status(400).send(); - else if (req.body.action=="info") { - try { - var actualBalance = DAO.actualBalance(); - actualBalance = etherUnits.toEther(actualBalance, 'wei'); - var extraBalance = eth.getBalance(extraBalanceAddr); - extraBalance = etherUnits.toEther(extraBalance, 'wei'); - var totalSupply = DAO.totalSupply(); - totalSupply = etherUnits.toEther(totalSupply, 'wei')*100; - var daoData = { - "balance": actualBalance, - "extra_balance": extraBalance, - "total_supply": totalSupply - } - res.write(JSON.stringify(daoData)); - res.end(); - } catch (e) { - console.error(e); - } - } else if (req.body.action=="balanceOf") { - var addr = req.body.addr.toLowerCase(); - try { - var tokens = DAO.balanceOf(addr); - tokens = etherUnits.toEther(tokens, 'wei')*100; - res.write(JSON.stringify({"tokens": tokens})); - res.end(); - } catch (e) { - console.error(e); - } - } else if (req.body.action=="createdTokens") { - if (req.body.last_id) - var options = {'_id': {$lt: req.body.last_id}}; - else - var options = {}; - var ctFind = DAOCreatedToken.find(options).lean(true).sort('-blockNumber').limit(MAX_ENTRIES); - ctFind.exec(function (err, docs) { - if (!docs.length){ - res.write(JSON.stringify([])); - } else { - var formatDocs = docs.map( function(doc) { - var d = doc; - d.amount = etherUnits.toEther(d.amount, 'wei')*100; - return d; - }); - res.write(JSON.stringify(formatDocs)); - } - res.end(); - }); - } else if (req.body.action=="transferTokens") { - if (req.body.last_id) - var options = {'_id': {$lt: req.body.last_id}}; - else - var options = {}; - var ctFind = DAOTransferToken.find(options).lean(true).sort('-blockNumber').limit(MAX_ENTRIES); - ctFind.exec(function (err, docs) { - if (!docs.length){ - res.write(JSON.stringify([])); - } else { - var formatDocs = docs.map( function(doc) { - var d = doc; - d.amount = etherUnits.toEther(d.amount, 'wei')*100; - return d; - }); - res.write(JSON.stringify(formatDocs)); - } - res.end(); - }); - } - -}; - -const MAX_ENTRIES = 50; \ No newline at end of file diff --git a/routes/fiat.js b/routes/fiat.js deleted file mode 100644 index 4ebf13a83..000000000 --- a/routes/fiat.js +++ /dev/null @@ -1,33 +0,0 @@ -var http = require('http'); -var etherUnits = require(__lib + "etherUnits.js") - -module.exports = function(req, res) { - var addr = req.body.addr; - if (typeof addr !== "undefined") - addr = addr.toLowerCase(); - else - res.sendStatus(400); - - var options = { - host: 'api.blockcypher.com', - port: '80', - path: '/v1/eth/main/addrs/' + addr + '/balance', - method: 'GET' - }; - - var balance = 0; - http.request(options, function(bcRes) { - bcRes.on('data', function (data) { - try { - balance = JSON.parse(data).balance; - balance = etherUnits.toEther( balance, "wei"); - } catch (e) { - console.error("BC err, probably invalid addr"); - } - res.write(JSON.stringify({"balance": balance})); - res.end(); - }) - }).end(); - -} - diff --git a/routes/filters.js b/routes/filters.js index 94c983746..dadc7f49b 100644 --- a/routes/filters.js +++ b/routes/filters.js @@ -1,127 +1,111 @@ 'use strict'; -var etherUnits = require(__lib + "etherUnits.js") -var BigNumber = require('bignumber.js'); -var RLP = require('rlp'); + +const etherUnits = require(`${__lib}etherUnits.js`); +const BigNumber = require('bignumber.js'); +const RLP = require('rlp'); /* - Filter an array of TX + Filter an array of TX */ function filterTX(txs, value) { - return txs.map(function(tx){ - return [tx.hash, tx.blockNumber, tx.from, tx.to, etherUnits.toEther(new BigNumber(tx.value), 'ether'), tx.gas, tx.timestamp, tx.creates]; - }) + return txs.map(tx => [tx.hash, tx.blockNumber, tx.from, tx.to, etherUnits.toEther(new BigNumber(tx.value), 'ether'), tx.gas, tx.timestamp, tx.creates]); } function filterTrace(txs, value) { - return txs.map(function(tx){ - var t = tx; - if (t.type == "suicide") { - if (t.action.address) - t.from = t.action.address; - if (t.action.balance) - t.value = etherUnits.toEther( new BigNumber(t.action.balance), "wei"); - if (t.action.refundAddress) - t.to = t.action.refundAddress; + return txs.map((tx) => { + const t = tx; + if (t.type == 'suicide') { + if (t.action.address) t.from = t.action.address; + if (t.action.balance) t.value = etherUnits.toEther(new BigNumber(t.action.balance), 'wei'); + if (t.action.refundAddress) t.to = t.action.refundAddress; } else { - if (t.action.to) - t.to = t.action.to; - t.from = t.action.from; - if (t.action.gas) - t.gas = new BigNumber(t.action.gas).toNumber(); - if ((t.result) && (t.result.gasUsed)) - t.gasUsed = new BigNumber(t.result.gasUsed).toNumber(); - if ((t.result) && (t.result.address)) - t.to = t.result.address; - t.value = etherUnits.toEther( new BigNumber(t.action.value), "wei"); + if (t.action.to) t.to = t.action.to; + t.from = t.action.from; + if (t.action.gas) t.gas = new BigNumber(t.action.gas).toNumber(); + if ((t.result) && (t.result.gasUsed)) t.gasUsed = new BigNumber(t.result.gasUsed).toNumber(); + if ((t.result) && (t.result.address)) t.to = t.result.address; + t.value = etherUnits.toEther(new BigNumber(t.action.value), 'wei'); } return t; - }) + }); } function filterBlock(block, field, value) { - var tx = block.transactions.filter(function(obj) { - return obj[field]==value; - }); + let tx = block.transactions.filter(obj => obj[field] == value); tx = tx[0]; - if (typeof tx !== "undefined") - tx.timestamp = block.timestamp; + if (typeof tx !== 'undefined') tx.timestamp = block.timestamp; return tx; } /* make blocks human readable */ function filterBlocks(blocks) { if (blocks.constructor !== Array) { - var b = blocks; - var ascii = hex2ascii(blocks.extraData); + const b = blocks; + const ascii = hex2ascii(blocks.extraData); b.extraDataHex = blocks.extraData; b.extraData = ascii; return b; } - return blocks.map(function(block) { - var b = block; - var ascii = hex2ascii(block.extraData); + return blocks.map((block) => { + const b = block; + const ascii = hex2ascii(block.extraData); b.extraDataHex = block.extraData; b.extraData = ascii; return b; - }) + }); } /* stupid datatable format */ function datatableTX(txs) { - return txs.map(function(tx){ - return [tx.hash, tx.blockNumber, tx.from, tx.to, - etherUnits.toEther(new BigNumber(tx.value), 'wei'), tx.gas, tx.timestamp] - }) + return txs.map(tx => [tx.hash, tx.blockNumber, tx.from, tx.to, + etherUnits.toEther(new BigNumber(tx.value), 'wei'), tx.gas, tx.timestamp]); } function internalTX(txs) { - return txs.map(function(tx){ - return [tx.transactionHash, tx.blockNumber, tx.action.from, tx.action.to, - etherUnits.toEther(new BigNumber(tx.action.value), 'wei'), tx.action.gas, tx.timestamp] - }) + return txs.map(tx => [tx.transactionHash, tx.blockNumber, tx.action.from, tx.action.to, + etherUnits.toEther(new BigNumber(tx.action.value), 'wei'), tx.action.gas, tx.timestamp]); } /* modified baToJSON() routine from rlp */ function baToString(ba) { if (Buffer.isBuffer(ba)) { return ba.toString('ascii'); - } else if (ba instanceof Array) { - var array = []; - for (var i = 0; i < ba.length; i++) { + } if (ba instanceof Array) { + const array = []; + for (let i = 0; i < ba.length; i++) { array.push(baToString(ba[i])); } return array.join('/'); - } else { - return ba; } + return ba; + } var hex2ascii = function (hexIn) { - var hex = hexIn.toString(); - var str = ''; + const hex = hexIn.toString(); + let str = ''; try { - var ba = RLP.decode(hex); - var test = ba[1].toString('ascii'); + const ba = RLP.decode(hex); + const test = ba[1].toString('ascii'); if (test == 'geth' || test == 'Parity') { // FIXME ba[0] = ba[0].toString('hex'); } str = baToString(ba); - } catch(e) { - for (var i = 0; i < hex.length; i += 2) - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + } catch (e) { + for (let i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); } return str; -} +}; module.exports = { - filterBlock: filterBlock, - filterBlocks: filterBlocks, - filterTX: filterTX, - filterTrace: filterTrace, - datatableTX: datatableTX, - internalTX: internalTX -} + filterBlock, + filterBlocks, + filterTX, + filterTrace, + datatableTX, + internalTX, +}; diff --git a/routes/index.js b/routes/index.js index 46c230147..31f13c6e2 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,25 +1,23 @@ -var mongoose = require( 'mongoose' ); +const mongoose = require('mongoose'); -var Block = mongoose.model( 'Block' ); -var Transaction = mongoose.model( 'Transaction' ); -var filters = require('./filters'); +const Block = mongoose.model('Block'); +const Transaction = mongoose.model('Transaction'); +const Account = mongoose.model('Account'); +const async = require('async'); +const filters = require('./filters'); -var async = require('async'); +module.exports = function (app) { + const web3relay = require('./web3relay'); -module.exports = function(app){ - var web3relay = require('./web3relay'); + const Token = require('./token'); - var DAO = require('./dao'); - var Token = require('./token'); + const compile = require('./compiler'); + const stats = require('./stats'); + const richList = require('./richlist'); - var compile = require('./compiler'); - var fiat = require('./fiat'); - var stats = require('./stats'); - var richList = require('./richlist'); - - /* + /* Local DB: data request format - { "address": "0x1234blah", "txin": true } + { "address": "0x1234blah", "txin": true } { "tx": "0x1234blah" } { "block": "1234" } */ @@ -29,29 +27,30 @@ module.exports = function(app){ app.post('/tx', getTx); app.post('/block', getBlock); app.post('/data', getData); + app.get('/total', getTotal); - app.post('/daorelay', DAO); - app.post('/tokenrelay', Token); + app.post('/tokenrelay', Token); app.post('/web3relay', web3relay.data); app.post('/compile', compile); - app.post('/fiat', fiat); app.post('/stats', stats); -} +}; -var getAddr = function(req, res){ +const getAddr = async (req, res) => { // TODO: validate addr and tx - var addr = req.body.addr.toLowerCase(); - var count = parseInt(req.body.count); + const addr = req.body.addr.toLowerCase(); + const count = parseInt(req.body.count); - var limit = parseInt(req.body.length); - var start = parseInt(req.body.start); + const limit = parseInt(req.body.length); + const start = parseInt(req.body.start); - var data = { draw: parseInt(req.body.draw), recordsFiltered: count, recordsTotal: count, mined: 0 }; + const data = { + draw: parseInt(req.body.draw), recordsFiltered: count, recordsTotal: count, mined: 0, + }; - var addrFind = Transaction.find( { $or: [{"to": addr}, {"from": addr}] }) + const addrFind = Transaction.find({ $or: [{ 'to': addr }, { 'from': addr }] }); - var sortOrder = '-blockNumber'; + let sortOrder = '-blockNumber'; if (req.body.order && req.body.order[0] && req.body.order[0].column) { // date or blockNumber column if (req.body.order[0].column == 1 || req.body.order[0].column == 6) { @@ -61,79 +60,77 @@ var getAddr = function(req, res){ } } - addrFind.lean(true).sort(sortOrder).skip(start).limit(limit) - .exec("find", function (err, docs) { - if (docs) - data.data = filters.filterTX(docs, addr); - else - data.data = []; + addrFind.lean(true).sort(sortOrder).skip(start).limit(limit) + .exec('find', (err, docs) => { + if (docs) data.data = filters.filterTX(docs, addr); + else data.data = []; res.write(JSON.stringify(data)); res.end(); }); }; -var getAddrCounter = function(req, res) { - var addr = req.body.addr.toLowerCase(); - var count = parseInt(req.body.count); - var data = { recordsFiltered: count, recordsTotal: count, mined: 0 }; +var getAddrCounter = function (req, res) { + const addr = req.body.addr.toLowerCase(); + const count = parseInt(req.body.count); + const data = { recordsFiltered: count, recordsTotal: count, mined: 0 }; async.waterfall([ - function(callback) { + function (callback) { - Transaction.count({ $or: [{"to": addr}, {"from": addr}] }, function(err, count) { - if (!err && count) { - // fix recordsTotal - data.recordsTotal = count; - data.recordsFiltered = count; - } - callback(null); - }); + Transaction.count({ $or: [{ 'to': addr }, { 'from': addr }] }, (err, count) => { + if (!err && count) { + // fix recordsTotal + data.recordsTotal = count; + data.recordsFiltered = count; + } + callback(null); + }); - }, function(callback) { + }, function (callback) { - Block.count({ "miner": addr }, function(err, count) { - if (!err && count) { - data.mined = count; - } - callback(null); - }); + Block.count({ 'miner': addr }, (err, count) => { + if (!err && count) { + data.mined = count; + } + callback(null); + }); - }], function (err) { + }], (err) => { res.write(JSON.stringify(data)); res.end(); }); }; -var getBlock = function(req, res) { +var getBlock = function (req, res) { // TODO: support queries for block hash - var txQuery = "number"; - var number = parseInt(req.body.block); + const txQuery = 'number'; + const number = parseInt(req.body.block); - var blockFind = Block.findOne( { number : number }).lean(true); - blockFind.exec(function (err, doc) { + const blockFind = Block.findOne({ number }).lean(true); + blockFind.exec((err, doc) => { if (err || !doc) { - console.error("BlockFind error: " + err) + console.error(`BlockFind error: ${err}`); console.error(req.body); - res.write(JSON.stringify({"error": true})); + res.write(JSON.stringify({ 'error': true })); } else { - var block = filters.filterBlocks([doc]); + const block = filters.filterBlocks([doc]); res.write(JSON.stringify(block[0])); } res.end(); }); }; -var getTx = function(req, res){ - var tx = req.body.tx.toLowerCase(); - var txFind = Block.findOne( { "transactions.hash" : tx }, "transactions timestamp") - .lean(true); - txFind.exec(function (err, doc) { - if (!doc){ - console.log("missing: " +tx) +var getTx = function (req, res) { + const tx = req.body.tx.toLowerCase(); + const txFind = Block.findOne({ 'transactions.hash': tx }, 'transactions timestamp') + .lean(true); + txFind.exec((err, doc) => { + if (!doc) { + console.log(`missing: ${tx}`); res.write(JSON.stringify({})); res.end(); } else { // filter transactions - var txDocs = filters.filterBlock(doc, "hash", tx) + const txDocs = filters.filterBlock(doc, 'hash', tx); res.write(JSON.stringify(txDocs)); res.end(); } @@ -142,89 +139,101 @@ var getTx = function(req, res){ /* Fetch data from DB */ -var getData = function(req, res){ +var getData = function (req, res) { // TODO: error handling for invalid calls - var action = req.body.action.toLowerCase(); - var limit = req.body.limit + const action = req.body.action.toLowerCase(); + const { limit } = req.body; if (action in DATA_ACTIONS) { - if (isNaN(limit)) - var lim = MAX_ENTRIES; - else - var lim = parseInt(limit); + if (isNaN(limit)) var lim = MAX_ENTRIES; + else var lim = parseInt(limit); DATA_ACTIONS[action](lim, res); - } else { - console.error("Invalid Request: " + action) + } else { + console.error(`Invalid Request: ${action}`); res.status(400).send(); } }; -/* +/* + Total supply API code +*/ +var getTotal = function (req, res) { + Account.aggregate([ + { $group: { _id: null, totalSupply: { $sum: '$balance' } } }, + ]).exec((err, docs) => { + if (err) { + res.write('Error getting total supply'); + res.end(); + } + res.write(docs[0].totalSupply.toString()); + res.end(); + }); +}; + +/* temporary blockstats here */ -var latestBlock = function(req, res) { - var block = Block.findOne({}, "totalDifficulty") - .lean(true).sort('-number'); - block.exec(function (err, doc) { +const latestBlock = function (req, res) { + const block = Block.findOne({}, 'totalDifficulty') + .lean(true).sort('-number'); + block.exec((err, doc) => { res.write(JSON.stringify(doc)); res.end(); }); -} - +}; -var getLatest = function(lim, res, callback) { - var blockFind = Block.find({}, "number transactions timestamp miner extraData") - .lean(true).sort('-number').limit(lim); - blockFind.exec(function (err, docs) { +const getLatest = function (lim, res, callback) { + const blockFind = Block.find({}, 'number transactions timestamp miner extraData') + .lean(true).sort('-number').limit(lim); + blockFind.exec((err, docs) => { callback(docs, res); }); -} +}; /* get blocks from db */ -var sendBlocks = function(lim, res) { - var blockFind = Block.find({}, "number timestamp miner extraData") - .lean(true).sort('-number').limit(lim); - blockFind.exec(function (err, docs) { - if(!err && docs) { - var blockNumber = docs[docs.length - 1].number; +const sendBlocks = function (lim, res) { + const blockFind = Block.find({}, 'number timestamp miner extraData') + .lean(true).sort('-number').limit(lim); + blockFind.exec((err, docs) => { + if (!err && docs) { + const blockNumber = docs[docs.length - 1].number; // aggregate transaction counters Transaction.aggregate([ - {$match: { blockNumber: { $gte: blockNumber } }}, - {$group: { _id: '$blockNumber', count: { $sum: 1 } }} - ]).exec(function(err, results) { - var txns = {}; + { $match: { blockNumber: { $gte: blockNumber } } }, + { $group: { _id: '$blockNumber', count: { $sum: 1 } } }, + ]).exec((err, results) => { + const txns = {}; if (!err && results) { // set transaction counters - results.forEach(function(txn) { + results.forEach((txn) => { txns[txn._id] = txn.count; }); - docs.forEach(function(doc) { + docs.forEach((doc) => { doc.txn = txns[doc.number] || 0; }); } - res.write(JSON.stringify({"blocks": filters.filterBlocks(docs)})); + res.write(JSON.stringify({ 'blocks': filters.filterBlocks(docs) })); res.end(); }); } else { - console.log("blockFind error:" + err); - res.write(JSON.stringify({"error": true})); + console.log(`blockFind error:${err}`); + res.write(JSON.stringify({ 'error': true })); res.end(); } }); -} +}; -var sendTxs = function(lim, res) { +const sendTxs = function (lim, res) { Transaction.find({}).lean(true).sort('-blockNumber').limit(lim) - .exec(function (err, txs) { - res.write(JSON.stringify({"txs": txs})); - res.end(); - }); -} + .exec((err, txs) => { + res.write(JSON.stringify({ 'txs': txs })); + res.end(); + }); +}; const MAX_ENTRIES = 10; const DATA_ACTIONS = { - "latest_blocks": sendBlocks, - "latest_txs": sendTxs -} - + 'latest_blocks': sendBlocks, + 'latest_txs': sendTxs, +}; diff --git a/routes/richlist.js b/routes/richlist.js index 8516645c2..6772f1757 100644 --- a/routes/richlist.js +++ b/routes/richlist.js @@ -3,47 +3,48 @@ * Endpoint for richlist */ -var async = require('async'); -var mongoose = require('mongoose'); +const async = require('async'); +const mongoose = require('mongoose'); -require( '../db.js' ); -var Account = mongoose.model('Account'); +require('../db.js'); -var getAccounts = function(req, res) { - var self = getAccounts; +const Account = mongoose.model('Account'); + +var getAccounts = function (req, res) { + const self = getAccounts; if (!self.totalSupply) { self.totalSupply = -1; self.timestamp = 0; } // check cached totalSupply - if (new Date() - self.timestamp > 30*60*1000) { + if (new Date() - self.timestamp > 30 * 60 * 1000) { self.totalSupply = -1; self.timestamp = 0; } // count accounts only once - var count = req.body.recordsTotal || 0; + let count = req.body.recordsTotal || 0; count = parseInt(count); if (count < 0) { count = 0; } // get totalSupply only once - var queryTotalSupply = self.totalSupply || req.body.totalSupply || null; + const queryTotalSupply = self.totalSupply || req.body.totalSupply || null; async.waterfall([ - function(callback) { + function (callback) { if (queryTotalSupply < 0) { Account.aggregate([ - { $group: { _id: null, totalSupply: { $sum: '$balance' } } } - ]).exec(function(err, docs) { + { $group: { _id: null, totalSupply: { $sum: '$balance' } } }, + ]).exec((err, docs) => { if (err) { callbck(err); return; } - var totalSupply = docs[0].totalSupply; + const { totalSupply } = docs[0]; // update cache self.timestamp = new Date(); self.totalSupply = totalSupply; @@ -53,10 +54,10 @@ var getAccounts = function(req, res) { callback(null, queryTotalSupply > 0 ? queryTotalSupply : null); } }, - function(totalSupply, callback) { + function (totalSupply, callback) { if (!count) { // get the number of all accounts - Account.count({}, function(err, count) { + Account.count({}, (err, count) => { if (err) { callbck(err); return; @@ -68,16 +69,16 @@ var getAccounts = function(req, res) { } else { callback(null, totalSupply, count); } - } - ], function(error, totalSupply, count) { + }, + ], (error, totalSupply, count) => { if (error) { - res.write(JSON.stringify({"error": true})); + res.write(JSON.stringify({ 'error': true })); res.end(); return; } // check sort order - var sortOrder = { balance: -1 }; + let sortOrder = { balance: -1 }; if (req.body.order && req.body.order[0] && req.body.order[0].column) { // balance column if (req.body.order[0].column == 3) { @@ -94,30 +95,28 @@ var getAccounts = function(req, res) { } // set datatable params - var limit = parseInt(req.body.length); - var start = parseInt(req.body.start); + const limit = parseInt(req.body.length); + const start = parseInt(req.body.start); - var data = { draw: parseInt(req.body.draw), recordsFiltered: count, recordsTotal: count }; + const data = { draw: parseInt(req.body.draw), recordsFiltered: count, recordsTotal: count }; if (totalSupply > 0) { data.totalSupply = totalSupply; } - Account.find({}).lean(true).sort(sortOrder).skip(start).limit(limit) - .exec(function (err, accounts) { + Account.find({}).lean(true).sort(sortOrder).skip(start) + .limit(limit) + .exec((err, accounts) => { if (err) { - res.write(JSON.stringify({"error": true})); + res.write(JSON.stringify({ 'error': true })); res.end(); return; } - data.data = accounts.map(function(account, i) { - return [i + 1 + start, account.address, account.type, account.balance, account.blockNumber]; - }); + data.data = accounts.map((account, i) => [i + 1 + start, account.address, account.type, account.balance, account.blockNumber]); res.write(JSON.stringify(data)); res.end(); - } - ); + }); }); -} +}; module.exports = getAccounts; diff --git a/routes/stats.js b/routes/stats.js index 68943f409..243ba5a8e 100644 --- a/routes/stats.js +++ b/routes/stats.js @@ -1,17 +1,18 @@ -var mongoose = require( 'mongoose' ); -var Block = mongoose.model( 'Block' ); -var BlockStat = mongoose.model( 'BlockStat' ); -var filters = require('./filters'); +const mongoose = require('mongoose'); -var https = require('https'); -var async = require('async'); +const Block = mongoose.model('Block'); +const BlockStat = mongoose.model('BlockStat'); -var etherUnits = require(__lib + "etherUnits.js") +const https = require('https'); +const async = require('async'); +const filters = require('./filters'); -var config = {}; +const etherUnits = require(`${__lib}etherUnits.js`); + +let config = {}; try { config = require('../config.json'); -} catch(e) { +} catch (e) { if (e.code == 'MODULE_NOT_FOUND') { console.log('No config file found. Using default configuration... (config.example.json)'); config = require('../config.example.json'); @@ -21,26 +22,18 @@ try { } } -module.exports = function(req, res) { +module.exports = function (req, res) { - if (!("action" in req.body)) - res.status(400).send(); - - else if (req.body.action=="miners") - getMinerStats(req, res) - - else if (req.body.action=="hashrate") - getHashrate(res); + if (!('action' in req.body)) res.status(400).send(); - else if (req.body.action=="hashrates") - getHashrates(req, res); - -} + else if (req.body.action == 'miners') { getMinerStats(req, res); } else if (req.body.action == 'hashrate') { getHashrate(res); } else if (req.body.action == 'hashrates') getHashrates(req, res); + +}; /** Aggregate miner stats **/ -var getMinerStats = function(req, res) { - var range = 6*60*60; // 6 hours +var getMinerStats = function (req, res) { + let range = 6 * 60 * 60; // 6 hours // check validity of range if (req.body.range && req.body.range < 60 * 60 * 24 * 7) { range = parseInt(req.body.range); @@ -49,31 +42,34 @@ var getMinerStats = function(req, res) { } } - var timebefore = parseInt((new Date())/1000) - range; - Block.find({ timestamp: { $lte: timebefore } }, "timestamp number") - .lean(true).sort('-number').limit(1).exec(function (err, docs) { - if (err || !docs) { - console.error(err); - res.status(500).send(); - res.end(); - return; - } - var blockNumber = docs[0].number; - console.log('getMinerStats(): blockNumber = ' + blockNumber); - Block.aggregate([ + const timebefore = parseInt((new Date()) / 1000) - range; + Block.find({ timestamp: { $lte: timebefore } }, 'timestamp number') + .lean(true).sort('-number').limit(1) + .exec((err, docs) => { + if (err || !docs) { + console.error(err); + res.status(500).send(); + res.end(); + return; + } + const blockNumber = docs[0].number; + console.log(`getMinerStats(): blockNumber = ${blockNumber}`); + Block.aggregate([ { $match: { number: { $gte: blockNumber } } }, - { $group: { - _id: '$miner', - timestamp: {$min: '$timestamp' }, - count: {$sum: 1} } - } - ], function (err, result) { + { + $group: { + _id: '$miner', + timestamp: { $min: '$timestamp' }, + count: { $sum: 1 }, + }, + }, + ], (err, result) => { if (err) { console.error(err); res.status(500).send(); } else { if (config.settings.miners) { - result.forEach(function(m) { + result.forEach((m) => { if (config.settings.miners[m._id]) { m._id = config.settings.miners[m._id]; } @@ -82,22 +78,22 @@ var getMinerStats = function(req, res) { res.write(JSON.stringify(result)); res.end(); } + }); }); - }); -} +}; /** Aggregate network hashrates **/ -var getHashrates = function(req, res) { +var getHashrates = function (req, res) { // setup default range //var range = 7 * 24 * 60 * 60; /* 7 days */ //var range = 14 * 24 * 60 * 60; /* 14 days */ //var range = 30 * 24 * 60 * 60; /* 1 months */ //var range = 2 * 30 * 24 * 60 * 60; /* 2 months */ - var range = 6 * 30 * 24 * 60 * 60; /* 6 months */ + let range = 6 * 30 * 24 * 60 * 60; /* 6 months */ if (req.body.days && req.body.days <= 365) { - var days = parseInt(req.body.days); + let days = parseInt(req.body.days); if (days <= 1) { days = 1; } @@ -110,131 +106,133 @@ var getHashrates = function(req, res) { } // select mod - var rngs = [ 30*60, 60*60, 2*60*60, 4*60*60, 6*60*60, - 12*60*60, 24*60*60, 7*24*60*60, 14*24*60*60, 30*24*60*60 - ]; - var mods = [ 1, 1, 2, 10, 10, - 15, 30, 15*60, 30*60, 30*60, - 60*60 - ]; - var i = 0; - rngs.forEach(function(r) { + const rngs = [30 * 60, 60 * 60, 2 * 60 * 60, 4 * 60 * 60, 6 * 60 * 60, + 12 * 60 * 60, 24 * 60 * 60, 7 * 24 * 60 * 60, 14 * 24 * 60 * 60, 30 * 24 * 60 * 60, + ]; + const mods = [1, 1, 2, 10, 10, + 15, 30, 15 * 60, 30 * 60, 30 * 60, + 60 * 60, + ]; + let i = 0; + rngs.forEach((r) => { if (range > r) { i++; } - return; + }); - var mod = mods[i]; + const mod = mods[i]; - var timestamp = parseInt((new Date())/1000) - range; + const timestamp = parseInt((new Date()) / 1000) - range; BlockStat.aggregate([ { $match: { timestamp: { $gte: timestamp } } }, - { $group: { - _id: { + { + $group: { + _id: { timestamp: { - $subtract: [ '$timestamp', { $mod: [ '$timestamp', mod ] } ] - } + $subtract: ['$timestamp', { $mod: ['$timestamp', mod] }], + }, + }, + blockTime: { $avg: '$blockTime' }, + difficulty: { $max: '$difficulty' }, + count: { $sum: 1 }, }, - blockTime: { $avg: '$blockTime' }, - difficulty: { $max: '$difficulty' }, - count: { $sum: 1 } - }}, - { $project: { - "_id": 0, - "timestamp": '$_id.timestamp', - "blockTime": 1, - "difficulty": 1, - "count": 1, - } - }]).sort('timestamp').exec(function(err, docs) { - var hashrates = []; - docs.forEach(function(doc) { + }, + { + $project: { + '_id': 0, + 'timestamp': '$_id.timestamp', + 'blockTime': 1, + 'difficulty': 1, + 'count': 1, + }, + }]).sort('timestamp').exec((err, docs) => { + const hashrates = []; + docs.forEach((doc) => { doc.instantHashrate = doc.difficulty / doc.blockTime; doc.unixtime = doc.timestamp; /* FIXME */ doc.timestamp = doc.timestamp; }); - res.write(JSON.stringify({"hashrates": docs})); + res.write(JSON.stringify({ 'hashrates': docs })); res.end(); }); -} +}; /** Get hashrate Diff stuff **/ -var getHashrate = function(res) { - var blockFind = Block.find({}, "difficulty timestamp number") - .lean(true).sort('-number').limit(100); - blockFind.exec(function (err, docs) { - var blockTime = (docs[0].timestamp - docs[99].timestamp)/100; - var hashrate = docs[0].difficulty / blockTime; +var getHashrate = function (res) { + const blockFind = Block.find({}, 'difficulty timestamp number') + .lean(true).sort('-number').limit(100); + blockFind.exec((err, docs) => { + const blockTime = (docs[0].timestamp - docs[99].timestamp) / 100; + const hashrate = docs[0].difficulty / blockTime; res.write(JSON.stringify({ - "blocks": docs, - "hashrate": hashrate, - "blockTime": blockTime, - "blockHeight": docs[0].number, - "difficulty": docs[0].difficulty + 'blocks': docs, + 'hashrate': hashrate, + 'blockTime': blockTime, + 'blockHeight': docs[0].number, + 'difficulty': docs[0].difficulty, })); res.end(); }); -} +}; /** OLD CODE DON'T USE Swipe ETC ETH data **/ -var getEtcEth = function(res) { - var options = [{ +const getEtcEth = function (res) { + const options = [{ host: 'api.minergate.com', path: '/1.0/etc/status', method: 'GET', - data: 'etc' - },{ + data: 'etc', + }, { host: 'api.minergate.com', path: '/1.0/eth/status', method: 'GET', - data: 'eth' + data: 'eth', }]; - - async.map(options, function(opt, callback) { - - https.request(opt, function(mg) { - mg.on('data', function (data) { + + async.map(options, (opt, callback) => { + + https.request(opt, (mg) => { + mg.on('data', (data) => { try { - var result = JSON.parse(data.toString()); + const result = JSON.parse(data.toString()); result.chain = opt.data; callback(null, result); } catch (e) { callback(e); } - }) + }); }).end(); - }, function(err, results) { + }, (err, results) => { if (err) { console.error(err); res.status(500).send(); } else { - if (results.length < 2) - res.status(500).send(); + if (results.length < 2) res.status(500).send(); else { - var c = ((results[0].chain == "etc") ? 0 : 1); - var h = 1 - c; - var etcHashrate = parseInt(results[c].instantHashrate); - var ethHashrate = parseInt(results[h].instantHashrate); - var etcDiff = results[c].difficulty.toFixed(2); - var ethDiff = results[h].difficulty.toFixed(2); - var etcEthHash = parseInt(100*etcHashrate/ethHashrate); - var etcEthDiff = parseInt(100*etcDiff/ethDiff); + const c = ((results[0].chain == 'etc') ? 0 : 1); + const h = 1 - c; + const etcHashrate = parseInt(results[c].instantHashrate); + const ethHashrate = parseInt(results[h].instantHashrate); + const etcDiff = results[c].difficulty.toFixed(2); + const ethDiff = results[h].difficulty.toFixed(2); + const etcEthHash = parseInt(100 * etcHashrate / ethHashrate); + const etcEthDiff = parseInt(100 * etcDiff / ethDiff); res.write(JSON.stringify({ - "etcHashrate": etcHashrate, - "ethHashrate": ethHashrate, - "etcDiff": etcDiff, - "ethDiff": ethDiff, - "etcEthHash": etcEthHash, - "etcEthDiff": etcEthDiff + 'etcHashrate': etcHashrate, + 'ethHashrate': ethHashrate, + 'etcDiff': etcDiff, + 'ethDiff': ethDiff, + 'etcEthHash': etcEthHash, + 'etcEthDiff': etcEthDiff, })); res.end(); - } + } } }); -} +}; diff --git a/routes/token.js b/routes/token.js index 5ef57629a..716d21dff 100644 --- a/routes/token.js +++ b/routes/token.js @@ -4,6 +4,35 @@ Endpoint for client interface with ERC-20 tokens */ +<<<<<<< HEAD +const { eth } = require('./web3relay'); + +const BigNumber = require('bignumber.js'); + +const etherUnits = require(`${__lib}etherUnits.js`); + +const ABI = [{ + 'constant': true, 'inputs': [], 'name': 'name', 'outputs': [{ 'name': '', 'type': 'string' }], 'payable': false, 'type': 'function', +}, { + 'constant': true, 'inputs': [], 'name': 'totalSupply', 'outputs': [{ 'name': '', 'type': 'uint256' }], 'payable': false, 'type': 'function', +}, { + 'constant': true, 'inputs': [], 'name': 'decimals', 'outputs': [{ 'name': '', 'type': 'uint8' }], 'payable': false, 'type': 'function', +}, { + 'constant': true, 'inputs': [{ 'name': '', 'type': 'address' }], 'name': 'balanceOf', 'outputs': [{ 'name': '', 'type': 'uint256' }], 'payable': false, 'type': 'function', +}, { + 'constant': true, 'inputs': [], 'name': 'symbol', 'outputs': [{ 'name': '', 'type': 'string' }], 'payable': false, 'type': 'function', +}]; + +module.exports = async (req, res) => { + console.log(req.body); + + const contractAddress = req.body.address; + + const Token = new eth.Contract(ABI, contractAddress); + + if (!('action' in req.body)) res.status(400).send(); + else if (req.body.action == 'info') { +======= require( '../db.js' ); var mongoose = require( 'mongoose' ); @@ -92,9 +121,25 @@ module.exports = function(req, res){ } catch (e) { decimals = 0; } +>>>>>>> 0b8c4c3885e581183f3777ca1993136c3386be4e try { - var actualBalance = eth.getBalance(contractAddress); + let actualBalance = await eth.getBalance(contractAddress); actualBalance = etherUnits.toEther(actualBalance, 'wei'); +<<<<<<< HEAD + const totalSupply = await Token.methods.totalSupply().call(); + const name = await Token.methods.name().call(); + const symbol = await Token.methods.symbol().call(); + const count = await eth.getTransactionCount(contractAddress); + + const tokenData = { + 'balance': actualBalance, + 'total_supply': totalSupply, + 'count': count, + 'name': name, + 'symbol': symbol, + 'bytecode': await eth.getCode(contractAddress), + }; +======= var totalSupply = token.totalSupply(); var name = token.name(); var symbol = token.symbol(); @@ -117,11 +162,19 @@ module.exports = function(req, res){ "decimals": decimals, "bytecode": eth.getCode(contractAddress) } +>>>>>>> 0b8c4c3885e581183f3777ca1993136c3386be4e res.write(JSON.stringify(tokenData)); res.end(); } catch (e) { console.error(e); } +<<<<<<< HEAD + } else if (req.body.action == 'balanceOf') { + const addr = req.body.user.toLowerCase(); + try { + const tokens = await Token.methods.balanceOf(addr).call(); + res.write(JSON.stringify({ 'tokens': tokens })); +======= } else if (req.body.action=="balanceOf") { var addr = req.body.user.toLowerCase(); var decimals = 0; @@ -136,6 +189,7 @@ module.exports = function(req, res){ var divisor = new BigNumber(10).pow(decimalsBN); tokens = tokens.dividedBy(divisor); res.write(JSON.stringify({"tokens": tokens})); +>>>>>>> 0b8c4c3885e581183f3777ca1993136c3386be4e res.end(); } catch (e) { var tokens = token.balanceOf(addr); @@ -164,6 +218,11 @@ module.exports = function(req, res){ } catch (e) { decimals = 0; } +<<<<<<< HEAD + } + +}; +======= var decimalsBN = new BigNumber(decimals); var divisor = new BigNumber(10).pow(decimalsBN); @@ -325,4 +384,5 @@ module.exports = function(req, res){ }; -const MAX_ENTRIES = 20; \ No newline at end of file +const MAX_ENTRIES = 20; +>>>>>>> 0b8c4c3885e581183f3777ca1993136c3386be4e diff --git a/routes/web3dummy.js b/routes/web3dummy.js deleted file mode 100644 index 9cc7a56ae..000000000 --- a/routes/web3dummy.js +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env node - -/* - Stand-in for local testing of web3 calls -*/ -var BigNumber = require('bignumber.js'); -var etherUnits = require(__lib + "etherUnits.js") - -exports.data = function(req, res){ - console.log(req.body) - - if ("addr" in req.body) { - var addr = req.body.addr.toLowerCase(); - var options = req.body.options; - var web3Tasks = []; - - var addrData = {}; - - if (options.indexOf("balance") > -1) { - addrData["balance"] = new BigNumber(75380000001024); - addrData["balance"] = etherUnits.toEther(addrData["balance"], 'wei'); - } - if (options.indexOf("count") > -1) { - addrData["count"] = 139; - } - if (options.indexOf("bytecode") > -1) { - addrData["isContract"] = true; - addrData["bytecode"] = "0x606060405273da4a4626d3e16e094de3225a751aab7128e96526600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550610462806100516000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e6e504a1461005a5780633ccfd60b14610069578063eedcf50a14610078578063fdf97cb2146100b157610058565b005b61006760048050506100ea565b005b6100766004805050610277565b005b6100856004805050610424565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100be600480505061043c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166318160ddd604051817c01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823130604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f11561000257505050604051805190602001503073ffffffffffffffffffffffffffffffffffffffff16310103604051809050600060405180830381858888f19350505050505b565b600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823133604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f1156100025750505060405180519060200150905073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166323b872dd333084604051847c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150158061041657503373ffffffffffffffffffffffffffffffffffffffff16600082604051809050600060405180830381858888f19350505050155b1561042057610002565b5b50565b73bb9bc244d798123fde783fcc1c72d3bb8c18941381565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156"; - } - - res.write(JSON.stringify(addrData)); - res.end(); - - - } else if ("tx" in req.body) { - var tx = { - blockHash: "0x59fee9b288d1201841ca59569026a93fa0e32f350224019747145cc52d2877ba", - blockNumber: 2004907, - from: "0xf9436cd1bc93805bd54326dbb8857e15e9e5ef4a", - gas: 90000, - gasPrice: 20000000000, - hash: "0x3868a24286d737841f42c55384b5593111defccfcec4a2d0b38115d67b10af6c", - input: "0x", - nonce: 3042, - to: "0x7172e090ef7aad8fb5b58052040587aaf248d7be", - transactionIndex: 5, - value: etherUnits.toEther( new BigNumber("400000000000000000000"), "wei") - } - - res.write(JSON.stringify(tx)); - res.end(); - - } else { - - console.error("Invalid Request: " + action) - res.status(400).send(); - } - -}; - -exports.eth = new function() { - this.getCode = function(addr) { - return "0x606060405273da4a4626d3e16e094de3225a751aab7128e96526600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550610462806100516000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e6e504a1461005a5780633ccfd60b14610069578063eedcf50a14610078578063fdf97cb2146100b157610058565b005b61006760048050506100ea565b005b6100766004805050610277565b005b6100856004805050610424565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100be600480505061043c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166318160ddd604051817c01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823130604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f11561000257505050604051805190602001503073ffffffffffffffffffffffffffffffffffffffff16310103604051809050600060405180830381858888f19350505050505b565b600073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166370a0823133604051827c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506020604051808303816000876161da5a03f1156100025750505060405180519060200150905073bb9bc244d798123fde783fcc1c72d3bb8c18941373ffffffffffffffffffffffffffffffffffffffff166323b872dd333084604051847c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506020604051808303816000876161da5a03f1156100025750505060405180519060200150158061041657503373ffffffffffffffffffffffffffffffffffffffff16600082604051809050600060405180830381858888f19350505050155b1561042057610002565b5b50565b73bb9bc244d798123fde783fcc1c72d3bb8c18941381565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156"; - } -} diff --git a/routes/web3relay.js b/routes/web3relay.js index 88d66a4f9..f53fa699c 100644 --- a/routes/web3relay.js +++ b/routes/web3relay.js @@ -4,9 +4,10 @@ Endpoint for client to talk to etc node */ -var Web3 = require("web3"); -var web3; +const Web3 = require('web3'); +const web3explorer = require('web3-explorer'); +let web3; var _ = require('lodash'); var BigNumber = require('bignumber.js'); var etherUnits = require(__lib + "etherUnits.js") @@ -18,9 +19,21 @@ var mongoose = require( 'mongoose' ); var Contract = mongoose.model( 'Contract' ); var Transaction = mongoose.model( 'Transaction' ); -var getLatestBlocks = require('./index').getLatestBlocks; -var filterBlocks = require('./filters').filterBlocks; -var filterTrace = require('./filters').filterTrace; +const _ = require('lodash'); +const BigNumber = require('bignumber.js'); + +const etherUnits = require(`${__lib}etherUnits.js`); + +require('../db.js'); +const mongoose = require('mongoose'); + +const Block = mongoose.model('Block'); +const Transaction = mongoose.model('Transaction'); +const Market = mongoose.model('Market'); + +const { getLatestBlocks } = require('./index'); +const { filterBlocks } = require('./filters'); +const { filterTrace } = require('./filters'); const ERC20ABI = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"},{"name":"data","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferAnyERC20Token","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenOwner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Approval","type":"event"}]; @@ -33,20 +46,20 @@ const KnownMethodIDs = { /*Start config for node connection and sync*/ // load config.json -var config = { nodeAddr: 'localhost', gethPort: 8545 }; +const config = { nodeAddr: 'localhost', wsPort: 8546 }; try { - var local = require('../config.json'); - _.extend(config, local); - console.log('config.json found.'); + var local = require('../config.json'); + _.extend(config, local); + console.log('config.json found.'); } catch (error) { - if (error.code === 'MODULE_NOT_FOUND') { - var local = require('../config.example.json'); - _.extend(config, local); - console.log('No config file found. Using default configuration... (config.example.json)'); - } else { - throw error; - process.exit(1); - } + if (error.code === 'MODULE_NOT_FOUND') { + var local = require('../config.example.json'); + _.extend(config, local); + console.log('No config file found. Using default configuration... (config.example.json)'); + } else { + throw error; + process.exit(1); + } } // load token list @@ -64,67 +77,103 @@ const KnownTokens = KnownTokenList.map((token)=> { }); //Create Web3 connection -console.log('Connecting ' + config.nodeAddr + ':' + config.gethPort + '...'); -if (typeof web3 !== "undefined") { - web3 = new Web3(web3.currentProvider); -} else { - web3 = new Web3(new Web3.providers.HttpProvider('http://'+config.nodeAddr+':'+config.gethPort)); -} +console.log(`Connecting ${config.nodeAddr}:${config.wsPort}...`); +web3 = new Web3(new Web3.providers.WebsocketProvider(`ws://${config.nodeAddr}:${config.wsPort}`)); -if (web3.isConnected()) - console.log("Web3 connection established"); -else - throw "No connection, please specify web3host in conf.json"; +if (web3.eth.net.isListening()) console.log('Web3 connection established'); +else throw 'No connection, please specify web3host in conf.json'; -if (web3.version.node.split('/')[0].toLowerCase().includes('parity')) { - // parity extension - web3 = require("../lib/trace.js")(web3); -} +async function detectNode() { + const nodeInfo = await web3.eth.getNodeInfo(); -var newBlocks = web3.eth.filter("latest"); -var newTxs = web3.eth.filter("pending"); + if (nodeInfo.split('/')[0].toLowerCase().includes('parity')) { + console.log('Web3 has detected parity node configuration'); + web3explorer(web3); + } + console.log(`Node version = ${nodeInfo}`); +} +detectNode(); -exports.data = function(req, res){ - console.log(req.body) +exports.data = async (req, res) => { + console.log(req.body); - if ("tx" in req.body) { + if ('tx' in req.body) { var txHash = req.body.tx.toLowerCase(); - web3.eth.getTransaction(txHash, function(err, tx) { - if(err || !tx) { - console.error("TxWeb3 error :" + err) - if (!tx) { - web3.eth.getBlock(txHash, function(err, block) { - if(err || !block) { - console.error("BlockWeb3 error :" + err) - res.write(JSON.stringify({"error": true})); + Transaction.findOne({ hash: txHash }).lean(true).exec(async (err, doc) => { + if (err || !doc) { + web3.eth.getTransaction(txHash, (err, tx) => { + if (err || !tx) { + console.error(`TxWeb3 error :${err}`); + if (!tx) { + web3.eth.getBlock(txHash, (err, block) => { + if (err || !block) { + console.error(`BlockWeb3 error :${err}`); + res.write(JSON.stringify({ 'error': true })); + } else { + console.log(`BlockWeb3 found: ${txHash}`); + res.write(JSON.stringify({ 'error': true, 'isBlock': true })); + } + res.end(); + }); } else { - console.log("BlockWeb3 found: " + txHash) - res.write(JSON.stringify({"error": true, "isBlock": true})); + res.write(JSON.stringify({ 'error': true })); + res.end(); } - res.end(); - }); - } else { - res.write(JSON.stringify({"error": true})); - res.end(); - } - } else { - var ttx = tx; - ttx.value = etherUnits.toEther( new BigNumber(tx.value), "wei"); - //get timestamp from block - var block = web3.eth.getBlock(tx.blockNumber, function(err, block) { - if (!err && block) - ttx.timestamp = block.timestamp; - ttx.isTrace = (ttx.input != "0x"); - res.write(JSON.stringify(ttx)); - res.end(); + } else { + const ttx = tx; + ttx.value = etherUnits.toEther(new BigNumber(tx.value), 'wei'); + //get TxReceipt status & gasUsed + web3.eth.getTransactionReceipt(txHash, (err, receipt) => { + if (err) { + console.error(err); + return; + } + ttx.gasUsed = receipt.gasUsed; + if (receipt.status) { + ttx.status = receipt.status; + } + if (!tx.to && !tx.creates) { + if (receipt && receipt.contractAddress) { + ttx.creates = receipt.contractAddress; + } + } + }); + //get timestamp from block + const block = web3.eth.getBlock(tx.blockNumber, (err, block) => { + if (!err && block) ttx.timestamp = block.timestamp; + ttx.isTrace = (ttx.input != '0x'); + txResponse = ttx; + }); + } }); + } else { + txResponse = doc; } + + const latestBlock = await web3.eth.getBlockNumber() + 1; + + txResponse.confirmations = latestBlock - txResponse.blockNumber; + + if (txResponse.confirmations === latestBlock) { + txResponse.confirmation = 0; + } + txResponse.gasPriceGwei = etherUnits.toGwei(new BigNumber(txResponse.gasPrice), 'wei'); + txResponse.gasPriceEther = etherUnits.toEther(new BigNumber(txResponse.gasPrice), 'wei'); + txResponse.txFee = txResponse.gasPriceEther * txResponse.gasUsed; + + if (config.settings.useFiat) { + const latestPrice = await Market.findOne().sort({ timestamp: -1 }); + txResponse.txFeeUSD = txResponse.txFee * latestPrice.quoteUSD; + txResponse.valueUSD = txResponse.value * latestPrice.quoteUSD; + } + + res.write(JSON.stringify(txResponse)); + res.end(); }); - } else if ("tx_trace" in req.body) { + } else if ('tx_trace' in req.body) { var txHash = req.body.tx_trace.toLowerCase(); - async.waterfall([ function(callback) { web3.eth.getTransaction(txHash, function(err, tx) { @@ -244,7 +293,7 @@ exports.data = function(req, res){ } res.end(); }); - } else if ("addr_trace" in req.body) { + } else if ('addr_trace' in req.body) { var addr = req.body.addr_trace.toLowerCase(); // need to filter both to and from // from block to end block, paging "toAddress":[addr], @@ -511,37 +560,35 @@ exports.data = function(req, res){ }); } else if ("addr" in req.body) { var addr = req.body.addr.toLowerCase(); - var options = req.body.options; + const { options } = req.body; - var addrData = {}; + let addrData = {}; - if (options.indexOf("balance") > -1) { + if (options.indexOf('balance') > -1) { try { - addrData["balance"] = web3.eth.getBalance(addr); - addrData["balance"] = etherUnits.toEther(addrData["balance"], 'wei'); - } catch(err) { - console.error("AddrWeb3 error :" + err); - addrData = {"error": true}; + addrData['balance'] = await web3.eth.getBalance(addr); + addrData['balance'] = etherUnits.toEther(addrData['balance'], 'wei'); + } catch (err) { + console.error(`AddrWeb3 error :${err}`); + addrData = { 'error': true }; } } - if (options.indexOf("count") > -1) { + if (options.indexOf('count') > -1) { try { - addrData["count"] = web3.eth.getTransactionCount(addr); + addrData['count'] = await web3.eth.getTransactionCount(addr); } catch (err) { - console.error("AddrWeb3 error :" + err); - addrData = {"error": true}; + console.error(`AddrWeb3 error :${err}`); + addrData = { 'error': true }; } } - if (options.indexOf("bytecode") > -1) { + if (options.indexOf('bytecode') > -1) { try { - addrData["bytecode"] = web3.eth.getCode(addr); - if (addrData["bytecode"].length > 2) - addrData["isContract"] = true; - else - addrData["isContract"] = false; + addrData['bytecode'] = await web3.eth.getCode(addr); + if (addrData['bytecode'].length > 2) addrData['isContract'] = true; + else addrData['isContract'] = false; } catch (err) { - console.error("AddrWeb3 error :" + err); - addrData = {"error": true}; + console.error(`AddrWeb3 error :${err}`); + addrData = { 'error': true }; } // is it a ERC20 compatible token? @@ -559,96 +606,113 @@ exports.data = function(req, res){ } } } - - res.write(JSON.stringify(addrData)); - res.end(); + if (config.settings.useFiat) { + const latestPrice = await Market.findOne().sort({ timestamp: -1 }); + addrData['balanceUSD'] = addrData.balance * latestPrice.quoteUSD; + } - } else if ("block" in req.body) { + res.write(JSON.stringify(addrData)); + res.end(); + } else if ('block' in req.body) { var blockNumOrHash; if (/^(0x)?[0-9a-f]{64}$/i.test(req.body.block.trim())) { - blockNumOrHash = req.body.block.toLowerCase(); + blockNumOrHash = req.body.block.toLowerCase(); } else { - blockNumOrHash = parseInt(req.body.block); + blockNumOrHash = parseInt(req.body.block); } - web3.eth.getBlock(blockNumOrHash, function(err, block) { - if(err || !block) { - console.error("BlockWeb3 error :" + err) - res.write(JSON.stringify({"error": true})); + Block.findOne({ $or: [{ hash: blockNumOrHash }, { number: blockNumOrHash }] }, + { '_id': 0 }).lean(true).exec('findOne', (err, doc) => { + if (err || !doc) { + web3.eth.getBlock(blockNumOrHash, (err, block) => { + if (err || !block) { + console.error(`BlockWeb3 error :${err}`); + res.write(JSON.stringify({ 'error': true })); + } else { + res.write(JSON.stringify(filterBlocks(block))); + } + res.end(); + }); } else { - res.write(JSON.stringify(filterBlocks(block))); + Transaction.find({ blockNumber: doc.number }).distinct('hash', (err, txs) => { + doc['transactions'] = txs; + res.write(JSON.stringify(filterBlocks(doc))); + res.end(); + }); } - res.end(); }); - /* + /* / TODO: Refactor, "block" / "uncle" determinations should likely come later / Can parse out the request once and then determine the path. */ - } else if ("uncle" in req.body) { - var uncle = req.body.uncle.trim(); - var arr = uncle.split('/'); + } else if ('uncle' in req.body) { + const uncle = req.body.uncle.trim(); + const arr = uncle.split('/'); var blockNumOrHash; // Ugly, does the same as blockNumOrHash above - var uncleIdx = parseInt(arr[1]) || 0; + const uncleIdx = parseInt(arr[1]) || 0; if (/^(?:0x)?[0-9a-f]{64}$/i.test(arr[0])) { blockNumOrHash = arr[0].toLowerCase(); - console.log(blockNumOrHash) + console.log(blockNumOrHash); } else { blockNumOrHash = parseInt(arr[0]); } - if (typeof blockNumOrHash == 'undefined') { - console.error("UncleWeb3 error :" + err); - res.write(JSON.stringify({"error": true})); + if (typeof blockNumOrHash === 'undefined') { + console.error(`UncleWeb3 error :${err}`); + res.write(JSON.stringify({ 'error': true })); res.end(); return; } - web3.eth.getUncle(blockNumOrHash, uncleIdx, function(err, uncle) { - if(err || !uncle) { - console.error("UncleWeb3 error :" + err) - res.write(JSON.stringify({"error": true})); + web3.eth.getBlock(blockNumOrHash, uncleIdx, (err, uncle) => { + if (err || !uncle) { + console.error(`UncleWeb3 error :${err}`); + res.write(JSON.stringify({ 'error': true })); } else { res.write(JSON.stringify(filterBlocks(uncle))); } res.end(); }); - } else if ("action" in req.body) { + } else if ('action' in req.body) { if (req.body.action == 'hashrate') { - web3.eth.getBlock('latest', function(err, latest) { - if(err || !latest) { - console.error("StatsWeb3 error :" + err); - res.write(JSON.stringify({"error": true})); + web3.eth.getBlock('latest', (err, latest) => { + if (err || !latest) { + console.error(`StatsWeb3 error :${err}`); + res.write(JSON.stringify({ 'error': true })); res.end(); } else { - console.log("StatsWeb3: latest block: " + latest.number); - var checknum = latest.number - 100; - if(checknum < 0) - checknum = 0; - var nblock = latest.number - checknum; - web3.eth.getBlock(checknum, function(err, block) { - if(err || !block) { - console.error("StatsWeb3 error :" + err); - res.write(JSON.stringify({"blockHeight": latest.number, "difficulty": latest.difficulty, "blockTime": 0, "hashrate": 0 })); + console.log(`StatsWeb3: latest block: ${latest.number}`); + let checknum = latest.number - 100; + if (checknum < 0) checknum = 0; + const nblock = latest.number - checknum; + web3.eth.getBlock(checknum, (err, block) => { + if (err || !block) { + console.error(`StatsWeb3 error :${err}`); + res.write(JSON.stringify({ + 'blockHeight': latest.number, 'difficulty': latest.difficulty, 'blockTime': 0, 'hashrate': 0, + })); } else { - console.log("StatsWeb3: check block: " + block.number); - var blocktime = (latest.timestamp - block.timestamp) / nblock; - var hashrate = latest.difficulty / blocktime; - res.write(JSON.stringify({"blockHeight": latest.number, "difficulty": latest.difficulty, "blockTime": blocktime, "hashrate": hashrate })); + console.log(`StatsWeb3: check block: ${block.number}`); + const blocktime = (latest.timestamp - block.timestamp) / nblock; + const hashrate = latest.difficulty / blocktime; + res.write(JSON.stringify({ + 'blockHeight': latest.number, 'difficulty': latest.difficulty, 'blockTime': blocktime, 'hashrate': hashrate, + })); } res.end(); }); } }); } else { - console.error("Invalid Request: " + action) + console.error(`Invalid Request: ${action}`); res.status(400).send(); } } else { - console.error("Invalid Request: " + action) + console.error(`Invalid Request: ${action}`); res.status(400).send(); } diff --git a/test/index.js b/test/index.js index f10b66ce1..83522bc4f 100644 --- a/test/index.js +++ b/test/index.js @@ -1,14 +1,13 @@ -var assert = require('assert'); - +const assert = require('assert'); //* load unit tests *// -var app = require('./units/apps'); +const app = require('./units/apps'); //* end unit tests *// /* tests to run (add tests here) */ -describe('Global functions', function() { - app +describe('Global functions', () => { + app; }); diff --git a/test/units/apps.js b/test/units/apps.js index 61b7fc7a7..2efae94e8 100644 --- a/test/units/apps.js +++ b/test/units/apps.js @@ -1,10 +1,10 @@ -var assert = require('assert'); -var expect = require('chai').expect; -var request = require('request'); +const assert = require('assert'); +const { expect } = require('chai'); +const request = require('request'); //* unit under test *// -var app = require('../../app.js'); +const app = require('../../app.js'); /* Description: * tests that the express server is basically functional @@ -12,24 +12,24 @@ var app = require('../../app.js'); module.exports = -describe("Classic Explorer Server Tests", function() { +describe('Classic Explorer Server Tests', () => { - //ping the index page to ensure it is running + //ping the index page to ensure it is running - describe("Test index page", function() { - var url = "http://localhost:3000/"; - it("returns status 200", function(done) { - request(url, function(error, response, body) { + describe('Test index page', () => { + const url = 'http://localhost:3000/'; + it('returns status 200', (done) => { + request(url, (error, response, body) => { expect(response.statusCode).to.equal(200); done(); }); }); - // return the 404 on a bad page request + // return the 404 on a bad page request - var badurl = "http://localhost:3000/ethereum_classic_is_best_classic"; - it("bad pages go to index", function(done) { - request(badurl, function(error, response, body) { + const badurl = 'http://localhost:3000/ethereum_classic_is_best_classic'; + it('bad pages go to index', (done) => { + request(badurl, (error, response, body) => { expect(response.statusCode).to.equal(200); done(); }); diff --git a/tools/blockHelper.js b/tools/blockHelper.js deleted file mode 100644 index 9cb243757..000000000 --- a/tools/blockHelper.js +++ /dev/null @@ -1,207 +0,0 @@ -require( '../db.js' ); -var etherUnits = require("../lib/etherUnits.js"); -var BigNumber = require('bignumber.js'); - -var Web3 = require('web3'); - -var mongoose = require( 'mongoose' ); -var Block = mongoose.model( 'Block' ); -var Transaction = mongoose.model( 'Transaction' ); - -var grabBlocks = function(config) { - if('listenOnly' in config && config.listenOnly === true) - listenBlocks(config, web3); - else - setTimeout(function() { - grabBlock(config, web3, config.blocks.pop()); - }, 2000); -} - -var listenBlocks = function(config, web3) { - var newBlocks = web3.eth.filter("latest"); - newBlocks.watch(function (error, log) { - if(error) { - console.log('Error: ' + error); - } else if (log == null) { - console.log('Warning: null block hash'); - } else { - grabBlock(config, web3, log); - } - }); -} - -var grabBlock = function(config, web3, blockHashOrNumber) { - var desiredBlockHashOrNumber; - // check if done - if(blockHashOrNumber == undefined) { - return; - } - if (typeof blockHashOrNumber === 'object') { - if('start' in blockHashOrNumber && 'end' in blockHashOrNumber) { - desiredBlockHashOrNumber = blockHashOrNumber.end; - } - else { - console.log('Error: Aborted becasue found a interval in blocks ' + - 'array that doesn\'t have both a start and end.'); - process.exit(9); - } - } - else { - desiredBlockHashOrNumber = blockHashOrNumber; - } - if(web3.isConnected()) { - web3.eth.getBlock(desiredBlockHashOrNumber, true, function(error, blockData) { - if(error) { - console.log('Warning: error on getting block with hash/number: ' + - desiredBlockHashOrNumber + ': ' + error); - } - else if(blockData == null) { - console.log('Warning: null block data received from the block with hash/number: ' + - desiredBlockHashOrNumber); - } - else { - if('terminateAtExistingDB' in config && config.terminateAtExistingDB === true) { - checkBlockDBExistsThenWrite(config, blockData); - } - else { - writeBlockToDB(config, blockData); - } - if (!('skipTransactions' in config && config.skipTransactions === true)) - writeTransactionsToDB(config, blockData); - if('listenOnly' in config && config.listenOnly === true) - return; - - if('hash' in blockData && 'number' in blockData) { - // If currently working on an interval (typeof blockHashOrNumber === 'object') and - // the block number or block hash just grabbed isn't equal to the start yet: - // then grab the parent block number ( - 1). Otherwise done - // with this interval object (or not currently working on an interval) - // -> so move onto the next thing in the blocks array. - if(typeof blockHashOrNumber === 'object' && - ( - (typeof blockHashOrNumber['start'] === 'string' && blockData['hash'] !== blockHashOrNumber['start']) || - (typeof blockHashOrNumber['start'] === 'number' && blockData['number'] > blockHashOrNumber['start']) - ) - ) { - blockHashOrNumber['end'] = blockData['number'] - 1; - grabBlock(config, web3, blockHashOrNumber); - } - else { - grabBlock(config, web3, config.blocks.pop()); - } - } - else { - console.log('Error: No hash or number was found for block: ' + blockHashOrNumber); - process.exit(9); - } - } - }); - } - else { - console.log('Error: Aborted due to web3 is not connected when trying to ' + - 'get block ' + desiredBlockHashOrNumber); - process.exit(9); - } -} - -var writeBlockToDB = function(config, blockData) { - return new Block(blockData).save( function( err, block, count ){ - if ( typeof err !== 'undefined' && err ) { - if (err.code == 11000) { - console.log('Skip: Duplicate key ' + - blockData.number.toString() + ': ' + - err); - } else { - console.log('Error: Aborted due to error on ' + - 'block number ' + blockData.number.toString() + ': ' + - err); - process.exit(9); - } - } else { - if(!('quiet' in config && config.quiet === true)) { - console.log('DB successfully written for block number ' + - blockData.number.toString() ); - } - } - }); -} - -/** - * Checks if the a record exists for the block number then -> - * if record exists: abort - * if record DNE: write a file for the block - */ -var checkBlockDBExistsThenWrite = function(config, blockData) { - Block.find({number: blockData.number}, function (err, b) { - if (!b.length) - writeBlockToDB(config, blockData); - else { - console.log('Aborting because block number: ' + blockData.number.toString() + - ' already exists in DB.'); - process.exit(9); - } - - }) -} - -/** - Break transactions out of blocks and write to DB -**/ -var writeTransactionsToDB = function(config, blockData) { - var bulkOps = []; - if (blockData.transactions.length > 0) { - for (d in blockData.transactions) { - var txData = blockData.transactions[d]; - txData.timestamp = blockData.timestamp; - txData.value = etherUnits.toEther(new BigNumber(txData.value), 'wei'); - bulkOps.push(txData); - } - Transaction.collection.insert(bulkOps, function( err, tx ){ - if ( typeof err !== 'undefined' && err ) { - if (err.code == 11000) { - console.log('Skip: Duplicate key ' + - err); - } else { - console.log('Error: Aborted due to error: ' + - err); - process.exit(9); - } - } else if(!('quiet' in config && config.quiet === true)) { - console.log('DB successfully written for block ' + - blockData.transactions.length.toString() ); - } - }); - } -} - -// load config.json -var config = { nodeAddr: 'localhost', gethPort: 8545, bulkSize: 100 }; -try { - var local = require('../config.json'); - _.extend(config, local); - console.log('config.json found.'); -} catch (error) { - if (error.code === 'MODULE_NOT_FOUND') { - var local = require('../config.example.json'); - _.extend(config, local); - console.log('No config file found. Using default configuration... (config.example.json)'); - } else { - throw error; - process.exit(1); - } -} - -console.log('Connecting ' + config.nodeAddr + ':' + config.gethPort + '...'); - -var web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.nodeAddr + ':' + config.gethPort.toString())); - -// set the default blocks if it's not provided -if (!('blocks' in config) || !(Array.isArray(config.blocks))) { - config.blocks = []; - config.blocks.push({'start': 0, 'end': 'latest'}); -} - -console.log('Using configuration:'); -console.log(config); - -grabBlocks(config); diff --git a/tools/richlist.js b/tools/richlist.js index 7e3c34258..34d535468 100644 --- a/tools/richlist.js +++ b/tools/richlist.js @@ -3,21 +3,41 @@ * Tool for calculating richlist by hackyminer */ -var _ = require('lodash'); -var Web3 = require('web3'); -var async = require('async'); -var BigNumber = require('bignumber.js'); -var mongoose = require('mongoose'); +const _ = require('lodash'); +const Web3 = require('web3'); +const web3explorer = require('web3-explorer'); +const asyncL = require('async'); +const BigNumber = require('bignumber.js'); +const mongoose = require('mongoose'); -var Account = require('../db.js').Account; -var Transaction = require('../db.js').Transaction; -var Block = require('../db.js').Block; +const { Account } = require('../db.js'); +const { Transaction } = require('../db.js'); +const { Block } = require('../db.js'); const ADDRESS_CACHE_MAX = 10000; // address cache threshold +/** + * Start config for node connection and sync + */ +const config = { nodeAddr: 'localhost', 'wsPort': 8546 }; +// load the config.json file +try { + const loaded = require('../config.json'); + _.extend(config, loaded); + console.log('config.json found.'); +} catch (error) { + console.log('No config file found.'); + throw error; + process.exit(1); +} + +console.log(`Connecting ${config.nodeAddr}:${config.wsPort}...`); +// Sets address for RPC WEB3 to connect to, usually your node IP address defaults ot localhost +const web3 = new Web3(new Web3.providers.WebsocketProvider(`ws://${config.nodeAddr}:${config.wsPort.toString()}`)); + // RichList for Geth Classic, Geth function makeRichList(toBlock, blocks, updateCallback) { - var self = makeRichList; + const self = makeRichList; if (!self.cached) { self.cached = {}; self.index = 0; @@ -25,33 +45,35 @@ function makeRichList(toBlock, blocks, updateCallback) { if (!self.accounts) { self.accounts = {}; } - var fromBlock = toBlock - blocks; + let fromBlock = toBlock - blocks; if (fromBlock < 0) { fromBlock = 0; } - console.log('Scan accounts from ' + fromBlock + ' to ' + toBlock + ' ...'); + if (!('quiet' in config && config.quiet === true)) { + console.log(`Scan accounts from ${fromBlock} to ${toBlock} ...`); + } - var ended = false; + let ended = false; if (fromBlock == toBlock) { ended = true; } - async.waterfall([ - function(callback) { + asyncL.waterfall([ + function (callback) { // Transaction.distinct("from", { blockNumber: { $lte: toBlock, $gt: fromBlock } }, function(err, docs) ... // faster // dictint("from") Transaction.aggregate([ { $match: { blockNumber: { $lte: toBlock, $gt: fromBlock } } }, - { $group: { _id: '$from' }}, - { $project: { "_id": 1 }} - ]).exec(function(err, docs) { + { $group: { _id: '$from' } }, + { $project: { '_id': 1 } }, + ]).exec((err, docs) => { if (err) { console.log(err); return; } - docs.forEach(function(doc) { + docs.forEach((doc) => { // check address cache if (!self.cached[doc._id]) { self.accounts[doc._id] = { address: doc._id, type: 0 }; @@ -63,18 +85,18 @@ function makeRichList(toBlock, blocks, updateCallback) { }); callback(null); }); - }, function(callback) { + }, function (callback) { // dictint("to") Transaction.aggregate([ { $match: { blockNumber: { $lte: toBlock, $gt: fromBlock } } }, - { $group: { _id: '$to' }}, - { $project: { "_id": 1 }} - ]).exec(function(err, docs) { + { $group: { _id: '$to' } }, + { $project: { '_id': 1 } }, + ]).exec((err, docs) => { if (err) { - console.log(err); - return; + console.log(err); + return; } - docs.forEach(function(doc) { + docs.forEach((doc) => { // to == null case if (!doc._id) { return; @@ -88,18 +110,18 @@ function makeRichList(toBlock, blocks, updateCallback) { }); callback(null); }); - }, function(callback) { + }, function (callback) { // aggregate miner's addresses Block.aggregate([ { $match: { number: { $lte: toBlock, $gt: fromBlock } } }, - { $group: { _id: '$miner' }}, - { $project: { "_id": 1 }} - ]).exec(function(err, docs) { + { $group: { _id: '$miner' } }, + { $project: { '_id': 1 } }, + ]).exec((err, docs) => { if (err) { - console.log(err); - return; + console.log(err); + return; } - docs.forEach(function(doc) { + docs.forEach((doc) => { if (!self.cached[doc._id]) { self.accounts[doc._id] = { address: doc._id, type: 0 }; self.cached[doc._id] = 1; @@ -109,92 +131,52 @@ function makeRichList(toBlock, blocks, updateCallback) { }); callback(null); }); - }, function(callback) { - let len = Object.keys(self.accounts).length; - console.info('* ' + len + ' / ' + (self.index + len) + ' total accounts.'); - if (updateCallback && (len >= 200 || ended)) { + }, function (callback) { + const len = Object.keys(self.accounts).length; + console.info(`* ${len} / ${self.index + len} total accounts.`); + if (updateCallback && (len >= 100 || ended)) { self.index += len; - console.log("* update " + len + " accounts ..."); + if (!('quiet' in config && config.quiet === true)) { + console.log(`* update ${len} accounts ...`); + } // split accounts into chunks to make proper sized json-rpc batch job. - var accounts = Object.keys(self.accounts); - var chunks = []; + const accounts = Object.keys(self.accounts); + const chunks = []; // about ~1000 `eth_getBalance` json rpc calls are possible in one json-rpc batchjob. - while (accounts.length > 800) { - var chunk = accounts.splice(0, 500); + while (accounts.length > 200) { + const chunk = accounts.splice(0, 100); chunks.push(chunk); } if (accounts.length > 0) { chunks.push(accounts); } - async.eachSeries(chunks, function(chunk, outerCallback) { - var data = {}; - // get account type + getBalance using json rpc batch job - async.waterfall([ - function(innerCallback) { - var batch = web3.createBatch(); - - for (var i = 0; i < chunk.length; i++) { - var account = chunk[i]; - batch.add(web3.eth.getCode.request(account)); - } - - batch.requestManager.sendBatch(batch.requests, function(err, results) { + asyncL.eachSeries(chunks, (chunk, outerCallback) => { + const data = {}; + asyncL.eachSeries(chunk, (account, eachCallback) => { + web3.eth.getCode(account, (err, code) => { if (err) { - console.log("ERROR: fail to getCode batch job:", err); - innerCallback(err); - return; + return eachCallback(err); } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var code = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - var account = batch.requests[i].params[0]; - data[account] = { address: account }; - if (code.length > 2) { - // 0: normal address, 1: contract - data[account].type = 1; // contract case - } else if (self.accounts[account]) { - data[account].type = self.accounts[account].type; - } - - }); - innerCallback(null, data); - }); - }, function(data, innerCallback) { - // batch rpc job - var batch = web3.createBatch(); - for (var i = 0; i < chunk.length; i++) { - var account = chunk[i]; - batch.add(web3.eth.getBalance.request(account)); - } - - batch.requestManager.sendBatch(batch.requests, function(err, results) { - if (err) { - console.log("ERROR: fail to getBalance batch job:", err); - innerCallback(err); - return; + data[account] = { address: account }; + if (code.length > 2) { + data[account].type = 1; // contract type + } else if (self.accounts[account]) { + data[account].type = self.accounts[account].type; } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var balance = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - - let ether; - if (typeof balance === 'object') { - ether = parseFloat(balance.div(1e18).toString()); - } else { - ether = balance / 1e18; + + web3.eth.getBalance(account, (err, balance) => { + if (err) { + return eachCallback(err); } - data[batch.requests[i].params[0]].balance = ether; + + data[account].balance = parseFloat(web3.utils.fromWei(balance, 'ether')); + eachCallback(); }); - innerCallback(null, data); }); - }], function(err) { + }, (err) => { if (err) { return outerCallback(err); } @@ -204,22 +186,21 @@ function makeRichList(toBlock, blocks, updateCallback) { outerCallback(); }); - }, function(error) { + }, (error) => { if (error) { - console.log("WARN: fail to call getBalance() " + error); + console.log(`WARN: fail to call getBalance() ${error}`); } // reset accounts self.accounts = {}; // check the size of the cached accounts if (Object.keys(self.cached).length > ADDRESS_CACHE_MAX) { - console.info("** reduce cached accounts ..."); - var sorted = Object.keys(self.cached).sort(function(a, b) { - return self.cached[b] - self.cached[a]; // descend order - }); - var newcached = {}; - var reduce = parseInt(ADDRESS_CACHE_MAX * 0.6); - for (var j = 0; j < reduce; j++) { + console.info('** reduce cached accounts ...'); + const sorted = Object.keys(self.cached).sort((a, b) => self.cached[b] - self.cached[a], // descend order + ); + const newcached = {}; + const reduce = parseInt(ADDRESS_CACHE_MAX * 0.6); + for (let j = 0; j < reduce; j++) { newcached[sorted[j]] = self.cached[sorted[j]]; } self.cached = newcached; @@ -230,17 +211,17 @@ function makeRichList(toBlock, blocks, updateCallback) { } else { callback(null); } - } - ], function(error) { + }, + ], (error) => { if (error) { console.log(error); return; } if (ended) { - console.log("**DONE**"); + console.log('**DONE**'); } else { - setTimeout(function() { + setTimeout(() => { makeRichList(fromBlock, blocks, updateCallback); }, 300); } @@ -248,102 +229,65 @@ function makeRichList(toBlock, blocks, updateCallback) { } function makeParityRichList(number, offset, blockNumber, updateCallback) { - var self = makeParityRichList; + const self = makeParityRichList; if (!self.index) { self.index = 0; } number = number || 100; offset = offset || null; - async.waterfall([ - function(callback) { - web3.parity.listAccounts(number, offset, blockNumber, function(err, result) { + asyncL.waterfall([ + function (callback) { + web3.parity.listAccounts(number, offset, blockNumber, (err, result) => { callback(err, result); }); - }, function(accounts, callback) { + }, function (accounts, callback) { if (!accounts) { return callback({ error: true, - message: "No accounts found. Please restart Parity with --fat-db=on option to enable FatDB." + message: 'No accounts found. Please restart Parity with --fat-db=on option to enable FatDB.', }); } if (accounts.length === 0) { return callback({ error: true, - message: "No more accounts found." + message: 'No more accounts found.', }); } - var lastAccount = accounts[accounts.length - 1]; - var data = {}; - - // get account type + getBalance using json rpc batch job - async.waterfall([ - function(innerCallback) { - var batch = web3.createBatch(); - - for (var i = 0; i < accounts.length; i++) { - var account = accounts[i]; - batch.add(web3.eth.getCode.request(account)); - } + const lastAccount = accounts[accounts.length - 1]; + const data = {}; - batch.requestManager.sendBatch(batch.requests, function(err, results) { + // Please see https://github.com/gobitfly/etherchain-light by gobitfly + asyncL.eachSeries(accounts, (account, eachCallback) => { + web3.eth.getCode(account, (err, code) => { if (err) { - console.log("ERROR: fail to getCode batch job:", err); - innerCallback(err); - return; + console.log(`ERROR: fail to getCode(${account})`); + return eachCallback(err); } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var code = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - var account = batch.requests[i].params[0]; - data[account] = { address: account }; - if (code.length > 2) { - // 0: normal address, 1: contract - data[account].type = 1; // contract case - } - - }); - innerCallback(null, data); - }); - }, function(data, innerCallback) { - // batch rpc job - var batch = web3.createBatch(); - for (var i = 0; i < accounts.length; i++) { - var account = accounts[i]; - batch.add(web3.eth.getBalance.request(account)); - } - - batch.requestManager.sendBatch(batch.requests, function(err, results) { - if (err) { - console.log("ERROR: fail to getBalance batch job:", err); - innerCallback(err); - return; + data[account] = {}; + data[account].address = account; + if (code.length > 2) { + // 0: normal address, 1: contract + data[account].type = 1; //contract case } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var balance = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - - let ether; - if (typeof balance === 'object') { - ether = parseFloat(balance.div(1e18).toString()); - } else { - ether = balance / 1e18; + + web3.eth.getBalance(account, (err, balance) => { + if (err) { + console.log(`ERROR: fail to getBalance(${account})`); + return eachCallback(err); } - data[batch.requests[i].params[0]].balance = ether; + + data[account].balance = parseFloat(web3.utils.fromWei(balance, 'ether')); + eachCallback(); }); - innerCallback(null, data); }); - }], function(err) { + }, (err) => { callback(err, data, lastAccount); }); - } - ], function(error, accounts, lastAccount) { + }, + ], (error, accounts, lastAccount) => { if (error) { console.log(error); process.exit(9); @@ -352,13 +296,15 @@ function makeParityRichList(number, offset, blockNumber, updateCallback) { //console.log(JSON.stringify(accounts, null, 2)); offset = lastAccount; - let j = Object.keys(accounts).length; + const j = Object.keys(accounts).length; self.index += j; - console.log(' * ' + j + ' / ' + self.index + ' accounts, offset = ' + offset); + if (!('quiet' in config && config.quiet === true)) { + console.log(` * ${j} / ${self.index} accounts, offset = ${offset}`); + } if (updateCallback) { updateCallback(accounts, blockNumber); } - setTimeout(function() { + setTimeout(() => { makeParityRichList(number, lastAccount, blockNumber, updateCallback); }, 300); }); @@ -367,33 +313,33 @@ function makeParityRichList(number, offset, blockNumber, updateCallback) { /** * Write accounts to DB */ -var updateAccounts = function(accounts, blockNumber) { +const updateAccounts = function (accounts, blockNumber) { // prepare - var bulk = Object.keys(accounts).map(function(j) { - let account = accounts[j]; + const bulk = Object.keys(accounts).map((j) => { + const account = accounts[j]; account.blockNumber = blockNumber; return account; }); bulkInsert(bulk); -} +}; -var bulkInsert = function(bulk) { +var bulkInsert = function (bulk) { if (!bulk.length) { return; } - var localbulk; + let localbulk; if (bulk.length > 300) { localbulk = bulk.splice(0, 200); } else { localbulk = bulk.splice(0, 300); } - Account.collection.insert(localbulk, function(error, data) { + Account.collection.insert(localbulk, (error, data) => { if (error) { if (error.code == 11000) { // For already exists case, try upsert method. - async.eachSeries(localbulk, function(item, eachCallback) { + asyncL.eachSeries(localbulk, (item, eachCallback) => { // upsert accounts item._id = undefined; delete item._id; // remove _id field @@ -402,161 +348,133 @@ var bulkInsert = function(bulk) { item.type = undefined; delete item.type; } - Account.collection.update({ "address": item.address }, { $set: item }, { upsert: true }, function(err, updated) { + Account.collection.update({ 'address': item.address }, { $set: item }, { upsert: true }, (err, updated) => { if (err) { if (!config.quiet) { - console.log('WARN: Duplicate DB key : ' + error); - console.log('ERROR: Fail to update account: ' + err); + console.log(`WARN: Duplicate DB key : ${error}`); + console.log(`ERROR: Fail to update account: ${err}`); } return eachCallback(err); } eachCallback(); }); - }, function(err) { + }, (err) => { if (err) { if (err.code != 11000) { - console.log('ERROR: Aborted due to error: ' + JSON.stringify(err, null, 2)); + console.log(`ERROR: Aborted due to error: ${JSON.stringify(err, null, 2)}`); process.exit(9); return; - } else { - console.log('WARN: Fail to upsert (ignore) ' + err); } + console.log(`WARN: Fail to upsert (ignore) ${err}`); + + } + if (!('quiet' in config && config.quiet === true)) { + console.log(`* ${localbulk.length} accounts successfully updated.`); } - console.log('* ' + localbulk.length + ' accounts successfully updated.'); if (bulk.length > 0) { - setTimeout(function() { + setTimeout(() => { bulkInsert(bulk); }, 200); } }); } else { - console.log('Error: Aborted due to error on DB: ' + error); + console.log(`Error: Aborted due to error on DB: ${error}`); process.exit(9); } } else { - console.log('* ' + data.insertedCount + ' accounts successfully inserted.'); + if (!('quiet' in config && config.quiet === true)) { + console.log(`* ${data.insertedCount} accounts successfully inserted.`); + } if (bulk.length > 0) { - setTimeout(function() { + setTimeout(() => { bulkInsert(bulk); }, 200); } } }); -} +}; function prepareJsonAddress(json, defaultType = 0) { - var accounts = {}; + const accounts = {}; if (json.accounts) { // genesis.json style - Object.keys(json.accounts).forEach(function(account) { - var key = account.toLowerCase(); - key = '0x' + key.replace(/^0x/, ''); - accounts[key] = { address: key, type: type }; + Object.keys(json.accounts).forEach((account) => { + let key = account.toLowerCase(); + key = `0x${key.replace(/^0x/, '')}`; + accounts[key] = { address: key, type }; }); } else if (typeof json === 'object') { - Object.keys(json).forEach(function(account) { - var key = account.toLowerCase(); - key = '0x' + key.replace(/^0x/, ''); - var type = defaultType; + Object.keys(json).forEach((account) => { + let key = account.toLowerCase(); + key = `0x${key.replace(/^0x/, '')}`; + let type = defaultType; if (json[account].type) { type = json[account].type; } - accounts[key] = { address: key, type: type }; + accounts[key] = { address: key, type }; }); } else { // normal array - json.forEach(function(account) { - var key = account.toLowerCase(); - key = '0x' + key.replace(/^0x/, ''); - accounts[key] = { address: key, type: type }; + json.forEach((account) => { + let key = account.toLowerCase(); + key = `0x${key.replace(/^0x/, '')}`; + accounts[key] = { address: key, type }; }); } return accounts; } function readJsonAccounts(json, blockNumber, callback, defaultType = 0) { - var data = prepareJsonAddress(json, defaultType); - var accounts = Object.keys(data); - console.log("* update " + accounts.length + " genesis accounts..."); - - // batch rpc job - var batch = web3.createBatch(); - // normally, the request size of batch getBalance() of all accounts is not bigger than 128kB. - // simply getBalance at once using rpc batch job. - for (var i = 0; i < accounts.length; i++) { - var account = accounts[i]; - batch.add(web3.eth.getBalance.request(account)); - } + const data = prepareJsonAddress(json, defaultType); + const accounts = Object.keys(data); + console.log(`* update ${accounts.length} genesis accounts...`); + async.eachSeries(accounts, (account, eachCallback) => { + web3.eth.getBalance(account, (err, balance) => { + if (err) { + console.log(`ERROR: fail to getBalance(${account})`); + return eachCallback(err); + } - batch.requestManager.sendBatch(batch.requests, function(err, results) { + data[account].balance = parseFloat(web3.utils.fromWei(balance, 'ether')); + eachCallback(); + }); + }, (err) => { if (err) { - console.log("ERROR: fail to getBalance batch job:", err); + console.log(`ERROR: fail to getBalance()${err}`); return; } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var balance = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - - let ether; - if (typeof balance === 'object') { - ether = parseFloat(balance.div(1e18).toString()); - } else { - ether = balance / 1e18; - } - data[batch.requests[i].params[0]].balance = ether; - }); callback(data, blockNumber); }); } -/** - * Start config for node connection and sync - */ -var config = { nodeAddr: 'localhost', 'gethPort': 8545 }; -// load the config.json file -try { - var loaded = require('../config.json'); - _.extend(config, loaded); - console.log('config.json found.'); -} catch (error) { - console.log('No config file found.'); - throw error; - process.exit(1); -} - // temporary turn on some debug //config.quiet = false; //mongoose.set('debug', true); -console.log('Connecting ' + config.nodeAddr + ':' + config.gethPort + '...'); +async function startSync() { + const latestBlock = await web3.eth.getBlockNumber(); + const nodeInfo = await web3.eth.getNodeInfo(); -var web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.nodeAddr + ':' + config.gethPort.toString())); + console.log(`Node version = ${nodeInfo}`); -var useParity = false; -if (!process.env.NOPARITY - && web3.version.node.split('/')[0].toLowerCase().includes('parity')) { - // load parity extension - web3 = require("../lib/trace.js")(web3); - useParity = true; -} - -var latestBlock = web3.eth.blockNumber; - -// run -console.log("* latestBlock = " + latestBlock); - -if (useParity) { - makeParityRichList(500, null, latestBlock, updateAccounts); -} else { - // load genesis account - if (config.settings && config.settings.genesisAddress) { - try { - var genesis = require('../' + config.settings.genesisAddress); - readJsonAccounts(genesis, latestBlock, updateAccounts); - } catch (e) { - console.log("Error: Fail to load genesis address (ignore)"); + if (nodeInfo.split('/')[0].toLowerCase().includes('parity')) { + console.log('Web3 has detected parity node configuration'); + web3explorer(web3); + console.log(`* latestBlock = ${latestBlock}`); + makeParityRichList(500, null, latestBlock, updateAccounts); + } else { + // load genesis account + if (config.settings && config.settings.genesisAddress) { + try { + const genesis = require(`../${config.settings.genesisAddress}`); + readJsonAccounts(genesis, latestBlock, updateAccounts); + } catch (e) { + console.log('Error: Fail to load genesis address (ignore)'); + } + } + if ('quiet' in config && config.quiet === true) { + console.log('Quiet mode enabled'); } + makeRichList(latestBlock, 500, updateAccounts); } - makeRichList(latestBlock, 500, updateAccounts); } +startSync(); diff --git a/tools/stats.js b/tools/stats.js index 2c912ed25..d92344f17 100644 --- a/tools/stats.js +++ b/tools/stats.js @@ -2,120 +2,140 @@ Tool for calculating block stats */ -var _ = require('lodash'); -var Web3 = require('web3'); +const _ = require('lodash'); +const Web3 = require('web3'); -var mongoose = require( 'mongoose' ); -var BlockStat = require( '../db.js' ).BlockStat; +const mongoose = require('mongoose'); +const { BlockStat } = require('../db.js'); -var updateStats = function(range, interval, rescan) { - var latestBlock = web3.eth.blockNumber; - - interval = Math.abs(parseInt(interval)); - if (!range) { - range = 1000; - } - range *= interval; - if (interval >= 10) { - latestBlock -= latestBlock % interval; - } - getStats(web3, latestBlock, null, latestBlock - range, interval, rescan); +// load config.json +const config = { nodeAddr: 'localhost', wsPort: 8546, bulkSize: 100 }; +try { + var local = require('../config.json'); + _.extend(config, local); + console.log('config.json found.'); +} catch (error) { + if (error.code === 'MODULE_NOT_FOUND') { + var local = require('../config.example.json'); + _.extend(config, local); + console.log('No config file found. Using default configuration... (config.example.json)'); + } else { + throw error; + process.exit(1); + } } +console.log(`Connecting ${config.nodeAddr}:${config.wsPort}...`); +// Sets address for RPC WEB3 to connect to, usually your node IP address defaults ot localhost +const web3 = new Web3(new Web3.providers.WebsocketProvider(`ws://${config.nodeAddr}:${config.wsPort.toString()}`)); +if ('quiet' in config && config.quiet === true) { + console.log('Quiet mode enabled'); +} -var getStats = function(web3, blockNumber, nextBlock, endNumber, interval, rescan) { - if (endNumber < 0) - endNumber = 0; - if (blockNumber <= endNumber) { - if (rescan) { - process.exit(9); - } - return; - } - - if(web3.isConnected()) { - - web3.eth.getBlock(blockNumber, true, function(error, blockData) { - if(error) { - console.log('Warning: error on getting block with hash/number: ' + - blockNumber + ': ' + error); - } - else if(blockData == null) { - console.log('Warning: null block data received from the block with hash/number: ' + - blockNumber); - } - else { - if (nextBlock) - checkBlockDBExistsThenWrite(web3, blockData, nextBlock, endNumber, interval, rescan); - else - checkBlockDBExistsThenWrite(web3, blockData, null, endNumber, interval, rescan); - } - }); - } else { - console.log('Error: Aborted due to web3 is not connected when trying to ' + - 'get block ' + blockNumber); - process.exit(9); +const updateStats = async (range, interval, rescan) => { + let latestBlock = await web3.eth.getBlockNumber(); + + interval = Math.abs(parseInt(interval)); + if (!range) { + range = 1000; + } + range *= interval; + if (interval >= 10) { + latestBlock -= latestBlock % interval; + } + getStats(web3, latestBlock, null, latestBlock - range, interval, rescan); +}; + +var getStats = function (web3, blockNumber, nextBlock, endNumber, interval, rescan) { + if (endNumber < 0) endNumber = 0; + if (blockNumber <= endNumber) { + if (rescan) { + process.exit(9); } -} + return; + } + + if (web3.eth.net.isListening()) { + + web3.eth.getBlock(blockNumber, true, (error, blockData) => { + if (error) { + console.log(`Warning: error on getting block with hash/number: ${ + blockNumber}: ${error}`); + } else if (blockData == null) { + console.log(`Warning: null block data received from the block with hash/number: ${ + blockNumber}`); + } else { + if (nextBlock) checkBlockDBExistsThenWrite(web3, blockData, nextBlock, endNumber, interval, rescan); + else checkBlockDBExistsThenWrite(web3, blockData, null, endNumber, interval, rescan); + } + }); + } else { + console.log(`${'Error: Aborted due to web3 is not connected when trying to ' + + 'get block '}${blockNumber}`); + process.exit(9); + } +}; /** - * Checks if the a record exists for the block number + * Checks if the a record exists for the block number * if record exists: abort * if record DNE: write a file for the block */ -var checkBlockDBExistsThenWrite = function(web3, blockData, nextBlock, endNumber, interval, rescan) { - BlockStat.find({number: blockData.number}, function (err, b) { - if (!b.length && nextBlock) { - // calc hashrate, txCount, blocktime, uncleCount - var stat = { - "number": blockData.number, - "timestamp": blockData.timestamp, - "difficulty": blockData.difficulty, - "txCount": blockData.transactions.length, - "gasUsed": blockData.gasUsed, - "gasLimit": blockData.gasLimit, - "miner": blockData.miner, - "blockTime": (nextBlock.timestamp - blockData.timestamp) / (nextBlock.number - blockData.number), - "uncleCount": blockData.uncles.length - } - new BlockStat(stat).save( function( err, s, count ){ - console.log(s) - if ( typeof err !== 'undefined' && err ) { - console.log('Error: Aborted due to error on ' + - 'block number ' + blockData.number.toString() + ': ' + - err); - process.exit(9); - } else { - console.log('DB successfully written for block number ' + - blockData.number.toString() ); - getStats(web3, blockData.number - interval, blockData, endNumber, interval, rescan); - } - }); +var checkBlockDBExistsThenWrite = function (web3, blockData, nextBlock, endNumber, interval, rescan) { + BlockStat.find({ number: blockData.number }, (err, b) => { + if (!b.length && nextBlock) { + // calc hashrate, txCount, blocktime, uncleCount + const stat = { + 'number': blockData.number, + 'timestamp': blockData.timestamp, + 'difficulty': blockData.difficulty, + 'txCount': blockData.transactions.length, + 'gasUsed': blockData.gasUsed, + 'gasLimit': blockData.gasLimit, + 'miner': blockData.miner, + 'blockTime': (nextBlock.timestamp - blockData.timestamp) / (nextBlock.number - blockData.number), + 'uncleCount': blockData.uncles.length, + }; + new BlockStat(stat).save((err, s, count) => { + if (!('quiet' in config && config.quiet === true)) { + console.log(s); + } + if (typeof err !== 'undefined' && err) { + console.log(`${'Error: Aborted due to error on ' + 'block number '}${blockData.number.toString()}: ${ + err}`); + process.exit(9); } else { - if (rescan || !nextBlock) { - getStats(web3, blockData.number - interval, blockData, endNumber, interval, rescan); - if (nextBlock) { - console.log('WARN: block number: ' + blockData.number.toString() + ' already exists in DB.'); - } - } else { - console.error('Aborting because block number: ' + blockData.number.toString() + - ' already exists in DB.'); - return; - } + if (!('quiet' in config && config.quiet === true)) { + console.log(`DB successfully written for block number ${blockData.number.toString()}`); + } + getStats(web3, blockData.number - interval, blockData, endNumber, interval, rescan); + } + }); + } else { + if (rescan || !nextBlock) { + getStats(web3, blockData.number - interval, blockData, endNumber, interval, rescan); + if (nextBlock) { + if (!('quiet' in config && config.quiet === true)) { + console.log(`WARN: block number: ${blockData.number.toString()} already exists in DB.`); + } + } + } else { + if (!('quiet' in config && config.quiet === true)) { + console.error(`Aborting because block number: ${blockData.number.toString()} already exists in DB.`); } - }) -} + } + } -/** On Startup **/ -// geth --rpc --rpcaddr "localhost" --rpcport "8545" --rpcapi "eth,net,web3" + }); +}; -var minutes = 1; +const minutes = 1; statInterval = minutes * 60 * 1000; -var rescan = false; /* rescan: true - rescan range */ -var range = 1000; -var interval = 100; +let rescan = false; /* rescan: true - rescan range */ +let range = 1000; +let interval = 100; /** * RESCAN=1000:100000 means interval;range @@ -124,50 +144,29 @@ var interval = 100; * RESCAN=1000:100000 node tools/stats.js */ if (process.env.RESCAN) { - var tmp = process.env.RESCAN.split(/:/); - if (tmp.length > 1) { - interval = Math.abs(parseInt(tmp[0])); - if (tmp[1]) { - range = Math.abs(parseInt(tmp[1])); - } - } - var i = interval; - var j = 0; - for (var j = 0; i >= 10; j++) { - i = parseInt(i / 10); - } - interval = Math.pow(10, j); - console.log('Selected interval = ' + interval); - - rescan = true; -} - -// load config.json -var config = { nodeAddr: 'localhost', gethPort: 8545, bulkSize: 100 }; -try { - var local = require('../config.json'); - _.extend(config, local); - console.log('config.json found.'); -} catch (error) { - if (error.code === 'MODULE_NOT_FOUND') { - var local = require('../config.example.json'); - _.extend(config, local); - console.log('No config file found. Using default configuration... (config.example.json)'); - } else { - throw error; - process.exit(1); + const tmp = process.env.RESCAN.split(/:/); + if (tmp.length > 1) { + interval = Math.abs(parseInt(tmp[0])); + if (tmp[1]) { + range = Math.abs(parseInt(tmp[1])); } + } + let i = interval; + var j = 0; + for (var j = 0; i >= 10; j++) { + i = parseInt(i / 10); + } + interval = Math.pow(10, j); + console.log(`Selected interval = ${interval}`); + + rescan = true; } -console.log('Connecting ' + config.nodeAddr + ':' + config.gethPort + '...'); - -var web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.nodeAddr + ':' + config.gethPort.toString())); - // run updateStats(range, interval, rescan); if (!rescan) { - setInterval(function() { - updateStats(range, interval); - }, statInterval); + setInterval(() => { + updateStats(range, interval); + }, statInterval); } diff --git a/tools/sync.js b/tools/sync.js index b4c5daa35..80f22d61c 100644 --- a/tools/sync.js +++ b/tools/sync.js @@ -4,18 +4,28 @@ Version: .0.0.2 This file will start syncing the blockchain from the node address you provide in the conf.json file. Please read the README in the root directory that explains the parameters of this code */ -require( '../db.js' ); -var etherUnits = require("../lib/etherUnits.js"); -var BigNumber = require('bignumber.js'); -var _ = require('lodash'); +require('../db.js'); +const BigNumber = require('bignumber.js'); +const _ = require('lodash'); -var async = require('async'); -var Web3 = require('web3'); +const asyncL = require('async'); +const Web3 = require('web3'); -var mongoose = require( 'mongoose' ); -var Block = mongoose.model( 'Block' ); -var Transaction = mongoose.model( 'Transaction' ); -var Account = mongoose.model( 'Account' ); +const ERC20ABI = require('human-standard-token-abi'); + +const fetch = require('node-fetch'); + +const mongoose = require('mongoose'); +const etherUnits = require('../lib/etherUnits.js'); +const { Market } = require('../db.js'); + +const Block = mongoose.model('Block'); +const Transaction = mongoose.model('Transaction'); +const Account = mongoose.model('Account'); +const Contract = mongoose.model('Contract'); +const TokenTransfer = mongoose.model('TokenTransfer'); + +const ERC20_METHOD_DIC = { '0xa9059cbb': 'transfer', '0xa978501e': 'transferFrom' }; function normalizeTX(txData, blockData) { var tx = { @@ -54,137 +64,112 @@ function normalizeTX(txData, blockData) { } /** - //Just listen for latest blocks and sync from the start of the app. + Start config for node connection and sync **/ -var listenBlocks = function(config) { - if (web3.eth.syncing) { - console.log('Info: waiting until syncing finished... (currentBlock is #' + web3.eth.syncing.currentBlock + ')'); - setTimeout(function() { listenBlocks(config); }, 10000); - return; +/** + * nodeAddr: node address + * wsPort: rpc port + * bulkSize: size of array in block to use bulk operation + */ +// load config.json +const config = { nodeAddr: 'localhost', wsPort: 8546, bulkSize: 100 }; +try { + var local = require('../config.json'); + _.extend(config, local); + console.log('config.json found.'); +} catch (error) { + if (error.code === 'MODULE_NOT_FOUND') { + var local = require('../config.example.json'); + _.extend(config, local); + console.log('No config file found. Using default configuration... (config.example.json)'); + } else { + throw error; + process.exit(1); } - var newBlocks = web3.eth.filter("latest"); - newBlocks.watch(function (error,latestBlock) { - if(error) { - console.log('Error: ' + error); - newBlocks.stopWatching(); - console.log('Retry to listen...'); - listenBlocks(config); - } else if (latestBlock == null) { - console.log('Warning: null block hash'); - } else { - console.log('Found new block: ' + latestBlock); - if(web3.isConnected()) { - web3.eth.getBlock(latestBlock, true, function(error,blockData) { - if(error) { - console.log('Warning: error on getting block with hash/number: ' + latestBlock + ': ' + error); - }else if(blockData == null) { - console.log('Warning: null block data received from the block with hash/number: ' + latestBlock); - }else{ - writeBlockToDB(config, blockData, true); - writeTransactionsToDB(config, blockData, true); - } - }); - }else{ - console.log('Error: Web3 connection time out trying to get block ' + latestBlock + ' retrying connection now'); - listenBlocks(config); - } - } - }); } -/** - If full sync is checked this function will start syncing the block chain from lastSynced param see README -**/ -var syncChain = function(config, nextBlock){ - if(web3.isConnected()) { - if (web3.eth.syncing) { - console.log('Info: waiting until syncing finished... (currentBlock is #' + web3.eth.syncing.currentBlock + ')'); - setTimeout(function() { syncChain(config, nextBlock); }, 10000); - return; - } - if (typeof nextBlock === 'undefined') { - prepareSync(config, function(error, startBlock) { - if(error) { - console.log('ERROR: error: ' + error); - return; - } - syncChain(config, startBlock); - }); - return; - } +console.log(`Connecting ${config.nodeAddr}:${config.wsPort}...`); +// Sets address for RPC WEB3 to connect to, usually your node IP address defaults ot localhost +const web3 = new Web3(new Web3.providers.WebsocketProvider(`ws://${config.nodeAddr}:${config.wsPort.toString()}`)); - if( nextBlock == null ) { - console.log('nextBlock is null'); - return; - } else if( nextBlock < config.startBlock ) { - writeBlockToDB(config, null, true); - writeTransactionsToDB(config, null, true); - console.log('*** Sync Finsihed ***'); - config.syncAll = false; - return; - } +const normalizeTX = async (txData, receipt, blockData) => { + const tx = { + blockHash: txData.blockHash, + blockNumber: txData.blockNumber, + from: txData.from.toLowerCase(), + hash: txData.hash.toLowerCase(), + value: etherUnits.toEther(new BigNumber(txData.value), 'wei'), + nonce: txData.nonce, + r: txData.r, + s: txData.s, + v: txData.v, + gas: txData.gas, + gasUsed: receipt.gasUsed, + gasPrice: String(txData.gasPrice), + input: txData.input, + transactionIndex: txData.transactionIndex, + timestamp: blockData.timestamp, + }; - var count = config.bulkSize; - while(nextBlock >= config.startBlock && count > 0) { - web3.eth.getBlock(nextBlock, true, function(error,blockData) { - if(error) { - console.log('Warning: error on getting block with hash/number: ' + nextBlock + ': ' + error); - }else if(blockData == null) { - console.log('Warning: null block data received from the block with hash/number: ' + nextBlock); - }else{ - writeBlockToDB(config, blockData); - writeTransactionsToDB(config, blockData); - } - }); - nextBlock--; - count--; - } + if (receipt.status) { + tx.status = receipt.status; + } - setTimeout(function() { syncChain(config, nextBlock); }, 500); - }else{ - console.log('Error: Web3 connection time out trying to get block ' + nextBlock + ' retrying connection now'); - syncChain(config, nextBlock); + if (txData.to) { + tx.to = txData.to.toLowerCase(); + return tx; + } else if (txData.creates) { + tx.creates = txData.creates.toLowerCase(); + return tx; + } else { + tx.creates = receipt.contractAddress.toLowerCase(); + return tx; } -} +}; + /** Write the whole block object to DB **/ -var writeBlockToDB = function(config, blockData, flush) { - var self = writeBlockToDB; +var writeBlockToDB = function (config, blockData, flush) { + const self = writeBlockToDB; if (!self.bulkOps) { self.bulkOps = []; } if (blockData && blockData.number >= 0) { self.bulkOps.push(new Block(blockData)); - console.log('\t- block #' + blockData.number.toString() + ' inserted.'); + if (!('quiet' in config && config.quiet === true)) { + console.log(`\t- block #${blockData.number.toString()} inserted.`); + } } - if(flush && self.bulkOps.length > 0 || self.bulkOps.length >= config.bulkSize) { - var bulk = self.bulkOps; + if (flush && self.bulkOps.length > 0 || self.bulkOps.length >= config.bulkSize) { + const bulk = self.bulkOps; self.bulkOps = []; - if(bulk.length == 0) return; + if (bulk.length === 0) return; - Block.collection.insert(bulk, function( err, blocks ){ - if ( typeof err !== 'undefined' && err ) { - if (err.code == 11000) { - if(!('quiet' in config && config.quiet === true)) { - console.log('Skip: Duplicate DB key : ' +err); + Block.collection.insert(bulk, (err, blocks) => { + if (typeof err !== 'undefined' && err) { + if (err.code === 11000) { + if (!('quiet' in config && config.quiet === true)) { + console.log(`Skip: Duplicate DB key : ${err}`); } - }else{ - console.log('Error: Aborted due to error on DB: ' + err); + } else { + console.log(`Error: Aborted due to error on DB: ${err}`); process.exit(9); } - }else{ - console.log('* ' + blocks.insertedCount + ' blocks successfully written.'); + } else { + if (!('quiet' in config && config.quiet === true)) { + console.log(`* ${blocks.insertedCount} blocks successfully written.`); + } } }); } -} +}; /** Break transactions out of blocks and write to DB **/ -var writeTransactionsToDB = function(config, blockData, flush) { - var self = writeTransactionsToDB; +const writeTransactionsToDB = async (config, blockData, flush) => { + const self = writeTransactionsToDB; if (!self.bulkOps) { self.bulkOps = []; self.blocks = 0; @@ -198,25 +183,116 @@ var writeTransactionsToDB = function(config, blockData, flush) { } if (blockData && blockData.transactions.length > 0) { for (d in blockData.transactions) { - var txData = blockData.transactions[d]; - - var tx = normalizeTX(txData, blockData); + const txData = blockData.transactions[d]; + const receipt = await web3.eth.getTransactionReceipt(txData.hash); + const tx = await normalizeTX(txData, receipt, blockData); + // Contact creation tx, Event logs of internal transaction + if (txData.input && txData.input.length > 2) { + // Contact creation tx + if (txData.to === null) { + // Support Parity & Geth case + if (txData.creates) { + contractAddress = txData.creates.toLowerCase(); + } else { + contractAddress = receipt.contractAddress.toLowerCase(); + } + const contractdb = {}; + let isTokenContract = true; + const Token = new web3.eth.Contract(ERC20ABI, contractAddress); + contractdb.owner = txData.from; + contractdb.blockNumber = blockData.number; + contractdb.creationTransaction = txData.hash; + try { + const call = await web3.eth.call({ to: contractAddress, data: web3.utils.sha3('totalSupply()') }); + if (call === '0x') { + isTokenContract = false; + } else { + try { + // ERC20 & ERC223 Token Standard compatible format + contractdb.tokenName = await Token.methods.name().call(); + contractdb.decimals = await Token.methods.decimals().call(); + contractdb.symbol = await Token.methods.symbol().call(); + contractdb.totalSupply = await Token.methods.totalSupply().call(); + } catch (err) { + isTokenContract = false; + } + } + } catch (err) { + isTokenContract = false; + } + contractdb.byteCode = await web3.eth.getCode(contractAddress); + if (isTokenContract) { + contractdb.ERC = 2; + } else { + // Normal Contract + contractdb.ERC = 0; + } + // Write to db + Contract.update( + { address: contractAddress }, + { $setOnInsert: contractdb }, + { upsert: true }, + (err, data) => { + if (err) { + console.log(err); + } + }, + ); + } else { + // Internal transaction . write to doc of InternalTx + const transfer = { + 'hash': '', 'blockNumber': 0, 'from': '', 'to': '', 'contract': '', 'value': 0, 'timestamp': 0, + }; + const methodCode = txData.input.substr(0, 10); + if (ERC20_METHOD_DIC[methodCode] === 'transfer' || ERC20_METHOD_DIC[methodCode] === 'transferFrom') { + if (ERC20_METHOD_DIC[methodCode] === 'transfer') { + // Token transfer transaction + transfer.from = txData.from; + transfer.to = `0x${txData.input.substring(34, 74)}`; + transfer.value = Number(`0x${txData.input.substring(74)}`); + } else { + // transferFrom + transfer.from = `0x${txData.input.substring(34, 74)}`; + transfer.to = `0x${txData.input.substring(74, 114)}`; + transfer.value = Number(`0x${txData.input.substring(114)}`); + } + transfer.method = ERC20_METHOD_DIC[methodCode]; + transfer.hash = txData.hash; + transfer.blockNumber = blockData.number; + transfer.contract = txData.to; + transfer.timestamp = blockData.timestamp; + // Write transfer transaction into db + TokenTransfer.update( + { hash: transfer.hash }, + { $setOnInsert: transfer }, + { upsert: true }, + (err, data) => { + if (err) { + console.log(err); + } + }, + ); + } + } + } self.bulkOps.push(tx); } - console.log('\t- block #' + blockData.number.toString() + ': ' + blockData.transactions.length.toString() + ' transactions recorded.'); + if (!('quiet' in config && config.quiet === true)) { + console.log(`\t- block #${blockData.number.toString()}: ${blockData.transactions.length.toString()} transactions recorded.`); + } } self.blocks++; if (flush && self.blocks > 0 || self.blocks >= config.bulkSize) { - var bulk = self.bulkOps; + const bulk = self.bulkOps; self.bulkOps = []; self.blocks = 0; - var miners = self.miners; + const { miners } = self; self.miners = []; // setup accounts - var data = {}; - bulk.forEach(function(tx) { + const data = {}; + bulk.forEach((tx) => { data[tx.from] = { address: tx.from, blockNumber: tx.blockNumber, type: 0 }; if (tx.to) { data[tx.to] = { address: tx.to, blockNumber: tx.blockNumber, type: 0 }; @@ -224,145 +300,180 @@ var writeTransactionsToDB = function(config, blockData, flush) { }); // setup miners - miners.forEach(function(miner) { + miners.forEach((miner) => { data[miner.address] = miner; }); - var accounts = Object.keys(data); + const accounts = Object.keys(data); - if (bulk.length == 0 && accounts.length == 0) return; + if (bulk.length === 0 && accounts.length === 0) return; // update balances - if (config.useRichList && accounts.length > 0) { - var n = 0; - var chunks = []; - while (accounts.length > 800) { - var chunk = accounts.splice(0, 500); - chunks.push(chunk); - } - if (accounts.length > 0) { - chunks.push(accounts); - } - async.eachSeries(chunks, function(chunk, outerCallback) { - async.waterfall([ - // get contract account type - function(callback) { - var batch = web3.createBatch(); - - for (var i = 0; i < chunk.length; i++) { - var account = chunk[i]; - batch.add(web3.eth.getCode.request(account)); - } - - batch.requestManager.sendBatch(batch.requests, function(err, results) { - if (err) { - console.log("ERROR: fail to getCode batch job:", err); - callback(err); - return; - } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var code = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - if (code.length > 2) { - data[batch.requests[i].params[0]].type = 1; // contract type - } + if (config.settings.useRichList && accounts.length > 0) { + asyncL.eachSeries(accounts, (account, eachCallback) => { + const { blockNumber } = data[account]; + // get contract account type + web3.eth.getCode(account, (err, code) => { + if (err) { + console.log(`ERROR: fail to getCode(${account})`); + return eachCallback(err); + } + if (code.length > 2) { + data[account].type = 1; // contract type + } - }); - callback(null); - }); - }, function(callback) { - // batch rpc job - var batch = web3.createBatch(); - for (var i = 0; i < chunk.length; i++) { - var account = chunk[i]; - if (account) { - batch.add(web3.eth.getBalance.request(account)); - } + web3.eth.getBalance(account, blockNumber, (err, balance) => { + if (err) { + console.log(err); + console.log(`ERROR: fail to getBalance(${account})`); + return eachCallback(err); } - batch.requestManager.sendBatch(batch.requests, function(err, results) { - if (err) { - console.log("ERROR: fail to getBalance batch job:", err); - callback(err); - return; - } - results = results || []; - batch.requests.map(function (request, index) { - return results[index] || {}; - }).forEach(function (result, i) { - var balance = batch.requests[i].format ? batch.requests[i].format(result.result) : result.result; - - let ether; - if (typeof balance === 'object') { - ether = parseFloat(balance.div(1e18).toString()); - } else { - ether = balance / 1e18; - } - var account = batch.requests[i].params[0]; - data[account].balance = ether; - - if (n <= 5) { - console.log(' - upsert ' + account + ' / balance = ' + data[account].balance); - } else if (n == 6) { - console.log(' (...) total ' + accounts.length + ' accounts updated.'); - } - n++; - // upsert account - Account.collection.update({ address: account }, { $set: data[account] }, { upsert: true }); - }); - }); - callback(null); - }], function(error) { + data[account].balance = parseFloat(web3.utils.fromWei(balance, 'ether')); + eachCallback(); + }); + }); + }, (err) => { + let n = 0; + accounts.forEach((account) => { + n++; + if (!('quiet' in config && config.quiet === true)) { + if (n <= 5) { + console.log(` - upsert ${account} / balance = ${data[account].balance}`); + } else if (n === 6) { + console.log(` (...) total ${accounts.length} accounts updated.`); + } + } + // upsert account + Account.collection.update({ address: account }, { $set: data[account] }, { upsert: true }); }); - }, function(error) { }); } - if (bulk.length > 0) - Transaction.collection.insert(bulk, function( err, tx ){ - if ( typeof err !== 'undefined' && err ) { - if (err.code == 11000) { - if(!('quiet' in config && config.quiet === true)) { - console.log('Skip: Duplicate transaction key ' + err); + if (bulk.length > 0) { + Transaction.collection.insert(bulk, (err, tx) => { + if (typeof err !== 'undefined' && err) { + if (err.code === 11000) { + if (!('quiet' in config && config.quiet === true)) { + console.log(`Skip: Duplicate transaction key ${err}`); + } + } else { + console.log(`Error: Aborted due to error on Transaction: ${err}`); + process.exit(9); + } + } else { + if (!('quiet' in config && config.quiet === true)) { + console.log(`* ${tx.insertedCount} transactions successfully recorded.`); } - }else{ - console.log('Error: Aborted due to error on Transaction: ' + err); - process.exit(9); } - }else{ - console.log('* ' + tx.insertedCount + ' transactions successfully recorded.'); + }); + } + } +}; +/** + //Just listen for latest blocks and sync from the start of the app. +**/ +const listenBlocks = function (config) { + const newBlocks = web3.eth.subscribe('newBlockHeaders', (error, result) => { + if (!error) { + return; + } + + console.error(error); + }); + newBlocks.on('data', (blockHeader) => { + web3.eth.getBlock(blockHeader.hash, true, (error, blockData) => { + if (blockHeader === null) { + console.log('Warning: null block hash'); + } else { + writeBlockToDB(config, blockData, true); + writeTransactionsToDB(config, blockData, true); } }); + }); + newBlocks.on('error', console.error); +}; +/** + If full sync is checked this function will start syncing the block chain from lastSynced param see README +**/ +var syncChain = function (config, nextBlock) { + if (web3.eth.net.isListening()) { + if (typeof nextBlock === 'undefined') { + prepareSync(config, (error, startBlock) => { + if (error) { + console.log(`ERROR: error: ${error}`); + return; + } + syncChain(config, startBlock); + }); + return; + } + + if (nextBlock === null) { + console.log('nextBlock is null'); + return; + } if (nextBlock < config.startBlock) { + writeBlockToDB(config, null, true); + writeTransactionsToDB(config, null, true); + console.log('*** Sync Finsihed ***'); + config.syncAll = false; + return; + } + + let count = config.bulkSize; + while (nextBlock >= config.startBlock && count > 0) { + web3.eth.getBlock(nextBlock, true, (error, blockData) => { + if (error) { + console.log(`Warning (syncChain): error on getting block with hash/number: ${nextBlock}: ${error}`); + } else if (blockData === null) { + console.log(`Warning: null block data received from the block with hash/number: ${nextBlock}`); + } else { + writeBlockToDB(config, blockData); + writeTransactionsToDB(config, blockData); + } + }); + nextBlock--; + count--; + } + + setTimeout(() => { syncChain(config, nextBlock); }, 500); + } else { + console.log(`Error: Web3 connection time out trying to get block ${nextBlock} retrying connection now`); + syncChain(config, nextBlock); } -} +}; /** //check oldest block or starting block then callback **/ -var prepareSync = function(config, callback) { - var blockNumber = null; - var oldBlockFind = Block.find({}, "number").lean(true).sort('number').limit(1); - oldBlockFind.exec(function (err, docs) { - if(err || !docs || docs.length < 1) { +const prepareSync = async (config, callback) => { + let blockNumber = null; + const oldBlockFind = Block.find({}, 'number').lean(true).sort('number').limit(1); + oldBlockFind.exec(async (err, docs) => { + if (err || !docs || docs.length < 1) { // not found in db. sync from config.endBlock or 'latest' - if(web3.isConnected()) { - var currentBlock = web3.eth.blockNumber; - var latestBlock = config.endBlock || currentBlock || 'latest'; - if(latestBlock === 'latest') { - web3.eth.getBlock(latestBlock, true, function(error, blockData) { - if(error) { - console.log('Warning: error on getting block with hash/number: ' + latestBlock + ': ' + error); - } else if(blockData == null) { - console.log('Warning: null block data received from the block with hash/number: ' + latestBlock); + if (web3.eth.net.isListening()) { + const currentBlock = await web3.eth.getBlockNumber(); + const latestBlock = config.endBlock || currentBlock || 'latest'; + if (latestBlock === 'latest') { + web3.eth.getBlock(latestBlock, true, (error, blockData) => { + if (error) { + console.log(`Warning (prepareSync): error on getting block with hash/number: ${latestBlock}: ${error}`); + } else if (blockData === null) { + console.log(`Warning: null block data received from the block with hash/number: ${latestBlock}`); } else { - console.log('Starting block number = ' + blockData.number); + console.log(`Starting block number = ${blockData.number}`); + if ('quiet' in config && config.quiet === true) { + console.log('Quiet mode enabled'); + } blockNumber = blockData.number - 1; callback(null, blockNumber); } }); } else { - console.log('Starting block number = ' + latestBlock); + console.log(`Starting block number = ${latestBlock}`); + if ('quiet' in config && config.quiet === true) { + console.log('Quiet mode enabled'); + } blockNumber = latestBlock - 1; callback(null, blockNumber); } @@ -370,56 +481,61 @@ var prepareSync = function(config, callback) { console.log('Error: Web3 connection error'); callback(err, null); } - }else{ + } else { blockNumber = docs[0].number - 1; - console.log('Old block found. Starting block number = ' + blockNumber); + console.log(`Old block found. Starting block number = ${blockNumber}`); + if ('quiet' in config && config.quiet === true) { + console.log('Quiet mode enabled'); + } callback(null, blockNumber); } }); -} +}; /** Block Patcher(experimental) **/ -var runPatcher = function(config, startBlock, endBlock) { - if(!web3 || !web3.isConnected()) { +const runPatcher = async (config, startBlock, endBlock) => { + if (!web3 || !web3.eth.net.isListening()) { console.log('Error: Web3 is not connected. Retrying connection shortly...'); - setTimeout(function() { runPatcher(config); }, 3000); + setTimeout(() => { runPatcher(config); }, 3000); return; } - if(typeof startBlock === 'undefined' || typeof endBlock === 'undefined') { + if (typeof startBlock === 'undefined' || typeof endBlock === 'undefined') { // get the last saved block - var blockFind = Block.find({}, "number").lean(true).sort('-number').limit(1); - blockFind.exec(function (err, docs) { - if(err || !docs || docs.length < 1) { + const blockFind = Block.find({}, 'number').lean(true).sort('-number').limit(1); + blockFind.exec(async (err, docs) => { + if (err || !docs || docs.length < 1) { // no blocks found. terminate runPatcher() console.log('No need to patch blocks.'); return; } - var lastMissingBlock = docs[0].number + 1; - var currentBlock = web3.eth.blockNumber; + const lastMissingBlock = docs[0].number + 1; + const currentBlock = await web3.eth.getBlockNumber(); runPatcher(config, lastMissingBlock, currentBlock - 1); }); return; } - var missingBlocks = endBlock - startBlock + 1; + const missingBlocks = endBlock - startBlock + 1; if (missingBlocks > 0) { - console.log('Patching from #' + startBlock + ' to #' + endBlock); - var patchBlock = startBlock; - var count = 0; - while(count < config.patchBlocks && patchBlock <= endBlock) { - if(!('quiet' in config && config.quiet === true)) { - console.log('Patching Block: ' + patchBlock) + if (!('quiet' in config && config.quiet === true)) { + console.log(`Patching from #${startBlock} to #${endBlock}`); + } + let patchBlock = startBlock; + let count = 0; + while (count < config.patchBlocks && patchBlock <= endBlock) { + if (!('quiet' in config && config.quiet === true)) { + console.log(`Patching Block: ${patchBlock}`); } - web3.eth.getBlock(patchBlock, true, function(error, patchData) { - if(error) { - console.log('Warning: error on getting block with hash/number: ' + patchBlock + ': ' + error); - } else if(patchData == null) { - console.log('Warning: null block data received from the block with hash/number: ' + patchBlock); + web3.eth.getBlock(patchBlock, true, (error, patchData) => { + if (error) { + console.log(`Warning: error on getting block with hash/number: ${patchBlock}: ${error}`); + } else if (patchData === null) { + console.log(`Warning: null block data received from the block with hash/number: ${patchBlock}`); } else { - checkBlockDBExistsThenWrite(config, patchData) + checkBlockDBExistsThenWrite(config, patchData); } }); patchBlock++; @@ -429,7 +545,7 @@ var runPatcher = function(config, startBlock, endBlock) { writeBlockToDB(config, null, true); writeTransactionsToDB(config, null, true); - setTimeout(function() { runPatcher(config, patchBlock, endBlock); }, 1000); + setTimeout(() => { runPatcher(config, patchBlock, endBlock); }, 1000); } else { // flush writeBlockToDB(config, null, true); @@ -437,52 +553,59 @@ var runPatcher = function(config, startBlock, endBlock) { console.log('*** Block Patching Completed ***'); } -} +}; /** This will be used for the patcher(experimental) **/ -var checkBlockDBExistsThenWrite = function(config, patchData, flush) { - Block.find({number: patchData.number}, function (err, b) { - if (!b.length){ +var checkBlockDBExistsThenWrite = function (config, patchData, flush) { + Block.find({ number: patchData.number }, (err, b) => { + if (!b.length) { writeBlockToDB(config, patchData, flush); writeTransactionsToDB(config, patchData, flush); - }else if(!('quiet' in config && config.quiet === true)) { - console.log('Block number: ' +patchData.number.toString() + ' already exists in DB.'); + } else if (!('quiet' in config && config.quiet === true)) { + console.log(`Block number: ${patchData.number.toString()} already exists in DB.`); } }); }; /** - Start config for node connection and sync + Fetch market price from cryptocompare **/ -/** - * nodeAddr: node address - * gethPort: geth port - * bulkSize: size of array in block to use bulk operation - */ -// load config.json -var config = { nodeAddr: 'localhost', gethPort: 8545, bulkSize: 100 }; -try { - var local = require('../config.json'); - _.extend(config, local); - console.log('config.json found.'); -} catch (error) { - if (error.code === 'MODULE_NOT_FOUND') { - var local = require('../config.example.json'); - _.extend(config, local); - console.log('No config file found. Using default configuration... (config.example.json)'); - } else { - throw error; - process.exit(1); - } -} +// 10 minutes +const quoteInterval = 10 * 60 * 1000; -console.log('Connecting ' + config.nodeAddr + ':' + config.gethPort + '...'); +const getQuote = async () => { + const options = { + timeout: 10000, + }; + const URL = `https://min-api.cryptocompare.com/data/price?fsym=${config.settings.symbol}&tsyms=USD`; -// Sets address for RPC WEB3 to connect to, usually your node IP address defaults ot localhost -var web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.nodeAddr + ':' + config.gethPort.toString())); + try { + const requestUSD = await fetch(URL); + const quoteUSD = await requestUSD.json(); + + quoteObject = { + timestamp: Math.round(Date.now() / 1000), + quoteUSD: quoteUSD.USD, + }; + + new Market(quoteObject).save((err, market, count) => { + if (typeof err !== 'undefined' && err) { + process.exit(9); + } else { + if (!('quiet' in config && config.quiet === true)) { + console.log('DB successfully written for market quote.'); + } + } + }); + } catch (error) { + if (!('quiet' in config && config.quiet === true)) { + console.log(error); + } + } +}; // patch missing blocks -if (config.patch === true){ +if (config.patch === true) { console.log('Checking for missing blocks'); runPatcher(config); } @@ -490,14 +613,23 @@ if (config.patch === true){ // check NORICHLIST env // you can use it like as 'NORICHLIST=1 node tools/sync.js' to disable balance updater temporary. if (process.env.NORICHLIST) { - config.useRichList = false; + config.settings.useRichList = false; } // Start listening for latest blocks listenBlocks(config); // Starts full sync when set to true in config -if (config.syncAll === true){ +if (config.syncAll === true) { console.log('Starting Full Sync'); syncChain(config); } + +// Start price sync on DB +if (config.settings.useFiat) { + getQuote(); + + setInterval(() => { + getQuote(); + }, quoteInterval); +} diff --git a/tools/tokens/daoTxns.js b/tools/tokens/daoTxns.js deleted file mode 100644 index 3922fcbd6..000000000 --- a/tools/tokens/daoTxns.js +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env node - -/* - Thing to get history of DAO transactions -*/ - -var Web3 = require("web3"); -var web3; -var async = require('async'); - -require( '../../db.js' ); -require( '../../db-dao.js' ); -require( '../../db-internal.js' ); -var mongoose = require( 'mongoose' ); -var Block = mongoose.model('Block'); -var DAOCreatedToken = mongoose.model('DAOCreatedToken'); -var DAOTransferToken = mongoose.model('DAOTransferToken'); -var InternalTx = mongoose.model( 'InternalTransaction' ); - -// load config.json -var config = { nodeAddr: 'localhost', gethPort: 8545 }; -try { - var local = require('../../config.json'); - _.extend(config, local); - console.log('config.json found.'); -} catch (error) { - if (error.code === 'MODULE_NOT_FOUND') { - var local = require('../../config.example.json'); - _.extend(config, local); - console.log('No config file found. Using default configuration... (config.example.json)'); - } else { - throw error; - process.exit(1); - } -} - -console.log('Connecting ' + config.nodeAddr + ':' + config.gethPort + '...'); - -if (typeof web3 !== "undefined") { - web3 = new Web3(web3.currentProvider); -} else { - web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.nodeAddr + ':' + config.gethPort.toString())); -} - -if (web3.isConnected()) - console.log("Web3 connection established"); -else - throw "No connection"; - - -var daoABI = [{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"FuelingToDate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"CreatedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"newCurator","type":"bool"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":true,"name":"voter","type":"address"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"bool"},{"indexed":false,"name":"quorum","type":"uint256"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_newCurator","type":"address"}],"name":"NewCurator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_recipient","type":"address"},{"indexed":false,"name":"_allowed","type":"bool"}],"name":"AllowedRecipientChanged","type":"event"}]; -var daoContract = web3.eth.contract(daoABI); -var DAO = daoContract.at("0xbb9bc244d798123fde783fcc1c72d3bb8c189413"); - -var creationBlock = 1428757; -var creationEnd = 1599205; - -var populateCreatedTokens = function () { - //total: 58713 - - var event = DAO.CreatedToken; - event({}, {fromBlock: creationBlock, toBlock: creationEnd}).get( function(err, log) { - if (err) { - console.error(err); - process.exit(9); - } else { - for (var l in log) { - try { - var newToken = { - "transactionHash": log[l].transactionHash, - "blockNumber": log[l].blockNumber, - "amount": log[l].args.amount, - "to": log[l].args.to - } - } catch (e) { - console.error(e); - continue; - } - - new DAOCreatedToken(newToken).save( function( err, token, count ){ - if ( typeof err !== 'undefined' && err ) { - if (err.code == 11000) { - console.log('Skip: Duplicate tx ' + - log[l].transactionHash + ': ' + - err); - } else { - console.log('Error: Aborted due to error on ' + - 'block number ' + log[l].blockNumber.toString() + ': ' + - err); - process.exit(9); - } - } else - console.log('DB successfully written for tx ' + - token.transactionHash ); - - }); - } - } - - }); -} - -var populateTransferTokens = function () { - - var event = DAO.Transfer; - event({}, {fromBlock: creationEnd, toBlock: "latest"}).get( function(err, log) { - if (err) { - console.error(err); - process.exit(9); - } else { - for (var l in log) { - try { - var newToken = { - "transactionHash": log[l].transactionHash, - "blockNumber": log[l].blockNumber, - "amount": log[l].args._amount, - "to": log[l].args._to, - "from": log[l].args._from - } - } catch (e) { - console.error(e); - continue; - } - try { - var block = web3.eth.getBlock(log[l].blockNumber); - newToken.timestamp = block.timestamp; - } catch (e) { - console.error(e); - continue; - } - new DAOTransferToken(newToken).save( function( err, token, count ){ - if ( typeof err !== 'undefined' && err ) { - if (err.code == 11000) { - console.log('Skip: Duplicate tx ' + - log[l].transactionHash + ': ' + - err); - return null; - } else { - console.log('Error: Aborted due to error on ' + - 'block number ' + log[l].blockNumber.toString() + ': ' + - err); - process.exit(9); - } - } else - console.log('DB successfully written for tx ' + - log[l].transactionHash ); - - }); - } - } - - }); -} - -var bulkTimeUpdate = function(bulk, callback) { - console.log("Bulk execution started"); - bulk.execute(function(err,result) { - if (err) - console.error(err); - else - console.log(result.toJSON()); - }); -} - - -var patchTimestamps = function(collection) { - mongoose.connection.on("open", function(err,conn) { - - var bulk = collection.initializeOrderedBulkOp(); - - var bulkOps = []; - var count = 0; - var missingCount = 5200; - collection.count({timestamp: null}, function(err, c) { - missingCount = c; - console.log("Missing: " + JSON.stringify(missingCount)); - }); - - collection.find({timestamp: null}).forEach(function(doc) { - setTimeout(function() { - try { - var block = web3.eth.getBlock(doc.blockNumber); - } catch (e) { - console.error(e); return; - } - - bulk.find({ '_id': doc._id }).updateOne({ - '$set': { 'timestamp': block.timestamp } - }); - count++; - if(count % 100 === 0) { - // Execute per 1000 operations and re-init - bulkTimeUpdate(bulk); - bulk = collection.initializeOrderedBulkOp(); - } - if(count == missingCount) { - // Clean up queues - bulkTimeUpdate(bulk); - } - }, 1000); - }); - - }) -} - -const BATCH = 1000; - -var patchBlocks = function(max, min) { - - Block.find({"number": {$gt: min, $lt: max}}, "number timestamp").lean(true).exec(function(err, docs) { - async.forEach(docs, function(doc, cb) { - var q = { 'timestamp': null, 'blockNumber': doc.number }; - InternalTx.collection.update(q, { $set: { 'timestamp': doc.timestamp }}, - {multi: true, upsert: false}, function(err, tx) { - if(err) console.error(err); - console.log(tx) - cb(); - }); - }, function() { return; }); - }); - -} - -InternalTx.collection.count({timestamp: null}, function(err, c) { - missingCount = c; - console.log("Missing: " + JSON.stringify(missingCount)); -}); - -var min; - -var max = web3.eth.blockNumber; - -setInterval(function() { - InternalTx.findOne({"timestamp": null}, "blockNumber") - .lean(true).sort('blockNumber') - .exec(function(err, doc) { - console.log(doc) - if (doc) - min = doc.blockNumber - 1; - else - min = max; - - var next = min + BATCH; - if (next > max) - process.exit(9) - - patchBlocks(next, min); - }); -}, 20000); - - -// patchTimestamps(InternalTx.collection) -// populateCreatedTokens(); -// populateTransferTokens(); diff --git a/views/index.ejs b/views/index.ejs index bab84257c..d209f5456 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -31,7 +31,7 @@ - +