diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f4b5311d5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,12 @@ +_Before filing a new issue, please **provide the following information**._ + +> I'm running: +> +> - **Parity version**: 0.0.0 +> - **Operating system**: Windows / MacOS / Linux +> - **And installed**: via installer / homebrew / binaries / from source + +_Your issue description goes here below. Try to include **actual** vs. **expected behavior** and **steps to reproduce** the issue._ + +--- + diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 26b1cc753..ed3a3675a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -561,11 +561,9 @@ docker-build: - docker info script: - if [ "$CI_BUILD_REF_NAME" == "beta-release" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi - - docker login -u $Docker_Hub_User -p $Docker_Hub_Pass - - sh scripts/docker-build.sh $DOCKER_TAG ethcore - - docker logout + - echo "Tag:" $DOCKER_TAG - docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity - - sh scripts/docker-build.sh $DOCKER_TAG parity + - sh scripts/docker-build.sh $DOCKER_TAG - docker logout tags: - docker @@ -613,11 +611,12 @@ test-rust-stable: image: parity/rust:gitlab-ci before_script: - git submodule update --init --recursive - - export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l) + - export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l) script: - rustup show - export RUST_BACKTRACE=1 - if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi + - if [ "$CI_BUILD_REF_NAME" == "nightly" ]; then sh scripts/aura-test.sh; fi tags: - rust - rust-stable diff --git a/CHANGELOG.md b/CHANGELOG.md index 29f84462d..78bf895ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,489 @@ +## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-28) + +Parity 1.7.0 is a major release introducing several important features: + +- **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. Please, note: The wallet UI integration for the light client is not included, yet. +- **Experimental web wallet**. A hosted version of Parity that keeps the keys and signs transactions using your browser storage. Try it at https://wallet.parity.io or run your own with `--public-node`. +- **WASM contract support**. Private networks can run contracts compiled into WASM bytecode. _More information and documentation to follow_. +- **DApps and RPC server merge**. DApp and RPC are now available through a single API endpoint. DApp server related settings are deprecated. +- **Export accounts from the wallet**. Backing up your keys can now simply be managed through the wallet interface. +- **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and, in the near future, light sync. +- **PubSub API**. https://github.com/paritytech/parity/wiki/JSONRPC-Parity-Pub-Sub-module +- **Signer apps for IOS and Android**. + +Full list of included changes: + +- Backports [#6163](https://github.com/paritytech/parity/pull/6163) + - Light client improvements ([#6156](https://github.com/paritytech/parity/pull/6156)) + - No seal checking + - Import command and --no-seal-check for light client + - Fix eth_call + - Tweak registry dapps lookup + - Ignore failed requests to non-server peers + - Fix connecting to wildcard addresses. ([#6167](https://github.com/paritytech/parity/pull/6167)) + - Don't display an overlay in case the time sync check fails. ([#6164](https://github.com/paritytech/parity/pull/6164)) + - Small improvements to time estimation. + - Temporarily disable NTP time check by default. +- Light client fixes ([#6148](https://github.com/paritytech/parity/pull/6148)) [#6151](https://github.com/paritytech/parity/pull/6151) + - Light client fixes + - Fix memory-lru-cache + - Clear pending reqs on disconnect +- Filter tokens logs from current block, not genesis ([#6128](https://github.com/paritytech/parity/pull/6128)) [#6141](https://github.com/paritytech/parity/pull/6141) +- Fix QR scanner returning null on confirm [#6122](https://github.com/paritytech/parity/pull/6122) +- Check QR before lowercase ([#6119](https://github.com/paritytech/parity/pull/6119)) [#6120](https://github.com/paritytech/parity/pull/6120) +- Remove chunk to restore from pending set only upon successful import [#6117](https://github.com/paritytech/parity/pull/6117) +- Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) +- Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) +- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108) +- Backported wallet fix [#6105](https://github.com/paritytech/parity/pull/6105) + - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) + - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) +- Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) +- Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) +- Bump snap version and tweak importing detection logic ([#6079](https://github.com/paritytech/parity/pull/6079)) [#6081](https://github.com/paritytech/parity/pull/6081) + - bump last tick just before printing info and restore sync detection + - bump kovan snapshot version + - Fixed sync tests + - Fixed rpc tests +- Acquire client report under lock in informant [#6071](https://github.com/paritytech/parity/pull/6071) +- Show busy indicator on Address forget [#6069](https://github.com/paritytech/parity/pull/6069) +- Add CSP for worker-src ([#6059](https://github.com/paritytech/parity/pull/6059)) [#6064](https://github.com/paritytech/parity/pull/6064) + - Specify worker-src seperately, add blob + - Upgrade react-qr-scan to latest version +- Set release channel to beta +- Limit transaction queue memory & limit future queue [#6038](https://github.com/paritytech/parity/pull/6038) +- Fix CI build issue [#6050](https://github.com/paritytech/parity/pull/6050) +- New contract PoA sync fixes [#5991](https://github.com/paritytech/parity/pull/5991) +- Fixed link to Multisig Contract Wallet on master [#5984](https://github.com/paritytech/parity/pull/5984) +- Ethcore crate split part 1 [#6041](https://github.com/paritytech/parity/pull/6041) +- Fix status icon [#6039](https://github.com/paritytech/parity/pull/6039) +- Errors & warnings for inappropriate RPCs [#6029](https://github.com/paritytech/parity/pull/6029) +- Add missing CSP for web3.site [#5992](https://github.com/paritytech/parity/pull/5992) +- Remove cargo install --git from README.md [#6037](https://github.com/paritytech/parity/pull/6037) +- Node Health warnings [#5951](https://github.com/paritytech/parity/pull/5951) +- RPC cpu pool [#6023](https://github.com/paritytech/parity/pull/6023) +- Use crates.io dependencies for parity-wasm [#6036](https://github.com/paritytech/parity/pull/6036) +- Add test for loading the chain specs [#6028](https://github.com/paritytech/parity/pull/6028) +- Whitelist APIs for generic Pub-Sub [#5840](https://github.com/paritytech/parity/pull/5840) +- WASM contracts MVP [#5679](https://github.com/paritytech/parity/pull/5679) +- Fix valid QR scan not advancing [#6033](https://github.com/paritytech/parity/pull/6033) +- --reseal-on-uncle [#5940](https://github.com/paritytech/parity/pull/5940) +- Support comments in reserved peers file ([#6004](https://github.com/paritytech/parity/pull/6004)) [#6012](https://github.com/paritytech/parity/pull/6012) +- Add new md tnc [#5937](https://github.com/paritytech/parity/pull/5937) +- Fix output of parity-evm in case of bad instruction [#5955](https://github.com/paritytech/parity/pull/5955) +- Don't send notifications to unsubscribed clients of PubSub [#5960](https://github.com/paritytech/parity/pull/5960) +- Proper light client informant and more verification of imported headers [#5897](https://github.com/paritytech/parity/pull/5897) +- New Kovan bootnodes [#6017](https://github.com/paritytech/parity/pull/6017) +- Use standard paths for Ethash cache [#5881](https://github.com/paritytech/parity/pull/5881) +- Defer code hash calculation. [#5959](https://github.com/paritytech/parity/pull/5959) +- Fix first run wizard. [#6000](https://github.com/paritytech/parity/pull/6000) +- migration to serde 1.0 [#5996](https://github.com/paritytech/parity/pull/5996) +- SecretStore: generating signatures [#5764](https://github.com/paritytech/parity/pull/5764) +- bigint upgraded to version 3.0 [#5986](https://github.com/paritytech/parity/pull/5986) +- config: don't allow dev chain with force sealing option [#5965](https://github.com/paritytech/parity/pull/5965) +- Update lockfile for miniz-sys and gcc [#5969](https://github.com/paritytech/parity/pull/5969) +- Clean up function naming in RPC error module [#5995](https://github.com/paritytech/parity/pull/5995) +- Fix underflow in gas calculation [#5975](https://github.com/paritytech/parity/pull/5975) +- PubSub for parity-js [#5830](https://github.com/paritytech/parity/pull/5830) +- Report whether a peer was kept from `Handler::on_connect` [#5958](https://github.com/paritytech/parity/pull/5958) +- Implement skeleton for transaction index and epoch transition proof PIP messages [#5908](https://github.com/paritytech/parity/pull/5908) +- TransactionQueue improvements [#5917](https://github.com/paritytech/parity/pull/5917) +- constant time HMAC comparison and clarify docs in ethkey [#5952](https://github.com/paritytech/parity/pull/5952) +- Avoid pre-computing jump destinations [#5954](https://github.com/paritytech/parity/pull/5954) +- Upgrade elastic array [#5949](https://github.com/paritytech/parity/pull/5949) +- PoA: Wait for transition finality before applying [#5774](https://github.com/paritytech/parity/pull/5774) +- Logs Pub-Sub [#5705](https://github.com/paritytech/parity/pull/5705) +- Add the command to install the parity snap [#5945](https://github.com/paritytech/parity/pull/5945) +- Reduce unnecessary allocations [#5944](https://github.com/paritytech/parity/pull/5944) +- Clarify confusing messages. [#5935](https://github.com/paritytech/parity/pull/5935) +- Content Security Policy [#5790](https://github.com/paritytech/parity/pull/5790) +- CLI: Export error message and less verbose peer counter. [#5870](https://github.com/paritytech/parity/pull/5870) +- network: make it more explicit about StreamToken and TimerToken [#5939](https://github.com/paritytech/parity/pull/5939) +- sync: make it more idiomatic rust [#5938](https://github.com/paritytech/parity/pull/5938) +- Prioritize accounts over address book [#5909](https://github.com/paritytech/parity/pull/5909) +- Fixing failing compilation of RPC test on master. [#5916](https://github.com/paritytech/parity/pull/5916) +- Empty local middleware, until explicitly requested [#5912](https://github.com/paritytech/parity/pull/5912) +- Cancel propagated TX [#5899](https://github.com/paritytech/parity/pull/5899) +- fix minor race condition in aura seal generation [#5910](https://github.com/paritytech/parity/pull/5910) +- Docs for Pub-Sub, optional parameter for parity_subscribe [#5833](https://github.com/paritytech/parity/pull/5833) +- Fix gas editor doubling-up on gas [#5820](https://github.com/paritytech/parity/pull/5820) +- Information about used paths added to general output block [#5904](https://github.com/paritytech/parity/pull/5904) +- Domain-locked web tokens. [#5894](https://github.com/paritytech/parity/pull/5894) +- Removed panic handlers [#5895](https://github.com/paritytech/parity/pull/5895) +- Latest changes from Rust RocksDB binding merged [#5905](https://github.com/paritytech/parity/pull/5905) +- Adjust keyethereum/secp256 aliasses [#5903](https://github.com/paritytech/parity/pull/5903) +- Keyethereum fs dependency [#5902](https://github.com/paritytech/parity/pull/5902) +- Ethereum Classic Monetary Policy [#5741](https://github.com/paritytech/parity/pull/5741) +- Initial token should allow full access. [#5873](https://github.com/paritytech/parity/pull/5873) +- Fixed account selection for Dapps on public node [#5856](https://github.com/paritytech/parity/pull/5856) +- blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874) +- Fix wrongly called timeouts [#5838](https://github.com/paritytech/parity/pull/5838) +- ArchiveDB and other small fixes [#5867](https://github.com/paritytech/parity/pull/5867) +- convert try!() to ? [#5866](https://github.com/paritytech/parity/pull/5866) +- Make config file optional in systemd [#5847](https://github.com/paritytech/parity/pull/5847) +- EIP-116 (214), [#4833](https://github.com/paritytech/parity/issues/4833) [#4851](https://github.com/paritytech/parity/pull/4851) +- all executables are workspace members [#5865](https://github.com/paritytech/parity/pull/5865) +- minor optimizations of the modexp builtin [#5860](https://github.com/paritytech/parity/pull/5860) +- three small commits for HashDB and MemoryDB [#5766](https://github.com/paritytech/parity/pull/5766) +- use rust 1.18's retain to boost the purge performance [#5801](https://github.com/paritytech/parity/pull/5801) +- Allow IPFS server to accept POST requests [#5858](https://github.com/paritytech/parity/pull/5858) +- Dutch i18n from [#5802](https://github.com/paritytech/parity/issues/5802) for master [#5836](https://github.com/paritytech/parity/pull/5836) +- Typos in token deploy dapp ui [#5851](https://github.com/paritytech/parity/pull/5851) +- A CLI flag to allow fast transaction signing when account is unlocked. [#5778](https://github.com/paritytech/parity/pull/5778) +- Removing `additional` field from EVM instructions [#5821](https://github.com/paritytech/parity/pull/5821) +- Don't fail on wrong log decoding [#5813](https://github.com/paritytech/parity/pull/5813) +- Use randomized subscription ids for PubSub [#5756](https://github.com/paritytech/parity/pull/5756) +- Fixed mem write for empty slice [#5827](https://github.com/paritytech/parity/pull/5827) +- Fix party technologies [#5810](https://github.com/paritytech/parity/pull/5810) +- Revert "Fixed mem write for empty slice" [#5826](https://github.com/paritytech/parity/pull/5826) +- Fixed mem write for empty slice [#5825](https://github.com/paritytech/parity/pull/5825) +- Fix JS tests [#5822](https://github.com/paritytech/parity/pull/5822) +- Bump native-tls and openssl crates. [#5817](https://github.com/paritytech/parity/pull/5817) +- Public node using WASM [#5734](https://github.com/paritytech/parity/pull/5734) +- enforce block signer == author field in PoA [#5808](https://github.com/paritytech/parity/pull/5808) +- Fix stack display in evmbin. [#5733](https://github.com/paritytech/parity/pull/5733) +- Disable UI if it's not compiled in. [#5773](https://github.com/paritytech/parity/pull/5773) +- Require phrase confirmation. [#5731](https://github.com/paritytech/parity/pull/5731) +- Duration limit made optional for EthashParams [#5777](https://github.com/paritytech/parity/pull/5777) +- Update Changelog for 1.6.8 [#5798](https://github.com/paritytech/parity/pull/5798) +- Replace Ethcore comany name in T&C and some other places [#5796](https://github.com/paritytech/parity/pull/5796) +- PubSub for IPC. [#5800](https://github.com/paritytech/parity/pull/5800) +- Fix terminology distributed -> decentralized applications [#5797](https://github.com/paritytech/parity/pull/5797) +- Disable compression for RLP strings [#5786](https://github.com/paritytech/parity/pull/5786) +- update the source for the snapcraft package [#5781](https://github.com/paritytech/parity/pull/5781) +- Fixed default UI port for mac installer [#5782](https://github.com/paritytech/parity/pull/5782) +- Block invalid account name creation [#5784](https://github.com/paritytech/parity/pull/5784) +- Update Cid/multihash/ring/tinykeccak [#5785](https://github.com/paritytech/parity/pull/5785) +- use NULL_RLP, remove NULL_RLP_STATIC [#5742](https://github.com/paritytech/parity/pull/5742) +- Blacklist empty phrase account. [#5730](https://github.com/paritytech/parity/pull/5730) +- EIP-211 RETURNDATACOPY and RETURNDATASIZE [#5678](https://github.com/paritytech/parity/pull/5678) +- Bump mio [#5763](https://github.com/paritytech/parity/pull/5763) +- Fixing UI issues after UI server refactor [#5710](https://github.com/paritytech/parity/pull/5710) +- Fix WS server expose issue. [#5728](https://github.com/paritytech/parity/pull/5728) +- Fix local transactions without condition. [#5716](https://github.com/paritytech/parity/pull/5716) +- Bump parity-wordlist. [#5748](https://github.com/paritytech/parity/pull/5748) +- two small changes in evm [#5700](https://github.com/paritytech/parity/pull/5700) +- Evmbin: JSON format printing pre-state. [#5712](https://github.com/paritytech/parity/pull/5712) +- Recover from empty phrase in dev mode [#5698](https://github.com/paritytech/parity/pull/5698) +- EIP-210 BLOCKHASH changes [#5505](https://github.com/paritytech/parity/pull/5505) +- fixes typo [#5708](https://github.com/paritytech/parity/pull/5708) +- Bump rocksdb [#5707](https://github.com/paritytech/parity/pull/5707) +- Fixed --datadir option [#5697](https://github.com/paritytech/parity/pull/5697) +- rpc -> weak to arc [#5688](https://github.com/paritytech/parity/pull/5688) +- typo fix [#5699](https://github.com/paritytech/parity/pull/5699) +- Revamping parity-evmbin [#5696](https://github.com/paritytech/parity/pull/5696) +- Update dependencies and bigint api [#5685](https://github.com/paritytech/parity/pull/5685) +- UI server refactoring [#5580](https://github.com/paritytech/parity/pull/5580) +- Fix from/into electrum in ethkey [#5686](https://github.com/paritytech/parity/pull/5686) +- Add unit tests [#5668](https://github.com/paritytech/parity/pull/5668) +- Guanqun add unit tests [#5671](https://github.com/paritytech/parity/pull/5671) +- Parity-PubSub as a separate API. [#5676](https://github.com/paritytech/parity/pull/5676) +- EIP-140 REVERT opcode [#5477](https://github.com/paritytech/parity/pull/5477) +- Update CHANGELOG for 1.6.7 [#5683](https://github.com/paritytech/parity/pull/5683) +- Updated docs slightly. [#5674](https://github.com/paritytech/parity/pull/5674) +- Fix build [#5684](https://github.com/paritytech/parity/pull/5684) +- Back-references for the on-demand service [#5573](https://github.com/paritytech/parity/pull/5573) +- Dynamically adjust PIP request costs based on gathered data [#5603](https://github.com/paritytech/parity/pull/5603) +- use cargo workspace [#5601](https://github.com/paritytech/parity/pull/5601) +- Latest headers Pub-Sub [#5655](https://github.com/paritytech/parity/pull/5655) +- improved dockerfile builds [#5659](https://github.com/paritytech/parity/pull/5659) +- Adding CLI options: port shift and unsafe expose. [#5677](https://github.com/paritytech/parity/pull/5677) +- Report missing author in Aura [#5583](https://github.com/paritytech/parity/pull/5583) +- typo fix [#5669](https://github.com/paritytech/parity/pull/5669) +- Remove public middleware (temporary) [#5665](https://github.com/paritytech/parity/pull/5665) +- Remove additional polyfill [#5663](https://github.com/paritytech/parity/pull/5663) +- Importing accounts from files. [#5644](https://github.com/paritytech/parity/pull/5644) +- remove the deprecated options in rustfmt.toml [#5616](https://github.com/paritytech/parity/pull/5616) +- Update the Console dapp [#5602](https://github.com/paritytech/parity/pull/5602) +- Create an account for chain=dev [#5612](https://github.com/paritytech/parity/pull/5612) +- Use babel-runtime as opposed to babel-polyfill [#5662](https://github.com/paritytech/parity/pull/5662) +- Connection dialog timestamp info [#5554](https://github.com/paritytech/parity/pull/5554) +- use copy_from_slice instead of for loop [#5647](https://github.com/paritytech/parity/pull/5647) +- Light friendly dapps [#5634](https://github.com/paritytech/parity/pull/5634) +- Add Recover button to Accounts and warnings [#5645](https://github.com/paritytech/parity/pull/5645) +- Update eth_sign docs. [#5631](https://github.com/paritytech/parity/pull/5631) +- Proper signer Pub-Sub for pending requests. [#5594](https://github.com/paritytech/parity/pull/5594) +- Bump bigint to 1.0.5 [#5641](https://github.com/paritytech/parity/pull/5641) +- PoA warp implementation [#5488](https://github.com/paritytech/parity/pull/5488) +- Improve on-demand dispatch and add support for batch requests [#5419](https://github.com/paritytech/parity/pull/5419) +- Use default account for sending transactions [#5588](https://github.com/paritytech/parity/pull/5588) +- Add peer management to the Status tab [#5566](https://github.com/paritytech/parity/pull/5566) +- Add monotonic step transition [#5587](https://github.com/paritytech/parity/pull/5587) +- Decrypting for external accounts. [#5581](https://github.com/paritytech/parity/pull/5581) +- only enable warp sync when engine supports it [#5595](https://github.com/paritytech/parity/pull/5595) +- fix the doc of installing rust [#5586](https://github.com/paritytech/parity/pull/5586) +- Small fixes [#5584](https://github.com/paritytech/parity/pull/5584) +- SecretStore: remove session on master node [#5545](https://github.com/paritytech/parity/pull/5545) +- run-clean [#5607](https://github.com/paritytech/parity/pull/5607) +- relicense RLP to MIT/Apache2 [#5591](https://github.com/paritytech/parity/pull/5591) +- Fix eth_sign signature encoding. [#5597](https://github.com/paritytech/parity/pull/5597) +- Check pending request on Node local transactions [#5564](https://github.com/paritytech/parity/pull/5564) +- Add tooltips on ActionBar [#5562](https://github.com/paritytech/parity/pull/5562) +- Can't deploy without compiling Contract [#5593](https://github.com/paritytech/parity/pull/5593) +- Add a warning when node is syncing [#5565](https://github.com/paritytech/parity/pull/5565) +- Update registry middleware [#5585](https://github.com/paritytech/parity/pull/5585) +- Set block condition to BigNumber in MethodDecoding [#5592](https://github.com/paritytech/parity/pull/5592) +- Load the sources immediately in Contract Dev [#5575](https://github.com/paritytech/parity/pull/5575) +- Remove formal verification messages in Dev Contract [#5574](https://github.com/paritytech/parity/pull/5574) +- Fix event params decoding when no names for parameters [#5567](https://github.com/paritytech/parity/pull/5567) +- Do not convert to Dates twice [#5563](https://github.com/paritytech/parity/pull/5563) +- Fix Multisig wallet settings [#5560](https://github.com/paritytech/parity/pull/5560) +- Typo [#5547](https://github.com/paritytech/parity/pull/5547) +- Generic PubSub implementation [#5456](https://github.com/paritytech/parity/pull/5456) +- Fix CI paths. [#5570](https://github.com/paritytech/parity/pull/5570) +- reorg into blocks before minimum history [#5558](https://github.com/paritytech/parity/pull/5558) +- EIP-86 update [#5506](https://github.com/paritytech/parity/pull/5506) +- Secretstore RPCs + integration [#5439](https://github.com/paritytech/parity/pull/5439) +- Fixes Parity Bar position [#5557](https://github.com/paritytech/parity/pull/5557) +- Fixes invalid log in BadgeReg events [#5556](https://github.com/paritytech/parity/pull/5556) +- Fix issues in Contract Development view [#5555](https://github.com/paritytech/parity/pull/5555) +- Added missing methods [#5542](https://github.com/paritytech/parity/pull/5542) +- option to disable persistent txqueue [#5544](https://github.com/paritytech/parity/pull/5544) +- Bump jsonrpc [#5552](https://github.com/paritytech/parity/pull/5552) +- Retrieve block headers only for header-only info [#5480](https://github.com/paritytech/parity/pull/5480) +- add snap to CI [#5519](https://github.com/paritytech/parity/pull/5519) +- Pass additional data when reporting [#5527](https://github.com/paritytech/parity/pull/5527) +- Calculate post-constructors state root in spec at load time [#5523](https://github.com/paritytech/parity/pull/5523) +- Fix utf8 decoding [#5533](https://github.com/paritytech/parity/pull/5533) +- Add CHANGELOG.md [#5513](https://github.com/paritytech/parity/pull/5513) +- Change all occurrences of ethcore.io into parity.io [#5528](https://github.com/paritytech/parity/pull/5528) +- Memory usage optimization [#5526](https://github.com/paritytech/parity/pull/5526) +- Compose transaction RPC. [#5524](https://github.com/paritytech/parity/pull/5524) +- Support external eth_sign [#5481](https://github.com/paritytech/parity/pull/5481) +- Treat block numbers as strings, not BigNums. [#5449](https://github.com/paritytech/parity/pull/5449) +- npm cleanups [#5512](https://github.com/paritytech/parity/pull/5512) +- Export acc js [#4973](https://github.com/paritytech/parity/pull/4973) +- YARN [#5395](https://github.com/paritytech/parity/pull/5395) +- Fix linting issues [#5511](https://github.com/paritytech/parity/pull/5511) +- Chinese Translation [#5460](https://github.com/paritytech/parity/pull/5460) +- Fixing secretstore TODOs - part 2 [#5416](https://github.com/paritytech/parity/pull/5416) +- fix json format of state snapshot [#5504](https://github.com/paritytech/parity/pull/5504) +- Bump jsonrpc version [#5489](https://github.com/paritytech/parity/pull/5489) +- Groundwork for generalized warp sync [#5454](https://github.com/paritytech/parity/pull/5454) +- Add the packaging metadata to build the parity snap [#5496](https://github.com/paritytech/parity/pull/5496) +- Cancel tx JS [#4958](https://github.com/paritytech/parity/pull/4958) +- EIP-212 (bn128 curve pairing) [#5307](https://github.com/paritytech/parity/pull/5307) +- fix panickers in tree-route [#5479](https://github.com/paritytech/parity/pull/5479) +- Update links to etherscan.io [#5455](https://github.com/paritytech/parity/pull/5455) +- Refresh UI on nodeKind changes, e.g. personal -> public [#5312](https://github.com/paritytech/parity/pull/5312) +- Correct contract address for EIP-86 [#5473](https://github.com/paritytech/parity/pull/5473) +- Force two decimals for USD conversion rate [#5471](https://github.com/paritytech/parity/pull/5471) +- Refactoring of Tokens & Balances [#5372](https://github.com/paritytech/parity/pull/5372) +- Background-repeat round [#5475](https://github.com/paritytech/parity/pull/5475) +- nl i18n updated [#5461](https://github.com/paritytech/parity/pull/5461) +- Show ETH value (even 0) if ETH transfer in transaction list [#5406](https://github.com/paritytech/parity/pull/5406) +- Store the pending requests per network version [#5405](https://github.com/paritytech/parity/pull/5405) +- Use in-memory database for tests [#5451](https://github.com/paritytech/parity/pull/5451) +- WebSockets RPC server [#5425](https://github.com/paritytech/parity/pull/5425) +- Added missing docs [#5452](https://github.com/paritytech/parity/pull/5452) +- Tests and tweaks for public node middleware [#5417](https://github.com/paritytech/parity/pull/5417) +- Fix removal of hash-mismatched files. [#5440](https://github.com/paritytech/parity/pull/5440) +- parity_getBlockHeaderByNumber and LightFetch utility [#5383](https://github.com/paritytech/parity/pull/5383) +- New state tests [#5418](https://github.com/paritytech/parity/pull/5418) +- Fix buffer length for QR code gen. [#5447](https://github.com/paritytech/parity/pull/5447) +- Add raw hash signing [#5423](https://github.com/paritytech/parity/pull/5423) +- Filters and block RPCs for the light client [#5320](https://github.com/paritytech/parity/pull/5320) +- Work around mismatch for QR checksum [#5374](https://github.com/paritytech/parity/pull/5374) +- easy to use conversion from and to string for ethstore::Crypto [#5437](https://github.com/paritytech/parity/pull/5437) +- Tendermint fixes [#5415](https://github.com/paritytech/parity/pull/5415) +- Adrianbrink lightclientcache branch. [#5428](https://github.com/paritytech/parity/pull/5428) +- Add caching to HeaderChain struct [#5403](https://github.com/paritytech/parity/pull/5403) +- Add decryption to the UI (in the Signer) [#5422](https://github.com/paritytech/parity/pull/5422) +- Add CIDv0 RPC [#5414](https://github.com/paritytech/parity/pull/5414) +- Updating documentation for RPCs [#5392](https://github.com/paritytech/parity/pull/5392) +- Fixing secretstore TODOs - part 1 [#5386](https://github.com/paritytech/parity/pull/5386) +- Fixing disappearing content. [#5399](https://github.com/paritytech/parity/pull/5399) +- Snapshot chunks packed by size [#5318](https://github.com/paritytech/parity/pull/5318) +- APIs wildcards and simple arithmetic. [#5402](https://github.com/paritytech/parity/pull/5402) +- Fixing compilation without dapps. [#5410](https://github.com/paritytech/parity/pull/5410) +- Don't use port 8080 anymore [#5397](https://github.com/paritytech/parity/pull/5397) +- Quick'n'dirty CLI for the light client [#5002](https://github.com/paritytech/parity/pull/5002) +- set gas limit before proving transactions [#5401](https://github.com/paritytech/parity/pull/5401) +- Public node: perf and fixes [#5390](https://github.com/paritytech/parity/pull/5390) +- Straight download path in the readme [#5393](https://github.com/paritytech/parity/pull/5393) +- On-chain ACL checker for secretstore [#5015](https://github.com/paritytech/parity/pull/5015) +- Allow empty-encoded values from QR encoding [#5385](https://github.com/paritytech/parity/pull/5385) +- Update npm build for new inclusions [#5381](https://github.com/paritytech/parity/pull/5381) +- Fix for Ubuntu Dockerfile [#5356](https://github.com/paritytech/parity/pull/5356) +- Secretstore over network [#4974](https://github.com/paritytech/parity/pull/4974) +- Dapps and RPC server merge [#5365](https://github.com/paritytech/parity/pull/5365) +- trigger js build release [#5379](https://github.com/paritytech/parity/pull/5379) +- Update expanse json with fork at block 600000 [#5351](https://github.com/paritytech/parity/pull/5351) +- Futures-based native wrappers for contract ABIs [#5341](https://github.com/paritytech/parity/pull/5341) +- Kovan warp sync fixed [#5337](https://github.com/paritytech/parity/pull/5337) +- Aura eip155 validation transition [#5362](https://github.com/paritytech/parity/pull/5362) +- Shared wordlist for brain wallets [#5331](https://github.com/paritytech/parity/pull/5331) +- Allow signing via Qr [#4881](https://github.com/paritytech/parity/pull/4881) +- Allow entry of url or hash for DappReg meta [#5360](https://github.com/paritytech/parity/pull/5360) +- Adjust tx overlay colours [#5353](https://github.com/paritytech/parity/pull/5353) +- Add ability to disallow API subscriptions [#5366](https://github.com/paritytech/parity/pull/5366) +- EIP-213 (bn128 curve operations) [#4999](https://github.com/paritytech/parity/pull/4999) +- Fix analize output file name [#5357](https://github.com/paritytech/parity/pull/5357) +- Add default eip155 validation [#5346](https://github.com/paritytech/parity/pull/5346) +- Add new seed nodes for Classic chain [#5345](https://github.com/paritytech/parity/pull/5345) +- Shared wordlist for frontend [#5336](https://github.com/paritytech/parity/pull/5336) +- fix rpc tests [#5338](https://github.com/paritytech/parity/pull/5338) +- Public node with accounts and signing in Frontend [#5304](https://github.com/paritytech/parity/pull/5304) +- Rename Status/Status -> Status/NodeStatus [#5332](https://github.com/paritytech/parity/pull/5332) +- Updating paths to repos. [#5330](https://github.com/paritytech/parity/pull/5330) +- Separate status for canceled local transactions. [#5319](https://github.com/paritytech/parity/pull/5319) +- Cleanup the Status View [#5317](https://github.com/paritytech/parity/pull/5317) +- Update UI minimised requests [#5324](https://github.com/paritytech/parity/pull/5324) +- Order signer transactions FIFO [#5321](https://github.com/paritytech/parity/pull/5321) +- updating dependencies [#5028](https://github.com/paritytech/parity/pull/5028) +- Minimise transactions progress [#4942](https://github.com/paritytech/parity/pull/4942) +- Fix eth_sign showing as wallet account [#5309](https://github.com/paritytech/parity/pull/5309) +- Ropsten revival [#5302](https://github.com/paritytech/parity/pull/5302) +- Strict validation transitions [#4988](https://github.com/paritytech/parity/pull/4988) +- Fix default list sorting [#5303](https://github.com/paritytech/parity/pull/5303) +- Use unique owners for multisig wallets [#5298](https://github.com/paritytech/parity/pull/5298) +- Copy all existing i18n strings into zh (as-is translation aid) [#5305](https://github.com/paritytech/parity/pull/5305) +- Fix booleans in Typedinput [#5295](https://github.com/paritytech/parity/pull/5295) +- node kind RPC [#5025](https://github.com/paritytech/parity/pull/5025) +- Fix the use of MobX in playground [#5294](https://github.com/paritytech/parity/pull/5294) +- Fine grained snapshot chunking [#5019](https://github.com/paritytech/parity/pull/5019) +- Add lint:i18n to find missing & extra keys [#5290](https://github.com/paritytech/parity/pull/5290) +- Scaffolding for zh translations, including first-round by @btceth [#5289](https://github.com/paritytech/parity/pull/5289) +- JS package bumps [#5287](https://github.com/paritytech/parity/pull/5287) +- Auto-extract new i18n strings (update) [#5288](https://github.com/paritytech/parity/pull/5288) +- eip100b [#5027](https://github.com/paritytech/parity/pull/5027) +- Set earliest era in snapshot restoration [#5021](https://github.com/paritytech/parity/pull/5021) +- Avoid clogging up tmp when updater dir has bad permissions. [#5024](https://github.com/paritytech/parity/pull/5024) +- Resilient warp sync [#5018](https://github.com/paritytech/parity/pull/5018) +- Create webpack analysis files (size) [#5009](https://github.com/paritytech/parity/pull/5009) +- Dispatch an open event on drag of Parity Bar [#4987](https://github.com/paritytech/parity/pull/4987) +- Various installer and tray apps fixes [#4970](https://github.com/paritytech/parity/pull/4970) +- Export account RPC [#4967](https://github.com/paritytech/parity/pull/4967) +- Switching ValidatorSet [#4961](https://github.com/paritytech/parity/pull/4961) +- Implement PIP messages, request builder, and handlers [#4945](https://github.com/paritytech/parity/pull/4945) +- auto lint [#5003](https://github.com/paritytech/parity/pull/5003) +- Fix FireFox overflows [#5000](https://github.com/paritytech/parity/pull/5000) +- Show busy indicator, focus first field in password change [#4997](https://github.com/paritytech/parity/pull/4997) +- Consistent store naming in the Signer components [#4996](https://github.com/paritytech/parity/pull/4996) +- second (and last) part of rlp refactor [#4901](https://github.com/paritytech/parity/pull/4901) +- Double click to select account creation type [#4986](https://github.com/paritytech/parity/pull/4986) +- Fixes to the Registry dapp [#4984](https://github.com/paritytech/parity/pull/4984) +- Extend api.util [#4979](https://github.com/paritytech/parity/pull/4979) +- Updating JSON-RPC crates [#4934](https://github.com/paritytech/parity/pull/4934) +- splitting part of util into smaller crates [#4956](https://github.com/paritytech/parity/pull/4956) +- Updating syntex et al [#4983](https://github.com/paritytech/parity/pull/4983) +- EIP198 and built-in activation [#4926](https://github.com/paritytech/parity/pull/4926) +- Fix MethodDecoding for Arrays [#4977](https://github.com/paritytech/parity/pull/4977) +- Try to fix WS race condition connection [#4976](https://github.com/paritytech/parity/pull/4976) +- eth_sign where account === undefined [#4964](https://github.com/paritytech/parity/pull/4964) +- Fix references to api outside of `parity.js` [#4981](https://github.com/paritytech/parity/pull/4981) +- Fix Password Dialog form overflow [#4968](https://github.com/paritytech/parity/pull/4968) +- Changing Mutex into RwLock for transaction queue [#4951](https://github.com/paritytech/parity/pull/4951) +- Disable max seal period for external sealing [#4927](https://github.com/paritytech/parity/pull/4927) +- Attach hardware wallets already in addressbook [#4912](https://github.com/paritytech/parity/pull/4912) +- rlp serialization refactor [#4873](https://github.com/paritytech/parity/pull/4873) +- Bump nanomsg [#4965](https://github.com/paritytech/parity/pull/4965) +- Fixed multi-chunk ledger transactions on windows [#4960](https://github.com/paritytech/parity/pull/4960) +- Fix outputs in Contract Constant Queries [#4953](https://github.com/paritytech/parity/pull/4953) +- systemd: Start parity after network.target [#4952](https://github.com/paritytech/parity/pull/4952) +- Remove transaction RPC [#4949](https://github.com/paritytech/parity/pull/4949) +- Swap out ethcore.io url for parity.io [#4947](https://github.com/paritytech/parity/pull/4947) +- Don't remove confirmed requests to early. [#4933](https://github.com/paritytech/parity/pull/4933) +- Ensure sealing work enabled in miner once subscribers added [#4930](https://github.com/paritytech/parity/pull/4930) +- Add z-index to small modals as well [#4923](https://github.com/paritytech/parity/pull/4923) +- Bump nanomsg [#4946](https://github.com/paritytech/parity/pull/4946) +- Bumping multihash and libc [#4943](https://github.com/paritytech/parity/pull/4943) +- Edit ETH value, gas and gas price in Contract Deployment [#4919](https://github.com/paritytech/parity/pull/4919) +- Add ability to configure Secure API [#4922](https://github.com/paritytech/parity/pull/4922) +- Add Token image from URL [#4916](https://github.com/paritytech/parity/pull/4916) +- Use the registry fee in Token Deployment dapp [#4915](https://github.com/paritytech/parity/pull/4915) +- Add reseal max period [#4903](https://github.com/paritytech/parity/pull/4903) +- Detect rust compiler version in Parity build script, closes 4742 [#4907](https://github.com/paritytech/parity/pull/4907) +- Add Vaults logic to First Run [#4914](https://github.com/paritytech/parity/pull/4914) +- Updated gcc and rayon crates to remove outdated num_cpus dependency [#4909](https://github.com/paritytech/parity/pull/4909) +- Renaming evm binary to avoid conflicts. [#4899](https://github.com/paritytech/parity/pull/4899) +- Better error handling for traces RPC [#4849](https://github.com/paritytech/parity/pull/4849) +- Safari SectionList fix [#4895](https://github.com/paritytech/parity/pull/4895) +- Safari Dialog scrolling fix [#4893](https://github.com/paritytech/parity/pull/4893) +- Spelling :) [#4900](https://github.com/paritytech/parity/pull/4900) +- Additional kovan params [#4892](https://github.com/paritytech/parity/pull/4892) +- trigger js-precompiled build [#4898](https://github.com/paritytech/parity/pull/4898) +- Recalculate receipt roots in close_and_lock [#4884](https://github.com/paritytech/parity/pull/4884) +- Reload UI on network switch [#4864](https://github.com/paritytech/parity/pull/4864) +- Update parity-ui-precompiled with branch [#4850](https://github.com/paritytech/parity/pull/4850) +- OSX Installer is no longer experimental [#4882](https://github.com/paritytech/parity/pull/4882) +- Chain-selection from UI [#4859](https://github.com/paritytech/parity/pull/4859) +- removed redundant (and unused) FromJson trait [#4871](https://github.com/paritytech/parity/pull/4871) +- fix typos and grammar [#4880](https://github.com/paritytech/parity/pull/4880) +- Remove old experimental remote-db code [#4872](https://github.com/paritytech/parity/pull/4872) +- removed redundant FixedHash trait, fixes [#4029](https://github.com/paritytech/parity/issues/4029) [#4866](https://github.com/paritytech/parity/pull/4866) +- Reference JSON-RPC more changes-friendly [#4870](https://github.com/paritytech/parity/pull/4870) +- Better handling of Solidity compliation [#4860](https://github.com/paritytech/parity/pull/4860) +- Go through contract links in Transaction List display [#4863](https://github.com/paritytech/parity/pull/4863) +- Fix Gas Price Selector Tooltips [#4865](https://github.com/paritytech/parity/pull/4865) +- Fix auto-updater [#4867](https://github.com/paritytech/parity/pull/4867) +- Make the UI work offline [#4861](https://github.com/paritytech/parity/pull/4861) +- Subscribe to accounts info in Signer / ParityBar [#4856](https://github.com/paritytech/parity/pull/4856) +- Don't link libsnappy explicitly [#4841](https://github.com/paritytech/parity/pull/4841) +- Fix paste in Inputs [#4854](https://github.com/paritytech/parity/pull/4854) +- Extract i18n from shared UI components [#4834](https://github.com/paritytech/parity/pull/4834) +- Fix paste in Inputs [#4844](https://github.com/paritytech/parity/pull/4844) +- Pull contract deployment title from available steps [#4848](https://github.com/paritytech/parity/pull/4848) +- Supress USB error message [#4839](https://github.com/paritytech/parity/pull/4839) +- Fix getTransactionCount in --geth mode [#4837](https://github.com/paritytech/parity/pull/4837) +- CI: test coverage (for core and js) [#4832](https://github.com/paritytech/parity/pull/4832) +- Lowering threshold for transactions above gas limit [#4831](https://github.com/paritytech/parity/pull/4831) +- Fix TxViewer when no `to` (contract deployment) [#4847](https://github.com/paritytech/parity/pull/4847) +- Fix method decoding [#4845](https://github.com/paritytech/parity/pull/4845) +- Add React Hot Reload to dapps + TokenDeploy fix [#4846](https://github.com/paritytech/parity/pull/4846) +- Dapps show multiple times in some cases [#4843](https://github.com/paritytech/parity/pull/4843) +- Fixes to the Registry dapp [#4838](https://github.com/paritytech/parity/pull/4838) +- Show token icons on list summary pages [#4826](https://github.com/paritytech/parity/pull/4826) +- Calibrate step before rejection [#4800](https://github.com/paritytech/parity/pull/4800) +- Add replay protection [#4808](https://github.com/paritytech/parity/pull/4808) +- Better icon on windows [#4804](https://github.com/paritytech/parity/pull/4804) +- Better logic for contract deployments detection [#4821](https://github.com/paritytech/parity/pull/4821) +- Fix wrong default values for contract queries inputs [#4819](https://github.com/paritytech/parity/pull/4819) +- Adjust selection colours/display [#4811](https://github.com/paritytech/parity/pull/4811) +- Update the Wallet Library Registry key [#4817](https://github.com/paritytech/parity/pull/4817) +- Update Wallet to new Wallet Code [#4805](https://github.com/paritytech/parity/pull/4805) + +## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-25) + +This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure. + +All Changes: + +- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116) + - Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112) + - Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874) + - Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work) +- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118) +- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108) +- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104) + - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) + - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) +- Bump to v1.6.10 + +## Parity [v1.6.9](https://github.com/paritytech/parity/releases/tag/v1.6.9) (2017-07-16) + +This is a first stable release of 1.6 series. It contains a number of minor fixes and introduces the `--reseal-on-uncles` option for miners. + +Full list of changes: + +- Backports [#6061](https://github.com/paritytech/parity/pull/6061) + - Ethereum Classic Monetary Policy [#5741](https://github.com/paritytech/parity/pull/5741) + - Update rewards for uncle miners for ECIP1017 + - Fix an off-by-one error in ECIP1017 era calculation + - `ecip1017_era_rounds` missing from EthashParams when run in build bot + - strip out ecip1017_eras_block_reward function and add unit test + - JS precompiled set to stable +- Backports [#6060](https://github.com/paritytech/parity/pull/6060) + - --reseal-on-uncle [#5940](https://github.com/paritytech/parity/pull/5940) + - Optimized uncle check + - Additional uncle check + - Updated comment + - Bump to v1.6.9 + - CLI: Export error message and less verbose peer counter. [#5870](https://github.com/paritytech/parity/pull/5870) + - Removed numbed of active connections from informant + - Print error message when fatdb is required + - Remove peers from UI + ## Parity [v1.6.8](https://github.com/paritytech/parity/releases/tag/v1.6.8) (2017-06-08) This release addresses: diff --git a/Cargo.lock b/Cargo.lock index 0c049c948..2f5ed0a21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,15 @@ [root] -name = "using_queue" +name = "wasm" version = "0.1.0" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-logger 1.8.0", + "ethcore-util 1.8.0", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", + "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", +] [[package]] name = "advapi32-sys" @@ -81,6 +90,20 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "backtrace-sys" version = "0.1.11" @@ -167,6 +190,14 @@ name = "blastfig" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bloomable" +version = "0.1.0" +dependencies = [ + "ethcore-bigint 0.1.3", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bloomchain" version = "0.1.0" @@ -206,6 +237,15 @@ name = "cfg-if" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chainspec" +version = "0.1.0" +dependencies = [ + "ethjson 0.1.0", + "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cid" version = "0.2.2" @@ -257,6 +297,7 @@ dependencies = [ name = "common-types" version = "0.1.0" dependencies = [ + "bloomable 0.1.0", "ethcore-util 1.8.0", "ethjson 0.1.0", "rlp 0.2.0", @@ -302,6 +343,11 @@ name = "crossbeam" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "crunchy" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "crypt32-sys" version = "0.2.0" @@ -424,13 +470,14 @@ dependencies = [ "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethash" version = "1.8.0" dependencies = [ + "crunchy 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -442,6 +489,7 @@ name = "ethcore" version = "1.8.0" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bloomable 0.1.0", "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bn 0.4.4 (git+https://github.com/paritytech/bn)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -475,15 +523,19 @@ dependencies = [ "native-contracts 0.1.0", "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "price-info 1.7.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", + "table 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "using_queue 0.1.0", + "vm 0.1.0", + "wasm 0.1.0", ] [[package]] @@ -605,6 +657,7 @@ dependencies = [ "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", ] [[package]] @@ -636,6 +689,7 @@ dependencies = [ "ethcrypto 0.1.0", "ethkey 0.2.0", "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -648,7 +702,7 @@ dependencies = [ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -667,7 +721,7 @@ dependencies = [ "ethcrypto 0.1.0", "ethkey 0.2.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -732,11 +786,9 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.1.0", - "table 0.1.0", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "using_queue 0.1.0", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -749,7 +801,7 @@ dependencies = [ "ethkey 0.2.0", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -757,7 +809,7 @@ name = "ethjson" version = "0.1.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.8.0", + "ethcore-bigint 0.1.3", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -775,7 +827,7 @@ dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -784,6 +836,7 @@ version = "0.1.0" dependencies = [ "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.2.0", + "panic_hook 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -811,7 +864,7 @@ dependencies = [ "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -820,6 +873,7 @@ version = "0.1.0" dependencies = [ "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethstore 0.1.0", + "panic_hook 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -842,6 +896,7 @@ dependencies = [ "ethcore-util 1.8.0", "ethkey 0.2.0", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -858,6 +913,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", + "ethcore-logger 1.8.0", "ethcore-util 1.8.0", "ethjson 0.1.0", "evmjit 1.8.0", @@ -866,6 +922,7 @@ dependencies = [ "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)", ] @@ -877,16 +934,18 @@ dependencies = [ "ethcore 1.8.0", "ethcore-util 1.8.0", "evm 0.1.0", + "panic_hook 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", ] [[package]] name = "evmjit" version = "1.8.0" dependencies = [ - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -902,7 +961,7 @@ name = "fetch" version = "0.1.0" dependencies = [ "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -935,10 +994,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-cpupool" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1016,6 +1074,11 @@ dependencies = [ "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hex" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "hidapi" version = "0.3.1" @@ -1124,6 +1187,11 @@ dependencies = [ "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipnetwork" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "isatty" version = "0.1.1" @@ -1150,7 +1218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jsonrpc-core" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1162,7 +1230,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1175,7 +1243,7 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1188,7 +1256,7 @@ dependencies = [ [[package]] name = "jsonrpc-macros" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1198,7 +1266,7 @@ dependencies = [ [[package]] name = "jsonrpc-minihttp-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1213,7 +1281,7 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1223,7 +1291,7 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1236,7 +1304,7 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1250,7 +1318,7 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#5e79be8a098cdda221713992f4a46b41a1d4d8f0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1479,7 +1547,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ring 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1514,7 +1582,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.8.0", + "ethcore-bigint 0.1.3", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "native-contract-generator 0.1.0", ] @@ -1694,6 +1762,15 @@ name = "order-stat" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ordered-float" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "owning_ref" version = "0.3.3" @@ -1702,9 +1779,16 @@ dependencies = [ "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "panic_hook" +version = "0.1.0" +dependencies = [ + "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity" -version = "1.7.0" +version = "1.8.0" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1722,6 +1806,7 @@ dependencies = [ "ethcore-ipc-tests 0.1.0", "ethcore-light 1.8.0", "ethcore-logger 1.8.0", + "ethcore-network 1.8.0", "ethcore-secretstore 1.0.0", "ethcore-stratum 1.8.0", "ethcore-util 1.8.0", @@ -1729,12 +1814,14 @@ dependencies = [ "ethsync 1.8.0", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "panic_hook 0.1.0", "parity-dapps 1.8.0", "parity-hash-fetch 1.8.0", "parity-ipfs-api 1.8.0", @@ -1743,6 +1830,7 @@ dependencies = [ "parity-rpc 1.8.0", "parity-rpc-client 1.4.0", "parity-updater 1.8.0", + "parity-whisper 0.1.0", "path 0.1.0", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1772,7 +1860,7 @@ dependencies = [ "ethcore-util 1.8.0", "fetch 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1881,10 +1969,9 @@ dependencies = [ "ethkey 0.2.0", "ethstore 0.1.0", "ethsync 1.8.0", - "evm 0.1.0", "fetch 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1910,6 +1997,7 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vm 0.1.0", ] [[package]] @@ -1966,7 +2054,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/paritytech/js-precompiled.git#92627cfd287eb5176c016089b9e2350107f8869a" +source = "git+https://github.com/paritytech/js-precompiled.git#dd9b92d9d8c244678e15163347f9adb2e2560959" dependencies = [ "parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2000,6 +2088,36 @@ dependencies = [ "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-whisper" +version = "0.1.0" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.1.3", + "ethcore-network 1.8.0", + "ethcrypto 0.1.0", + "ethkey 0.2.0", + "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.0", + "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity-wordlist" version = "1.0.1" @@ -2088,6 +2206,17 @@ dependencies = [ "difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "price-info" +version = "1.7.0" +dependencies = [ + "fetch 0.1.0", + "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "primal" version = "0.2.3" @@ -2474,6 +2603,14 @@ dependencies = [ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_ignored" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "1.0.2" @@ -2728,7 +2865,7 @@ dependencies = [ [[package]] name = "tiny-keccak" -version = "1.2.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2951,6 +3088,10 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "using_queue" +version = "0.1.0" + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -2979,6 +3120,20 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "vm" +version = "0.1.0" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "common-types 0.1.0", + "ethcore-util 1.8.0", + "ethjson 0.1.0", + "evmjit 1.8.0", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.0", +] + [[package]] name = "void" version = "1.0.2" @@ -2987,7 +3142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-utils" version = "0.1.0" -source = "git+https://github.com/paritytech/wasm-utils#fee06b6d5826c2dc1fc1aa183b0c2c75e3e140c3" +source = "git+https://github.com/paritytech/wasm-utils#9462bcc0680f0ec2c876abdf75bae981dd4344a5" dependencies = [ "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3073,6 +3228,7 @@ dependencies = [ "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" +"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76" "checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff" "checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1" "checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c" @@ -3101,6 +3257,7 @@ dependencies = [ "checksum core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20a6d0448d3a99d977ae4a2aa5a98d886a923e863e81ad9ff814645b6feb3bbd" "checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5" "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" +"checksum crunchy 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6aa9cb5f2d7bffc4eecfaf924fe450549dc4f0c3a6502298dc24f968b1eabbe" "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "" "checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" @@ -3121,7 +3278,7 @@ dependencies = [ "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" "checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d" -"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82" +"checksum futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a283c84501e92cade5ea673a2a7ca44f71f209ccdd302a3e0896f50083d2c5ff" "checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" @@ -3130,6 +3287,7 @@ dependencies = [ "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" "checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4" "checksum heck 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f807d2f64cc044a6bcf250ff23e59be0deec7a16612c014f962a06fa7e020f9" +"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "" "checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae" "checksum hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)" = "" @@ -3139,6 +3297,7 @@ dependencies = [ "checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" "checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" +"checksum ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "232e76922883005380e831068f731ef0305541c9f77b30df3a1635047b16f370" "checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c" "checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a" "checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5" @@ -3199,6 +3358,7 @@ dependencies = [ "checksum openssl 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b34cd77cf91301fff3123fbd46b065c3b728b17a392835de34c397315dce5586" "checksum openssl-sys 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e035022a50faa380bd7ccdbd184d946ce539ebdb0a358780de92a995882af97a" "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" +"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1d06f6ee0fda786df3784a96ee3f0629f529b91cbfb7d142f6410e6bcd1ce2c" "checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" @@ -3257,6 +3417,7 @@ dependencies = [ "checksum serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c6b751a2e8d5df57a5ff71b5b4fc8aaee9ee28ff1341d640dd130bb5f4f7a" "checksum serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f6ca58905ebd3c3b285a8a6d4f3ac92b92c0d7951d5649b1bdd212549c06639" "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" +"checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" @@ -3287,7 +3448,7 @@ dependencies = [ "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" "checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" -"checksum tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b50173faa6ee499206f77b189d7ff3bef40f6969f228c9ec22b82080df9aa41" +"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292" "checksum tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e958104a67877907c1454386d5482fe8e965a55d60be834a15a44328e7dc76" "checksum tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "48f55df1341bb92281f229a6030bc2abffde2c7a44c6d6b802b7687dd8be0775" "checksum tokio-minihttp 0.1.0 (git+https://github.com/tomusdrw/tokio-minihttp)" = "" diff --git a/Cargo.toml b/Cargo.toml index 93341b564..3adaf62d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Parity Ethereum client" name = "parity" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0" authors = ["Parity Technologies "] build = "build.rs" @@ -41,6 +41,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" } ethcore-light = { path = "ethcore/light" } ethcore-logger = { path = "logger" } ethcore-stratum = { path = "stratum" } +ethcore-network = { path = "util/network" } ethkey = { path = "ethkey" } rlp = { path = "util/rlp" } rpc-cli = { path = "rpc_cli" } @@ -51,7 +52,9 @@ parity-reactor = { path = "util/reactor" } parity-rpc = { path = "rpc" } parity-rpc-client = { path = "rpc_client" } parity-updater = { path = "updater" } +parity-whisper = { path = "whisper" } path = { path = "util/path" } +panic_hook = { path = "panic_hook" } parity-dapps = { path = "dapps", optional = true } clippy = { version = "0.0.103", optional = true} @@ -63,6 +66,7 @@ rustc_version = "0.2" [dev-dependencies] ethcore-ipc-tests = { path = "ipc/tests" } pretty_assertions = "0.1" +ipnetwork = "0.12.6" [target.'cfg(windows)'.dependencies] winapi = "0.2" @@ -106,4 +110,4 @@ lto = false panic = "abort" [workspace] -members = ["ethstore/cli", "ethkey/cli", "evmbin"] +members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper", "chainspec"] diff --git a/README.md b/README.md index 92d74c8d2..16758bc27 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,41 @@ -# [Parity](https://parity.io/parity.html) -### Fast, light, and robust Ethereum implementation +# [Parity](https://parity.io/parity.html) - fast, light, and robust Ethereum client -### [Download latest release](https://github.com/paritytech/parity/releases) +[![build status](https://gitlab.parity.io/parity/parity/badges/master/build.svg)](https://gitlab.parity.io/parity/parity/commits/master) +[![Snap Status](https://build.snapcraft.io/badge/paritytech/parity.svg)](https://build.snapcraft.io/user/paritytech/parity) +[![GPLv3](https://img.shields.io/badge/license-GPL%20v3-green.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) -[![build status](https://gitlab.parity.io/parity/parity/badges/master/build.svg)](https://gitlab.parity.io/parity/parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![GPLv3][license-image]][license-url] +- [Download the latest release here.](https://github.com/paritytech/parity/releases) ### Join the chat! -Parity [![Join the chat at https://gitter.im/ethcore/parity][gitter-image]][gitter-url] and -parity.js [![Join the chat at https://gitter.im/ethcore/parity.js](https://badges.gitter.im/ethcore/parity.js.svg)](https://gitter.im/ethcore/parity.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -[Internal Documentation][doc-url] - - -Be sure to check out [our wiki][wiki-url] for more information. - -[coveralls-image]: https://coveralls.io/repos/github/paritytech/parity/badge.svg?branch=master -[coveralls-url]: https://coveralls.io/github/paritytech/parity?branch=master -[gitter-image]: https://badges.gitter.im/Join%20Chat.svg -[gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge -[license-image]: https://img.shields.io/badge/license-GPL%20v3-green.svg -[license-url]: https://www.gnu.org/licenses/gpl-3.0.en.html -[doc-url]: https://paritytech.github.io/parity/ethcore/index.html -[wiki-url]: https://github.com/paritytech/parity/wiki +Get in touch with us on Gitter: +[![Gitter: Parity](https://img.shields.io/badge/gitter-parity-4AB495.svg)](https://gitter.im/paritytech/parity) +[![Gitter: Parity.js](https://img.shields.io/badge/gitter-parity.js-4AB495.svg)](https://gitter.im/paritytech/parity.js) +[![Gitter: Parity/Miners](https://img.shields.io/badge/gitter-parity/miners-4AB495.svg)](https://gitter.im/paritytech/parity/miners) +[![Gitter: Parity-PoA](https://img.shields.io/badge/gitter-parity--poa-4AB495.svg)](https://gitter.im/paritytech/parity-poa) +Be sure to check out [our wiki](https://github.com/paritytech/parity/wiki) and the [internal documentation](https://paritytech.github.io/parity/ethcore/index.html) for more information. ---- - ## About Parity -Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and -cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs. +Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs. + +Parity comes with a built-in wallet. To access [Parity Wallet](http://web3.site/) simply go to http://web3.site/ (if you don't have access to the internet, but still want to use the service, you can also use http://127.0.0.1:8180/). It includes various functionality allowing you to: -Parity comes with a built-in wallet. To access [Parity Wallet](http://web3.site/) simply go to http://web3.site/ (if you don't have access to the internet, but still want to use the service, you can also use http://127.0.0.1:8180/). It -includes various functionality allowing you to: - create and manage your Ethereum accounts; - manage your Ether and any Ethereum tokens; - create and register your own tokens; - and much more. -By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number -of RPC APIs. +By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number of RPC APIs. -If you run into an issue while using parity, feel free to file one in this repository -or hop on our [gitter chat room][gitter-url] to ask a question. We are glad to help! +If you run into an issue while using parity, feel free to file one in this repository or hop on our [gitter chat room](https://gitter.im/paritytech/parity) to ask a question. We are glad to help! -Parity's current release is 1.6. You can download it at https://github.com/paritytech/parity/releases or follow the instructions -below to build from source. +**For security-critical issues**, please refer to the security policy outlined in `SECURITY.MD`. + +Parity's current release is 1.7. You can download it at https://github.com/paritytech/parity/releases or follow the instructions below to build from source. ---- diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..8257cf733 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,54 @@ +# Security Policy + +For security inquiries or vulnerability reports, please send a message to security@parity.io. + +Please use a descriptive subject line so we can identify the report as such. + +If you send a report, we will respond to the e-mail within 48 hours, and provide regular updates from that time onwards. + +If you would like to encrypt your report, please use the PGP key provided below. +It is also reproduced [on MIT's key server](https://pgp.mit.edu/pks/lookup?op=get&search=0x5D0F03018D07DE73) + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBFlyIAwBCACe0keNPjgYzZ1Oy/8t3zj/Qw9bHHqrzx7FWy8NbXnYBM19NqOZ +DIP7Oe0DvCaf/uruBskCS0iVstHlEFQ2AYe0Ei0REt9lQdy61GylU/DEB3879IG+ +6FO0SnFeYeerv1/hFI2K6uv8v7PyyVDiiJSW0I1KIs2OBwJicTKmWxLAeQsRgx9G +yRGalrVk4KP+6pWTA7k3DxmDZKZyfYV/Ej10NtuzmsemwDbv98HKeomp/kgFOfSy +3AZjeCpctlsNqpjUuXa0/HudmH2WLxZ0fz8XeoRh8XM9UudNIecjrDqmAFrt/btQ +/3guvlzhFCdhYPVGsUusKMECk/JG+Xx1/1ZjABEBAAG0LFBhcml0eSBTZWN1cml0 +eSBDb250YWN0IDxzZWN1cml0eUBwYXJpdHkuaW8+iQFUBBMBCAA+FiEE2uUVYCjP +N6B8aTiDXQ8DAY0H3nMFAllyIAwCGwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwEC +HgECF4AACgkQXQ8DAY0H3nM60wgAkS3A36Zc+upiaxU7tumcGv+an17j7gin0sif ++0ELSjVfrXInM6ovai+NhUdcLkJ7tCrKS90fvlaELK5Sg9CXBWCTFccKN4A/B7ey +rOg2NPXUecnyBB/XqQgKYH7ujYlOlqBDXMfz6z8Hj6WToxg9PPMGGomyMGh8AWxM +3yRPFs5RKt0VKgN++5N00oly5Y8ri5pgCidDvCLYMGTVDHFKwkuc9w6BlWlu1R1e +/hXFWUFAP1ffTAul3QwyKhjPn2iotCdxXjvt48KaU8DN4iL7aMBN/ZBKqGS7yRdF +D/JbJyaaJ0ZRvFSTSXy/sWY3z1B5mtCPBxco8hqqNfRkCwuZ6LkBDQRZciAMAQgA +8BP8xrwe12TOUTqL/Vrbxv/FLdhKh53J6TrPKvC2TEEKOrTNo5ahRq+XOS5E7G2N +x3b+fq8gR9BzFcldAx0XWUtGs/Wv++ulaSNqTBxj13J3G3WGsUfMKxRgj//piCUD +bCFLQfGZdKk0M1o9QkPVARwwmvCNiNB/l++xGqPtfc44H5jWj3GoGvL2MkShPzrN +yN/bJ+m+R5gtFGdInqa5KXBuxxuW25eDKJ+LzjbgUgeC76wNcfOiQHTdMkcupjdO +bbGFwo10hcbRAOcZEv6//Zrlmk/6nPxEd2hN20St2bSN0+FqfZ267mWEu3ejsgF8 +ArdCpv5h4fBvJyNwiTZwIQARAQABiQE8BBgBCAAmFiEE2uUVYCjPN6B8aTiDXQ8D +AY0H3nMFAllyIAwCGwwFCQPCZwAACgkQXQ8DAY0H3nNisggAl4fqhRlA34wIb190 +sqXHVxiCuzPaqS6krE9xAa1+gncX485OtcJNqnjugHm2rFE48lv7oasviuPXuInE +/OgVFnXYv9d/Xx2JUeDs+bFTLouCDRY2Unh7KJZasfqnMcCHWcxHx5FvRNZRssaB +WTZVo6sizPurGUtbpYe4/OLFhadBqAE0EUmVRFEUMc1YTnu4eLaRBzoWN4d2UWwi +LN25RSrVSke7LTSFbgn9ntQrQ2smXSR+cdNkkfRCjFcpUaecvFl9HwIqoyVbT4Ym +0hbpbbX/cJdc91tKa+psa29uMeGL/cgL9fAu19yNFRyOTMxjZnvql1X/WE1pLmoP +ETBD1Q== +=K9Qw +-----END PGP PUBLIC KEY BLOCK----- +``` + +Important Legal Information: + +Your submission might be eligible for a bug bounty. The bug bounty program is an experimental and discretionary rewards program for the Parity community to reward those who are helping to improve the Parity software. Rewards are at the sole discretion of Parity Technologies Ltd.. + +We are not able to issue rewards to individuals who are on sanctions lists or who are in countries on sanctions lists (e.g. North Korea, Iran, etc). + +You are responsible for all taxes. All rewards are subject to applicable law. + +Finally, your testing must not violate any law or compromise any data that is not yours. diff --git a/chainspec/Cargo.toml b/chainspec/Cargo.toml new file mode 100644 index 000000000..73daf795a --- /dev/null +++ b/chainspec/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "chainspec" +version = "0.1.0" +authors = ["debris "] + +[dependencies] +ethjson = { path = "../json" } +serde_json = "1.0" +serde_ignored = "0.0.4" diff --git a/chainspec/src/main.rs b/chainspec/src/main.rs new file mode 100644 index 000000000..bcef53f3f --- /dev/null +++ b/chainspec/src/main.rs @@ -0,0 +1,48 @@ +extern crate serde_json; +extern crate serde_ignored; +extern crate ethjson; + +use std::collections::BTreeSet; +use std::{fs, env, process}; +use ethjson::spec::Spec; + +fn quit(s: &str) -> ! { + println!("{}", s); + process::exit(1); +} + +fn main() { + let mut args = env::args(); + if args.len() != 2 { + quit("You need to specify chainspec.json\n\ + \n\ + ./chainspec "); + } + + let path = args.nth(1).expect("args.len() == 2; qed"); + let file = match fs::File::open(&path) { + Ok(file) => file, + Err(_) => quit(&format!("{} could not be opened", path)), + }; + + let mut unused = BTreeSet::new(); + let mut deserializer = serde_json::Deserializer::from_reader(file); + + let spec: Result = serde_ignored::deserialize(&mut deserializer, |field| { + unused.insert(field.to_string()); + }); + + if let Err(err) = spec { + quit(&format!("{} {}", path, err.to_string())); + } + + if !unused.is_empty() { + let err = unused.into_iter() + .map(|field| format!("{} unexpected field `{}`", path, field)) + .collect::>() + .join("\n"); + quit(&err); + } + + println!("{} is valid", path); +} diff --git a/dapps/src/api/api.rs b/dapps/src/api/api.rs index 7d38e288f..7bd7fa049 100644 --- a/dapps/src/api/api.rs +++ b/dapps/src/api/api.rs @@ -21,7 +21,7 @@ use hyper::method::Method; use hyper::status::StatusCode; use api::{response, types}; -use api::time::TimeChecker; +use api::time::{TimeChecker, MAX_DRIFT}; use apps::fetcher::Fetcher; use handlers::{self, extract_url}; use endpoint::{Endpoint, Handler, EndpointPath}; @@ -122,7 +122,6 @@ impl RestApiRouter { // Check time let time = { - const MAX_DRIFT: i64 = 500; let (status, message, details) = match time { Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => { (HealthStatus::Ok, "".into(), diff) @@ -147,13 +146,7 @@ impl RestApiRouter { HealthInfo { status, message, details, } }; - let status = if [&peers.status, &sync.status, &time.status].iter().any(|x| *x != &HealthStatus::Ok) { - StatusCode::PreconditionFailed // HTTP 412 - } else { - StatusCode::Ok // HTTP 200 - }; - - response::as_json(status, &Health { peers, sync, time }) + response::as_json(StatusCode::Ok, &Health { peers, sync, time }) }; let time = self.api.time.time_drift(); diff --git a/dapps/src/api/time.rs b/dapps/src/api/time.rs index 084890dc9..06b9cee7f 100644 --- a/dapps/src/api/time.rs +++ b/dapps/src/api/time.rs @@ -33,17 +33,22 @@ use std::io; use std::{fmt, mem, time}; - use std::collections::VecDeque; +use std::sync::atomic::{self, AtomicUsize}; +use std::sync::Arc; + use futures::{self, Future, BoxFuture}; -use futures_cpupool::CpuPool; +use futures::future::{self, IntoFuture}; +use futures_cpupool::{CpuPool, CpuFuture}; use ntp; use time::{Duration, Timespec}; -use util::{Arc, RwLock}; +use util::RwLock; /// Time checker error. #[derive(Debug, Clone, PartialEq)] pub enum Error { + /// No servers are currently available for a query. + NoServersAvailable, /// There was an error when trying to reach the NTP server. Ntp(String), /// IO error when reading NTP response. @@ -55,6 +60,7 @@ impl fmt::Display for Error { use self::Error::*; match *self { + NoServersAvailable => write!(fmt, "No NTP servers available"), Ntp(ref err) => write!(fmt, "NTP error: {}", err), Io(ref err) => write!(fmt, "Connection Error: {}", err), } @@ -71,52 +77,123 @@ impl From for Error { /// NTP time drift checker. pub trait Ntp { + /// Returned Future. + type Future: IntoFuture; + /// Returns the current time drift. - fn drift(&self) -> BoxFuture; + fn drift(&self) -> Self::Future; +} + +const SERVER_MAX_POLL_INTERVAL_SECS: u64 = 60; +#[derive(Debug)] +struct Server { + pub address: String, + next_call: RwLock, + failures: AtomicUsize, +} + +impl Server { + pub fn is_available(&self) -> bool { + *self.next_call.read() < time::Instant::now() + } + + pub fn report_success(&self) { + self.failures.store(0, atomic::Ordering::SeqCst); + self.update_next_call(1) + } + + pub fn report_failure(&self) { + let errors = self.failures.fetch_add(1, atomic::Ordering::SeqCst); + self.update_next_call(1 << errors) + } + + fn update_next_call(&self, delay: usize) { + *self.next_call.write() = time::Instant::now() + time::Duration::from_secs(delay as u64 * SERVER_MAX_POLL_INTERVAL_SECS); + } +} + +impl> From for Server { + fn from(t: T) -> Self { + Server { + address: t.as_ref().to_owned(), + next_call: RwLock::new(time::Instant::now()), + failures: Default::default(), + } + } } /// NTP client using the SNTP algorithm for calculating drift. #[derive(Clone)] pub struct SimpleNtp { - address: Arc, + addresses: Vec>, pool: CpuPool, } impl fmt::Debug for SimpleNtp { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Ntp {{ address: {} }}", self.address) + f + .debug_struct("SimpleNtp") + .field("addresses", &self.addresses) + .finish() } } impl SimpleNtp { - fn new(address: &str, pool: CpuPool) -> SimpleNtp { + fn new>(addresses: &[T], pool: CpuPool) -> SimpleNtp { SimpleNtp { - address: Arc::new(address.to_owned()), + addresses: addresses.iter().map(Server::from).map(Arc::new).collect(), pool: pool, } } } impl Ntp for SimpleNtp { - fn drift(&self) -> BoxFuture { - let address = self.address.clone(); - self.pool.spawn_fn(move || { - let packet = ntp::request(&*address)?; - let dest_time = ::time::now_utc().to_timespec(); - let orig_time = Timespec::from(packet.orig_time); - let recv_time = Timespec::from(packet.recv_time); - let transmit_time = Timespec::from(packet.transmit_time); + type Future = future::Either< + CpuFuture, + future::FutureResult, + >; - let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2; + fn drift(&self) -> Self::Future { + use self::future::Either::{A, B}; - Ok(drift) - }).boxed() + let server = self.addresses.iter().find(|server| server.is_available()); + server.map(|server| { + let server = server.clone(); + A(self.pool.spawn_fn(move || { + debug!(target: "dapps", "Fetching time from {}.", server.address); + + match ntp::request(&server.address) { + Ok(packet) => { + let dest_time = ::time::now_utc().to_timespec(); + let orig_time = Timespec::from(packet.orig_time); + let recv_time = Timespec::from(packet.recv_time); + let transmit_time = Timespec::from(packet.transmit_time); + + let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2; + + server.report_success(); + Ok(drift) + }, + Err(err) => { + server.report_failure(); + Err(err.into()) + }, + } + })) + }).unwrap_or_else(|| B(future::err(Error::NoServersAvailable))) } } +// NOTE In a positive scenario first results will be seen after: +// MAX_RESULTS * UPDATE_TIMEOUT_INCOMPLETE_SECS seconds. const MAX_RESULTS: usize = 4; -const UPDATE_TIMEOUT_OK_SECS: u64 = 30; -const UPDATE_TIMEOUT_ERR_SECS: u64 = 2; +const UPDATE_TIMEOUT_OK_SECS: u64 = 6 * 60 * 60; +const UPDATE_TIMEOUT_WARN_SECS: u64 = 15 * 60; +const UPDATE_TIMEOUT_ERR_SECS: u64 = 60; +const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10; + +/// Maximal valid time drift. +pub const MAX_DRIFT: i64 = 500; #[derive(Debug, Clone)] /// A time checker. @@ -127,13 +204,13 @@ pub struct TimeChecker { impl TimeChecker { /// Creates new time checker given the NTP server address. - pub fn new(ntp_address: String, pool: CpuPool) -> Self { + pub fn new>(ntp_addresses: &[T], pool: CpuPool) -> Self { let last_result = Arc::new(RwLock::new( // Assume everything is ok at the very beginning. (time::Instant::now(), vec![Ok(0)].into()) )); - let ntp = SimpleNtp::new(&ntp_address, pool); + let ntp = SimpleNtp::new(ntp_addresses, pool); TimeChecker { ntp, @@ -142,22 +219,34 @@ impl TimeChecker { } } -impl TimeChecker { +impl TimeChecker where ::Future: Send + 'static { /// Updates the time pub fn update(&self) -> BoxFuture { + trace!(target: "dapps", "Updating time from NTP."); let last_result = self.last_result.clone(); - self.ntp.drift().then(move |res| { + self.ntp.drift().into_future().then(move |res| { + let res = res.map(|d| d.num_milliseconds()); + + if let Err(Error::NoServersAvailable) = res { + debug!(target: "dapps", "No NTP servers available. Selecting an older result."); + return select_result(last_result.read().1.iter()); + } + + // Update the results. let mut results = mem::replace(&mut last_result.write().1, VecDeque::new()); + let has_all_results = results.len() >= MAX_RESULTS; let valid_till = time::Instant::now() + time::Duration::from_secs( - if res.is_ok() && results.len() == MAX_RESULTS { - UPDATE_TIMEOUT_OK_SECS - } else { - UPDATE_TIMEOUT_ERR_SECS + match res { + Ok(time) if has_all_results && time < MAX_DRIFT => UPDATE_TIMEOUT_OK_SECS, + Ok(_) if has_all_results => UPDATE_TIMEOUT_WARN_SECS, + Err(_) if has_all_results => UPDATE_TIMEOUT_ERR_SECS, + _ => UPDATE_TIMEOUT_INCOMPLETE_SECS, } ); + trace!(target: "dapps", "New time drift received: {:?}", res); // Push the result. - results.push_back(res.map(|d| d.num_milliseconds())); + results.push_back(res); while results.len() > MAX_RESULTS { results.pop_front(); } @@ -202,7 +291,7 @@ mod tests { use std::cell::{Cell, RefCell}; use std::time::Instant; use time::Duration; - use futures::{self, BoxFuture, Future}; + use futures::{future, Future}; use super::{Ntp, TimeChecker, Error}; use util::RwLock; @@ -217,15 +306,17 @@ mod tests { } impl Ntp for FakeNtp { - fn drift(&self) -> BoxFuture { + type Future = future::FutureResult; + + fn drift(&self) -> Self::Future { self.1.set(self.1.get() + 1); - futures::future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift().")).boxed() + future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift().")) } } fn time_checker() -> TimeChecker { let last_result = Arc::new(RwLock::new( - (Instant::now(), vec![Err(Error::Ntp("NTP server unavailable.".into()))].into()) + (Instant::now(), vec![Err(Error::Ntp("NTP server unavailable".into()))].into()) )); TimeChecker { diff --git a/dapps/src/handlers/mod.rs b/dapps/src/handlers/mod.rs index bb640ed17..7937ce667 100644 --- a/dapps/src/handlers/mod.rs +++ b/dapps/src/handlers/mod.rs @@ -68,6 +68,9 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd b"font-src 'self' data: https:;".to_vec(), // Allow inline scripts and scripts eval (webpack/jsconsole) b"script-src 'self' 'unsafe-inline' 'unsafe-eval';".to_vec(), + // Same restrictions as script-src (fallback) with additional + // blob: that is required for camera access (worker) + b"worker-src 'self' 'unsafe-inline' 'unsafe-eval' blob: ;".to_vec(), // Restrict everything else to the same origin. b"default-src 'self';".to_vec(), // Run in sandbox mode (although it's not fully safe since we allow same-origin and script) @@ -140,4 +143,3 @@ pub fn convert_uri_to_url(uri: &uri::RequestUri, host: Option<&header::Host>) -> _ => None, } } - diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 0cb7024cc..f34c24cae 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -130,7 +130,7 @@ impl Middleware { /// Creates new middleware for UI server. pub fn ui( - ntp_server: &str, + ntp_servers: &[String], pool: CpuPool, remote: Remote, dapps_domain: &str, @@ -146,7 +146,7 @@ impl Middleware { ).embeddable_on(None).allow_dapps(false)); let special = { let mut special = special_endpoints( - ntp_server, + ntp_servers, pool, content_fetcher.clone(), remote.clone(), @@ -171,7 +171,7 @@ impl Middleware { /// Creates new Dapps server middleware. pub fn dapps( - ntp_server: &str, + ntp_servers: &[String], pool: CpuPool, remote: Remote, ui_address: Option<(String, u16)>, @@ -203,7 +203,7 @@ impl Middleware { let special = { let mut special = special_endpoints( - ntp_server, + ntp_servers, pool, content_fetcher.clone(), remote.clone(), @@ -237,8 +237,8 @@ impl http::RequestMiddleware for Middleware { } } -fn special_endpoints( - ntp_server: &str, +fn special_endpoints>( + ntp_servers: &[T], pool: CpuPool, content_fetcher: Arc, remote: Remote, @@ -250,7 +250,7 @@ fn special_endpoints( special.insert(router::SpecialEndpoint::Api, Some(api::RestApi::new( content_fetcher, sync_status, - api::TimeChecker::new(ntp_server.into(), pool), + api::TimeChecker::new(ntp_servers, pool), remote, ))); special diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index 2d9d5f341..38dd82de6 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -255,7 +255,7 @@ impl Server { fetch: F, ) -> Result { let middleware = Middleware::dapps( - "pool.ntp.org:123", + &["0.pool.ntp.org:123".into(), "1.pool.ntp.org:123".into()], CpuPool::new(4), remote, signer_address, diff --git a/docker/hub/Dockerfile b/docker/hub/Dockerfile index 3120eeba7..c3406a5bd 100644 --- a/docker/hub/Dockerfile +++ b/docker/hub/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /build #ENV for build TAG ARG BUILD_TAG ENV BUILD_TAG ${BUILD_TAG:-master} -RUN echo $BUILD_TAG +RUN echo "Build tag:" $BUILD_TAG # install tools and dependencies RUN apt-get update && \ apt-get install -y --force-yes --no-install-recommends \ @@ -48,7 +48,7 @@ RUN apt-get update && \ # show backtraces RUST_BACKTRACE=1 && \ # build parity - cd /build&&git clone https://github.com/paritytech/parity && \ +cd /build&&git clone https://github.com/paritytech/parity && \ cd parity && \ git pull&& \ git checkout $BUILD_TAG && \ diff --git a/ethash/Cargo.toml b/ethash/Cargo.toml index f7d37e375..87069d6f8 100644 --- a/ethash/Cargo.toml +++ b/ethash/Cargo.toml @@ -10,3 +10,7 @@ log = "0.3" sha3 = { path = "../util/sha3" } primal = "0.2.3" parking_lot = "0.4" +crunchy = "0.1.0" + +[features] +benches = [] \ No newline at end of file diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index fae47c505..ab2c758df 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -123,7 +123,9 @@ impl Light { } let num_nodes = cache_size / NODE_BYTES; let mut nodes: Vec = Vec::with_capacity(num_nodes); - nodes.resize(num_nodes, unsafe { mem::uninitialized() }); + + unsafe { nodes.set_len(num_nodes) }; + let buf = unsafe { slice::from_raw_parts_mut(nodes.as_mut_ptr() as *mut u8, cache_size) }; file.read_exact(buf)?; Ok(Light { @@ -208,17 +210,20 @@ pub fn slow_get_seedhash(block_number: u64) -> H256 { SeedHashCompute::resume_compute_seedhash([0u8; 32], 0, block_number / ETHASH_EPOCH_LENGTH) } -#[inline] fn fnv_hash(x: u32, y: u32) -> u32 { return x.wrapping_mul(FNV_PRIME) ^ y; } -#[inline] fn sha3_512(input: &[u8], output: &mut [u8]) { unsafe { sha3::sha3_512(output.as_mut_ptr(), output.len(), input.as_ptr(), input.len()) }; } -#[inline] +fn sha3_512_inplace(input: &mut [u8]) { + // This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This + // means that we can reuse the input buffer for both input and output. + unsafe { sha3::sha3_512(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()) }; +} + fn get_cache_size(block_number: u64) -> usize { let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); sz = sz - NODE_BYTES as u64; @@ -228,7 +233,6 @@ fn get_cache_size(block_number: u64) -> usize { sz as usize } -#[inline] fn get_data_size(block_number: u64) -> usize { let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH); sz = sz - ETHASH_MIX_BYTES as u64; @@ -238,7 +242,6 @@ fn get_data_size(block_number: u64) -> usize { sz as usize } - /// Difficulty quick check for POW preverification /// /// `header_hash` The hash of the header @@ -246,17 +249,27 @@ fn get_data_size(block_number: u64) -> usize { /// `mix_hash` The mix digest hash /// Boundary recovered from mix hash pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256) -> H256 { - let mut buf = [0u8; 64 + 32]; - unsafe { ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32) }; - unsafe { ptr::copy_nonoverlapping(mem::transmute(&nonce), buf[32..].as_mut_ptr(), 8) }; + unsafe { + // This is safe - the `sha3_512` call below reads the first 40 bytes (which we explicitly set + // with two `copy_nonoverlapping` calls) but writes the first 64, and then we explicitly write + // the next 32 bytes before we read the whole thing with `sha3_256`. + // + // This cannot be elided by the compiler as it doesn't know the implementation of + // `sha3_512`. + let mut buf: [u8; 64 + 32] = mem::uninitialized(); - unsafe { sha3::sha3_512(buf.as_mut_ptr(), 64, buf.as_ptr(), 40) }; - unsafe { ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32) }; + ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32); + ptr::copy_nonoverlapping(mem::transmute(&nonce), buf[32..].as_mut_ptr(), 8); - let mut hash = [0u8; 32]; - unsafe { sha3::sha3_256(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len()) }; - hash.as_mut_ptr(); - hash + sha3::sha3_512(buf.as_mut_ptr(), 64, buf.as_ptr(), 40); + ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32); + + // This is initialized in `sha3_256` + let mut hash: [u8; 32] = mem::uninitialized(); + sha3::sha3_256(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len()); + + hash + } } /// Calculate the light client data @@ -269,78 +282,194 @@ pub fn light_compute(light: &Light, header_hash: &H256, nonce: u64) -> ProofOfWo } fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) -> ProofOfWork { + macro_rules! make_const_array { + ($n:expr, $value:expr) => {{ + // We use explicit lifetimes to ensure that val's borrow is invalidated until the + // transmuted val dies. + unsafe fn make_const_array<'a, T, U>(val: &'a mut [T]) -> &'a mut [U; $n] { + use ::std::mem; + + debug_assert_eq!(val.len() * mem::size_of::(), $n * mem::size_of::()); + mem::transmute(val.as_mut_ptr()) + } + + make_const_array($value) + }} + } + + #[repr(C)] + struct MixBuf { + half_mix: Node, + compress_bytes: [u8; MIX_WORDS], + }; + if full_size % MIX_WORDS != 0 { panic!("Unaligned full size"); } - // pack hash and nonce together into first 40 bytes of s_mix - let mut s_mix: [Node; MIX_NODES + 1] = [Node::default(), Node::default(), Node::default()]; - unsafe { ptr::copy_nonoverlapping(header_hash.as_ptr(), s_mix.get_unchecked_mut(0).bytes.as_mut_ptr(), 32) }; - unsafe { ptr::copy_nonoverlapping(mem::transmute(&nonce), s_mix.get_unchecked_mut(0).bytes[32..].as_mut_ptr(), 8) }; - // compute sha3-512 hash and replicate across mix - unsafe { - sha3::sha3_512(s_mix.get_unchecked_mut(0).bytes.as_mut_ptr(), NODE_BYTES, s_mix.get_unchecked(0).bytes.as_ptr(), 40); - let (f_mix, mut mix) = s_mix.split_at_mut(1); - for w in 0..MIX_WORDS { - *mix.get_unchecked_mut(0).as_words_mut().get_unchecked_mut(w) = *f_mix.get_unchecked(0).as_words().get_unchecked(w % NODE_WORDS); - } + // You may be asking yourself: what in the name of Crypto Jesus is going on here? So: we need + // `half_mix` and `compress_bytes` in a single array later down in the code (we hash them + // together to create `value`) so that we can hash the full array. However, we do a bunch of + // reading and writing to these variables first. We originally allocated two arrays and then + // stuck them together with `ptr::copy_nonoverlapping` at the end, but this method is + // _significantly_ faster - by my benchmarks, a consistent 3-5%. This is the most ridiculous + // optimization I have ever done and I am so sorry. I can only chalk it up to cache locality + // improvements, since I can't imagine that 3-5% of our runtime is taken up by catting two + // arrays together. + let mut buf: MixBuf = MixBuf { + half_mix: unsafe { + // Pack `header_hash` and `nonce` together + // We explicitly write the first 40 bytes, leaving the last 24 as uninitialized. Then + // `sha3_512` reads the first 40 bytes (4th parameter) and overwrites the entire array, + // leaving it fully initialized. + let mut out: [u8; NODE_BYTES] = mem::uninitialized(); - let page_size = 4 * MIX_WORDS; - let num_full_pages = (full_size / page_size) as u32; - let cache: &[Node] = &light.cache; // deref once for better performance + ptr::copy_nonoverlapping( + header_hash.as_ptr(), + out.as_mut_ptr(), + header_hash.len(), + ); + ptr::copy_nonoverlapping( + mem::transmute(&nonce), + out[header_hash.len()..].as_mut_ptr(), + mem::size_of::(), + ); - for i in 0..(ETHASH_ACCESSES as u32) { - let index = fnv_hash(f_mix.get_unchecked(0).as_words().get_unchecked(0) ^ i, *mix.get_unchecked(0).as_words().get_unchecked((i as usize) % MIX_WORDS)) % num_full_pages; - for n in 0..MIX_NODES { - let tmp_node = calculate_dag_item(index * MIX_NODES as u32 + n as u32, cache); - for w in 0..NODE_WORDS { - *mix.get_unchecked_mut(n).as_words_mut().get_unchecked_mut(w) = fnv_hash(*mix.get_unchecked(n).as_words().get_unchecked(w), *tmp_node.as_words().get_unchecked(w)); + // compute sha3-512 hash and replicate across mix + sha3::sha3_512( + out.as_mut_ptr(), + NODE_BYTES, + out.as_ptr(), + header_hash.len() + mem::size_of::() + ); + + Node { bytes: out } + }, + // This is fully initialized before being read, see `let mut compress = ...` below + compress_bytes: unsafe { mem::uninitialized() }, + }; + + let mut mix: [_; MIX_NODES] = [buf.half_mix.clone(), buf.half_mix.clone()]; + + let page_size = 4 * MIX_WORDS; + let num_full_pages = (full_size / page_size) as u32; + // deref once for better performance + let cache: &[Node] = &light.cache; + let first_val = buf.half_mix.as_words()[0]; + + debug_assert_eq!(MIX_NODES, 2); + debug_assert_eq!(NODE_WORDS, 16); + + for i in 0..ETHASH_ACCESSES as u32 { + let index = { + // This is trivially safe, but does not work on big-endian. The safety of this is + // asserted in debug builds (see the definition of `make_const_array!`). + let mix_words: &mut [u32; MIX_WORDS] = unsafe { + make_const_array!(MIX_WORDS, &mut mix) + }; + + fnv_hash( + first_val ^ i, + mix_words[i as usize % MIX_WORDS] + ) % num_full_pages + }; + + unroll! { + // MIX_NODES + for n in 0..2 { + let tmp_node = calculate_dag_item( + index * MIX_NODES as u32 + n as u32, + cache, + ); + + unroll! { + // NODE_WORDS + for w in 0..16 { + mix[n].as_words_mut()[w] = + fnv_hash( + mix[n].as_words()[w], + tmp_node.as_words()[w], + ); + } } } } + } - // compress mix - for i in 0..(MIX_WORDS / 4) { - let w = i * 4; - let mut reduction = *mix.get_unchecked(0).as_words().get_unchecked(w + 0); - reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 1); - reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 2); - reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 3); - *mix.get_unchecked_mut(0).as_words_mut().get_unchecked_mut(i) = reduction; - } + let mix_words: [u32; MIX_WORDS] = unsafe { mem::transmute(mix) }; - let mut mix_hash = [0u8; 32]; - let mut buf = [0u8; 32 + 64]; - ptr::copy_nonoverlapping(f_mix.get_unchecked_mut(0).bytes.as_ptr(), buf.as_mut_ptr(), 64); - ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), buf[64..].as_mut_ptr(), 32); - ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), mix_hash.as_mut_ptr(), 32); - let mut value: H256 = [0u8; 32]; - sha3::sha3_256(value.as_mut_ptr(), value.len(), buf.as_ptr(), buf.len()); - ProofOfWork { - mix_hash: mix_hash, - value: value, + { + // This is an uninitialized buffer to begin with, but we iterate precisely `compress.len()` + // times and set each index, leaving the array fully initialized. THIS ONLY WORKS ON LITTLE- + // ENDIAN MACHINES. See a future PR to make this and the rest of the code work correctly on + // big-endian arches like mips. + let mut compress: &mut [u32; MIX_WORDS / 4] = unsafe { + make_const_array!(MIX_WORDS / 4, &mut buf.compress_bytes) + }; + + // Compress mix + debug_assert_eq!(MIX_WORDS / 4, 8); + unroll! { + for i in 0..8 { + let w = i * 4; + + let mut reduction = mix_words[w + 0]; + reduction = reduction.wrapping_mul(FNV_PRIME) ^ mix_words[w + 1]; + reduction = reduction.wrapping_mul(FNV_PRIME) ^ mix_words[w + 2]; + reduction = reduction.wrapping_mul(FNV_PRIME) ^ mix_words[w + 3]; + compress[i] = reduction; + } } } + + let mix_hash = buf.compress_bytes; + + let value: H256 = unsafe { + // We can interpret the buffer as an array of `u8`s, since it's `repr(C)`. + let read_ptr: *const u8 = mem::transmute(&buf); + // We overwrite the second half since `sha3_256` has an internal buffer and so allows + // overlapping arrays as input. + let write_ptr: *mut u8 = mem::transmute(&mut buf.compress_bytes); + sha3::sha3_256( + write_ptr, + buf.compress_bytes.len(), + read_ptr, + buf.half_mix.bytes.len() + buf.compress_bytes.len(), + ); + buf.compress_bytes + }; + + ProofOfWork { + mix_hash: mix_hash, + value: value, + } } fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node { - unsafe { - let num_parent_nodes = cache.len(); - let init = cache.get_unchecked(node_index as usize % num_parent_nodes); - let mut ret = init.clone(); - *ret.as_words_mut().get_unchecked_mut(0) ^= node_index; - sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len()); + let num_parent_nodes = cache.len(); + let mut ret = cache[node_index as usize % num_parent_nodes].clone(); + ret.as_words_mut()[0] ^= node_index; - for i in 0..ETHASH_DATASET_PARENTS { - let parent_index = fnv_hash(node_index ^ i, *ret.as_words().get_unchecked(i as usize % NODE_WORDS)) % num_parent_nodes as u32; - let parent = cache.get_unchecked(parent_index as usize); - for w in 0..NODE_WORDS { - *ret.as_words_mut().get_unchecked_mut(w) = fnv_hash(*ret.as_words().get_unchecked(w), *parent.as_words().get_unchecked(w)); + sha3_512_inplace(&mut ret.bytes); + + debug_assert_eq!(NODE_WORDS, 16); + for i in 0..ETHASH_DATASET_PARENTS as u32 { + let parent_index = fnv_hash( + node_index ^ i, + ret.as_words()[i as usize % NODE_WORDS], + ) % num_parent_nodes as u32; + let parent = &cache[parent_index as usize]; + + unroll! { + for w in 0..16 { + ret.as_words_mut()[w] = fnv_hash(ret.as_words()[w], parent.as_words()[w]); } } - sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len()); - ret } + + sha3_512_inplace(&mut ret.bytes); + + ret } fn light_new>(cache_dir: T, block_number: u64) -> Light { @@ -351,21 +480,30 @@ fn light_new>(cache_dir: T, block_number: u64) -> Light { assert!(cache_size % NODE_BYTES == 0, "Unaligned cache size"); let num_nodes = cache_size / NODE_BYTES; - let mut nodes = Vec::with_capacity(num_nodes); - nodes.resize(num_nodes, Node::default()); + let mut nodes: Vec = Vec::with_capacity(num_nodes); unsafe { + // Use uninit instead of unnecessarily writing `size_of::() * num_nodes` 0s + nodes.set_len(num_nodes); + sha3_512(&seedhash[0..32], &mut nodes.get_unchecked_mut(0).bytes); for i in 1..num_nodes { sha3::sha3_512(nodes.get_unchecked_mut(i).bytes.as_mut_ptr(), NODE_BYTES, nodes.get_unchecked(i - 1).bytes.as_ptr(), NODE_BYTES); } + debug_assert_eq!(NODE_WORDS, 16); + + // This _should_ get unrolled by the compiler, since it's not using the loop variable. for _ in 0..ETHASH_CACHE_ROUNDS { for i in 0..num_nodes { let idx = *nodes.get_unchecked_mut(i).as_words().get_unchecked(0) as usize % num_nodes; let mut data = nodes.get_unchecked((num_nodes - 1 + i) % num_nodes).clone(); - for w in 0..NODE_WORDS { - *data.as_words_mut().get_unchecked_mut(w) ^= *nodes.get_unchecked(idx).as_words().get_unchecked(w); + + unroll! { + for w in 0..16 { + *data.as_words_mut().get_unchecked_mut(w) ^= *nodes.get_unchecked(idx).as_words().get_unchecked(w); + } } + sha3_512(&data.bytes, &mut nodes.get_unchecked_mut(i).bytes); } } diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs index a598af6f7..9112546c4 100644 --- a/ethash/src/lib.rs +++ b/ethash/src/lib.rs @@ -16,10 +16,15 @@ //! Ethash implementation //! See https://github.com/ethereum/wiki/wiki/Ethash + +#![cfg_attr(feature = "benches", feature(test))] + extern crate primal; extern crate sha3; extern crate parking_lot; +#[macro_use] +extern crate crunchy; #[macro_use] extern crate log; mod compute; @@ -128,3 +133,29 @@ fn test_lru() { assert_eq!(ethash.cache.lock().recent_epoch.unwrap(), 2); assert_eq!(ethash.cache.lock().prev_epoch.unwrap(), 0); } + +#[cfg(feature = "benches")] +mod benchmarks { + extern crate test; + + use compute::{Light, light_compute, SeedHashCompute}; + use self::test::Bencher; + + #[bench] + fn bench_light_compute(b: &mut Bencher) { + use ::std::env; + + let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72]; + let nonce = 0xd7b3ac70a301a249; + let light = Light::new(env::temp_dir(), 486382); + + b.iter(|| light_compute(&light, &hash, nonce)); + } + + #[bench] + fn bench_seedhash(b: &mut Bencher) { + let seed_compute = SeedHashCompute::new(); + + b.iter(|| seed_compute.get_seedhash(486382)); + } +} diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index c629c3aca..0b4abc1bb 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -44,15 +44,20 @@ lru-cache = "0.1.0" native-contracts = { path = "native_contracts" } num = "0.1" num_cpus = "1.2" +price-info = { path = "../price-info" } rand = "0.3" rlp = { path = "../util/rlp" } rust-crypto = "0.2.34" rustc-hex = "1.0" -rustc-serialize = "0.3" semver = "0.6" stats = { path = "../util/stats" } time = "0.1" transient-hashmap = "0.4" +using_queue = { path = "../util/using_queue" } +table = { path = "../util/table" } +bloomable = { path = "../util/bloomable" } +vm = { path = "vm" } +wasm = { path = "wasm" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index b48dd2346..2780703da 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -13,7 +13,9 @@ ethjson = { path = "../../json" } lazy_static = "0.2" log = "0.3" rlp = { path = "../../util/rlp" } +vm = { path = "../vm" } parity-wasm = "0.12" +ethcore-logger = { path = "../../logger" } wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } [dev-dependencies] diff --git a/ethcore/evm/src/benches/mod.rs b/ethcore/evm/src/benches/mod.rs index 4463696d6..ecb7d379a 100644 --- a/ethcore/evm/src/benches/mod.rs +++ b/ethcore/evm/src/benches/mod.rs @@ -25,7 +25,7 @@ extern crate test; use self::test::{Bencher, black_box}; use util::*; -use evm::action_params::ActionParams; +use vm::ActionParams; use evm::{self, Factory, VMType}; use evm::tests::FakeExt; diff --git a/ethcore/evm/src/evm.rs b/ethcore/evm/src/evm.rs index c27caf8b3..d593143a6 100644 --- a/ethcore/evm/src/evm.rs +++ b/ethcore/evm/src/evm.rs @@ -17,142 +17,8 @@ //! Evm interface. use std::{ops, cmp, fmt}; -use util::{U128, U256, U512, trie}; -use action_params::ActionParams; -use {Ext}; - -use super::wasm; - -/// Evm errors. -#[derive(Debug, Clone, PartialEq)] -pub enum Error { - /// `OutOfGas` is returned when transaction execution runs out of gas. - /// The state should be reverted to the state from before the - /// transaction execution. But it does not mean that transaction - /// was invalid. Balance still should be transfered and nonce - /// should be increased. - OutOfGas, - /// `BadJumpDestination` is returned when execution tried to move - /// to position that wasn't marked with JUMPDEST instruction - BadJumpDestination { - /// Position the code tried to jump to. - destination: usize - }, - /// `BadInstructions` is returned when given instruction is not supported - BadInstruction { - /// Unrecognized opcode - instruction: u8, - }, - /// `StackUnderflow` when there is not enough stack elements to execute instruction - StackUnderflow { - /// Invoked instruction - instruction: &'static str, - /// How many stack elements was requested by instruction - wanted: usize, - /// How many elements were on stack - on_stack: usize - }, - /// When execution would exceed defined Stack Limit - OutOfStack { - /// Invoked instruction - instruction: &'static str, - /// How many stack elements instruction wanted to push - wanted: usize, - /// What was the stack limit - limit: usize - }, - /// Built-in contract failed on given input - BuiltIn(&'static str), - /// When execution tries to modify the state in static context - MutableCallInStaticContext, - /// Likely to cause consensus issues. - Internal(String), - /// Wasm runtime error - Wasm(String), -} - -impl From> for Error { - fn from(err: Box) -> Self { - Error::Internal(format!("Internal error: {}", err)) - } -} - -impl From for Error { - fn from(err: wasm::RuntimeError) -> Self { - Error::Wasm(format!("Runtime error: {:?}", err)) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - match *self { - OutOfGas => write!(f, "Out of gas"), - BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination), - BadInstruction { instruction } => write!(f, "Bad instruction {:x}", instruction), - StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack), - OutOfStack { instruction, wanted, limit } => write!(f, "Out of stack {} {}/{}", instruction, wanted, limit), - BuiltIn(name) => write!(f, "Built-in failed: {}", name), - Internal(ref msg) => write!(f, "Internal error: {}", msg), - MutableCallInStaticContext => write!(f, "Mutable call in static context"), - Wasm(ref msg) => write!(f, "Internal error: {}", msg), - } - } -} - -/// A specialized version of Result over EVM errors. -pub type Result = ::std::result::Result; - -/// Return data buffer. Holds memory from a previous call and a slice into that memory. -#[derive(Debug)] -pub struct ReturnData { - mem: Vec, - offset: usize, - size: usize, -} - -impl ::std::ops::Deref for ReturnData { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.mem[self.offset..self.offset + self.size] - } -} - -impl ReturnData { - /// Create empty `ReturnData`. - pub fn empty() -> Self { - ReturnData { - mem: Vec::new(), - offset: 0, - size: 0, - } - } - /// Create `ReturnData` from give buffer and slice. - pub fn new(mem: Vec, offset: usize, size: usize) -> Self { - ReturnData { - mem: mem, - offset: offset, - size: size, - } - } -} - -/// Gas Left: either it is a known value, or it needs to be computed by processing -/// a return instruction. -#[derive(Debug)] -pub enum GasLeft { - /// Known gas left - Known(U256), - /// Return or Revert instruction must be processed. - NeedsReturn { - /// Amount of gas left. - gas_left: U256, - /// Return data buffer. - data: ReturnData, - /// Apply or revert state changes on revert. - apply_state: bool - }, -} +use util::{U128, U256, U512}; +use vm::{Ext, Result, ReturnData, GasLeft, Error}; /// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing /// a return instruction. @@ -281,15 +147,6 @@ impl CostType for usize { } } -/// Evm interface -pub trait Evm { - /// This function should be used to execute transaction. - /// - /// It returns either an error, a known amount of gas left, or parameters to be used - /// to compute the final gas left. - fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result; -} - #[cfg(test)] mod tests { use util::U256; diff --git a/ethcore/evm/src/factory.rs b/ethcore/evm/src/factory.rs index 2d8934ca1..20275dbff 100644 --- a/ethcore/evm/src/factory.rs +++ b/ethcore/evm/src/factory.rs @@ -17,7 +17,7 @@ //! Evm factory. //! use std::sync::Arc; -use evm::Evm; +use vm::Vm; use util::U256; use super::interpreter::SharedCache; use super::vmtype::VMType; @@ -33,7 +33,7 @@ impl Factory { /// Create fresh instance of VM /// Might choose implementation depending on supplied gas. #[cfg(feature = "jit")] - pub fn create(&self, gas: U256) -> Box { + pub fn create(&self, gas: U256) -> Box { match self.evm { VMType::Jit => { Box::new(super::jit::JitEvm::default()) @@ -49,7 +49,7 @@ impl Factory { /// Create fresh instance of VM /// Might choose implementation depending on supplied gas. #[cfg(not(feature = "jit"))] - pub fn create(&self, gas: U256) -> Box { + pub fn create(&self, gas: U256) -> Box { match self.evm { VMType::Interpreter => if Self::can_fit_in_usize(gas) { Box::new(super::interpreter::Interpreter::::new(self.evm_cache.clone())) diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index c2dcf5412..161c7db39 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -14,18 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::cmp; use util::*; use super::u256_to_address; -use {evm, ext}; +use {evm, vm}; use instructions::{self, Instruction, InstructionInfo}; use interpreter::stack::Stack; -use schedule::Schedule; +use vm::Schedule; macro_rules! overflowing { ($x: expr) => {{ let (v, overflow) = $x; - if overflow { return Err(evm::Error::OutOfGas); } + if overflow { return Err(vm::Error::OutOfGas); } v }} } @@ -59,16 +60,16 @@ impl Gasometer { } } - pub fn verify_gas(&self, gas_cost: &Gas) -> evm::Result<()> { + pub fn verify_gas(&self, gas_cost: &Gas) -> vm::Result<()> { match &self.current_gas < gas_cost { - true => Err(evm::Error::OutOfGas), + true => Err(vm::Error::OutOfGas), false => Ok(()) } } /// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation /// and that we `requested` some. - pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option) -> evm::Result { + pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option) -> vm::Result { // Try converting requested gas to `Gas` (`U256/u64`) // but in EIP150 even if we request more we should never fail from OOG let requested = requested.map(Gas::from_u256); @@ -82,7 +83,7 @@ impl Gasometer { }; if let Some(Ok(r)) = requested { - Ok(min(r, max_gas_provided)) + Ok(cmp::min(r, max_gas_provided)) } else { Ok(max_gas_provided) } @@ -107,12 +108,12 @@ impl Gasometer { /// it will be the amount of gas that the current context provides to the child context. pub fn requirements( &mut self, - ext: &ext::Ext, + ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack, current_mem_size: usize, - ) -> evm::Result> { + ) -> vm::Result> { let schedule = ext.schedule(); let tier = instructions::get_tier_idx(info.tier); let default_gas = Gas::from(schedule.tier_step_gas[tier]); @@ -291,7 +292,7 @@ impl Gasometer { }) } - fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> evm::Result<(Gas, Gas, usize)> { + fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> vm::Result<(Gas, Gas, usize)> { let gas_for_mem = |mem_size: Gas| { let s = mem_size >> 5; // s * memory_gas + s * s / quad_coeff_div @@ -319,12 +320,12 @@ impl Gasometer { #[inline] -fn mem_needed_const(mem: &U256, add: usize) -> evm::Result { +fn mem_needed_const(mem: &U256, add: usize) -> vm::Result { Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add)))) } #[inline] -fn mem_needed(offset: &U256, size: &U256) -> evm::Result { +fn mem_needed(offset: &U256, size: &U256) -> vm::Result { if size.is_zero() { return Ok(Gas::from(0)); } diff --git a/ethcore/evm/src/interpreter/memory.rs b/ethcore/evm/src/interpreter/memory.rs index 017b5777d..a13c99a82 100644 --- a/ethcore/evm/src/interpreter/memory.rs +++ b/ethcore/evm/src/interpreter/memory.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use util::U256; -use {ReturnData}; +use vm::ReturnData; const MAX_RETURN_WASTE_BYTES: usize = 16384; diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 885557dd3..3069ab2fe 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -23,17 +23,23 @@ mod stack; mod memory; mod shared_cache; +use std::marker::PhantomData; +use std::{cmp, mem}; +use std::sync::Arc; + +use vm::{ + self, ActionParams, ActionValue, CallType, MessageCallResult, + ContractCreateResult, CreateContractAddress, ReturnData, GasLeft +}; + +use evm::CostType; +use instructions::{self, Instruction, InstructionInfo}; + use self::gasometer::Gasometer; use self::stack::{Stack, VecStack}; use self::memory::Memory; pub use self::shared_cache::SharedCache; -use std::marker::PhantomData; -use action_params::{ActionParams, ActionValue}; -use call_type::CallType; -use instructions::{self, Instruction, InstructionInfo}; -use evm::{self, GasLeft, CostType, ReturnData}; -use ext::{self, MessageCallResult, ContractCreateResult, CreateContractAddress}; use bit_set::BitSet; use util::*; @@ -107,8 +113,8 @@ pub struct Interpreter { _type: PhantomData, } -impl evm::Evm for Interpreter { - fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result { +impl vm::Vm for Interpreter { + fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result { self.mem.clear(); let mut informant = informant::EvmInformant::new(ext.depth()); @@ -205,33 +211,34 @@ impl Interpreter { } } - fn verify_instruction(&self, ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> evm::Result<()> { + fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> vm::Result<()> { let schedule = ext.schedule(); if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) || (instruction == instructions::CREATE2 && !schedule.have_create2) || (instruction == instructions::STATICCALL && !schedule.have_static_call) || + ((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) || (instruction == instructions::REVERT && !schedule.have_revert) { - return Err(evm::Error::BadInstruction { + return Err(vm::Error::BadInstruction { instruction: instruction }); } if info.tier == instructions::GasPriceTier::Invalid { - return Err(evm::Error::BadInstruction { + return Err(vm::Error::BadInstruction { instruction: instruction }); } if !stack.has(info.args) { - Err(evm::Error::StackUnderflow { + Err(vm::Error::StackUnderflow { instruction: info.name, wanted: info.args, on_stack: stack.size() }) } else if stack.size() - info.args + info.ret > schedule.stack_limit { - Err(evm::Error::OutOfStack { + Err(vm::Error::OutOfStack { instruction: info.name, wanted: info.ret - info.args, limit: schedule.stack_limit @@ -271,12 +278,12 @@ impl Interpreter { &mut self, gas: Cost, params: &ActionParams, - ext: &mut ext::Ext, + ext: &mut vm::Ext, instruction: Instruction, code: &mut CodeReader, stack: &mut Stack, provided: Option - ) -> evm::Result> { + ) -> vm::Result> { match instruction { instructions::JUMP => { let jump = stack.pop_back(); @@ -592,13 +599,13 @@ impl Interpreter { } } - fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> evm::Result { + fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> vm::Result { let jump = jump_u.low_u64() as usize; if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { Ok(jump) } else { - Err(evm::Error::BadJumpDestination { + Err(vm::Error::BadJumpDestination { destination: jump }) } @@ -616,7 +623,7 @@ impl Interpreter { } } - fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack) -> evm::Result<()> { + fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack) -> vm::Result<()> { match instruction { instructions::DUP1...instructions::DUP16 => { let position = instructions::get_dup_position(instruction); @@ -821,7 +828,7 @@ impl Interpreter { } }, _ => { - return Err(evm::Error::BadInstruction { + return Err(vm::Error::BadInstruction { instruction: instruction }); } diff --git a/ethcore/evm/src/jit.rs b/ethcore/evm/src/jit.rs index f27e9b5d3..22262cbb6 100644 --- a/ethcore/evm/src/jit.rs +++ b/ethcore/evm/src/jit.rs @@ -19,6 +19,7 @@ use util::*; use evmjit; use evm::{self, GasLeft}; use evm::CallType; +use vm::{self, Vm}; /// Should be used to convert jit types to ethcore trait FromJit: Sized { @@ -318,7 +319,7 @@ pub struct JitEvm { context: Option, } -impl evm::Evm for JitEvm { +impl vm::Vm for JitEvm { fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result { // Dirty hack. This is unsafe, but we interact with ffi, so it's justified. let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext, params.address.clone())) }; @@ -370,8 +371,8 @@ impl evm::Evm for JitEvm { ext.suicide(&Address::from_jit(&context.suicide_refund_address())); Ok(GasLeft::Known(U256::from(context.gas_left()))) }, - evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas), - _err => Err(evm::Error::Internal) + evmjit::ReturnCode::OutOfGas => Err(vm::Error::OutOfGas), + _err => Err(vm::Error::Internal) } } } diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index fa4d12315..833b26664 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -24,11 +24,12 @@ extern crate ethjson; extern crate rlp; extern crate parity_wasm; extern crate wasm_utils; +extern crate ethcore_logger; +extern crate vm; #[macro_use] extern crate lazy_static; -#[macro_use] extern crate log; #[cfg(feature = "jit")] @@ -37,14 +38,8 @@ extern crate evmjit; #[cfg(test)] extern crate rustc_hex; -pub mod action_params; -pub mod call_type; -pub mod env_info; -pub mod ext; pub mod evm; pub mod interpreter; -pub mod schedule; -pub mod wasm; #[macro_use] pub mod factory; @@ -59,12 +54,12 @@ mod tests; #[cfg(all(feature="benches", test))] mod benches; -pub use self::action_params::ActionParams; -pub use self::call_type::CallType; -pub use self::env_info::EnvInfo; -pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData}; -pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +pub use vm::{ + Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext, + ContractCreateResult, MessageCallResult, CreateContractAddress, + GasLeft, ReturnData +}; +pub use self::evm::{Finalize, FinalizationResult, CostType}; pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::vmtype::VMType; pub use self::factory::Factory; -pub use self::schedule::{Schedule, CleanDustMode}; diff --git a/ethcore/evm/src/tests.rs b/ethcore/evm/src/tests.rs index d0502f79a..7263d1779 100644 --- a/ethcore/evm/src/tests.rs +++ b/ethcore/evm/src/tests.rs @@ -15,212 +15,17 @@ // along with Parity. If not, see . use std::fmt::Debug; +use std::str::FromStr; +use std::hash::Hash; +use std::sync::Arc; +use std::collections::{HashMap, HashSet}; use rustc_hex::FromHex; use util::*; -use action_params::{ActionParams, ActionValue}; -use env_info::EnvInfo; -use call_type::CallType; -use schedule::Schedule; -use evm::{self, GasLeft, ReturnData}; -use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +use vm::{self, ActionParams, ActionValue}; +use vm::tests::{FakeExt, FakeCall, FakeCallType, test_finalize}; use factory::Factory; use vmtype::VMType; -pub struct FakeLogEntry { - topics: Vec, - data: Bytes -} - -#[derive(PartialEq, Eq, Hash, Debug)] -pub enum FakeCallType { - Call, Create -} - -#[derive(PartialEq, Eq, Hash, Debug)] -pub struct FakeCall { - pub call_type: FakeCallType, - pub gas: U256, - pub sender_address: Option
, - pub receive_address: Option
, - pub value: Option, - pub data: Bytes, - pub code_address: Option
, -} - -/// Fake externalities test structure. -/// -/// Can't do recursive calls. -#[derive(Default)] -pub struct FakeExt { - pub store: HashMap, - pub suicides: HashSet
, - pub calls: HashSet, - sstore_clears: usize, - depth: usize, - blockhashes: HashMap, - codes: HashMap>, - logs: Vec, - info: EnvInfo, - schedule: Schedule, - balances: HashMap, -} - -// similar to the normal `finalize` function, but ignoring NeedsReturn. -fn test_finalize(res: Result) -> Result { - match res { - Ok(GasLeft::Known(gas)) => Ok(gas), - Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. - Err(e) => Err(e), - } -} - -impl FakeExt { - pub fn new() -> Self { - FakeExt::default() - } -} - -impl Default for Schedule { - fn default() -> Self { - Schedule::new_frontier() - } -} - -impl Ext for FakeExt { - fn storage_at(&self, key: &H256) -> evm::Result { - Ok(self.store.get(key).unwrap_or(&H256::new()).clone()) - } - - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { - self.store.insert(key, value); - Ok(()) - } - - fn exists(&self, address: &Address) -> evm::Result { - Ok(self.balances.contains_key(address)) - } - - fn exists_and_not_null(&self, address: &Address) -> evm::Result { - Ok(self.balances.get(address).map_or(false, |b| !b.is_zero())) - } - - fn origin_balance(&self) -> evm::Result { - unimplemented!() - } - - fn balance(&self, address: &Address) -> evm::Result { - Ok(self.balances[address]) - } - - fn blockhash(&mut self, number: &U256) -> H256 { - self.blockhashes.get(number).unwrap_or(&H256::new()).clone() - } - - fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult { - self.calls.insert(FakeCall { - call_type: FakeCallType::Create, - gas: *gas, - sender_address: None, - receive_address: None, - value: Some(*value), - data: code.to_vec(), - code_address: None - }); - ContractCreateResult::Failed - } - - fn call(&mut self, - gas: &U256, - sender_address: &Address, - receive_address: &Address, - value: Option, - data: &[u8], - code_address: &Address, - _output: &mut [u8], - _call_type: CallType - ) -> MessageCallResult { - - self.calls.insert(FakeCall { - call_type: FakeCallType::Call, - gas: *gas, - sender_address: Some(sender_address.clone()), - receive_address: Some(receive_address.clone()), - value: value, - data: data.to_vec(), - code_address: Some(code_address.clone()) - }); - MessageCallResult::Success(*gas, ReturnData::empty()) - } - - fn extcode(&self, address: &Address) -> evm::Result> { - Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone()) - } - - fn extcodesize(&self, address: &Address) -> evm::Result { - Ok(self.codes.get(address).map_or(0, |c| c.len())) - } - - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()> { - self.logs.push(FakeLogEntry { - topics: topics, - data: data.to_vec() - }); - Ok(()) - } - - fn ret(self, _gas: &U256, _data: &ReturnData) -> evm::Result { - unimplemented!(); - } - - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { - self.suicides.insert(refund_address.clone()); - Ok(()) - } - - fn schedule(&self) -> &Schedule { - &self.schedule - } - - fn env_info(&self) -> &EnvInfo { - &self.info - } - - fn depth(&self) -> usize { - self.depth - } - - fn inc_sstore_clears(&mut self) { - self.sstore_clears += 1; - } -} - -#[test] -fn test_stack_underflow() { - let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let code = "01600055".from_hex().unwrap(); - - let mut params = ActionParams::default(); - params.address = address.clone(); - params.gas = U256::from(100_000); - params.code = Some(Arc::new(code)); - let mut ext = FakeExt::new(); - - let err = { - let mut vm : Box = Box::new(super::interpreter::Interpreter::::new(Arc::new(super::interpreter::SharedCache::default()))); - test_finalize(vm.exec(params, &mut ext)).unwrap_err() - }; - - match err { - evm::Error::StackUnderflow {wanted, on_stack, ..} => { - assert_eq!(wanted, 2); - assert_eq!(on_stack, 0); - } - _ => { - assert!(false, "Expected StackUndeflow") - } - }; -} - evm_test!{test_add: test_add_jit, test_add_int} fn test_add(factory: super::Factory) { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); @@ -849,7 +654,7 @@ fn test_badinstruction_int() { }; match err { - evm::Error::BadInstruction { instruction: 0xaf } => (), + vm::Error::BadInstruction { instruction: 0xaf } => (), _ => assert!(false, "Expected bad instruction") } } diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 09f2e0e1a..b652050d2 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -19,6 +19,7 @@ ethcore-io = { path = "../../util/io" } ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-devtools = { path = "../../devtools" } evm = { path = "../evm" } +vm = { path = "../vm" } rlp = { path = "../../util/rlp" } time = "0.1" smallvec = "0.4" diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index eb70242de..d6ac109c7 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -405,6 +405,7 @@ impl HeaderChain { match id { BlockId::Earliest | BlockId::Number(0) => Some(self.genesis_header.clone()), + BlockId::Hash(hash) if hash == self.genesis_hash() => { Some(self.genesis_header.clone()) } BlockId::Hash(hash) => load_from_db(hash), BlockId::Number(num) => { if self.best_block.read().number < num { return None } @@ -781,4 +782,18 @@ mod tests { assert_eq!(chain.block_header(BlockId::Latest).unwrap().number(), 10); assert!(chain.candidates.read().get(&100).is_some()) } + + #[test] + fn genesis_header_available() { + let spec = Spec::new_test(); + let genesis_header = spec.genesis_header(); + let db = make_db(); + let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6)))); + + let chain = HeaderChain::new(db.clone(), None, &::rlp::encode(&genesis_header), cache.clone()).unwrap(); + + assert!(chain.block_header(BlockId::Earliest).is_some()); + assert!(chain.block_header(BlockId::Number(0)).is_some()); + assert!(chain.block_header(BlockId::Hash(genesis_header.hash())).is_some()); + } } diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index db0d3ad25..3f0e50584 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -58,6 +58,8 @@ pub struct Config { pub db_wal: bool, /// Should it do full verification of blocks? pub verify_full: bool, + /// Should it check the seal of blocks? + pub check_seal: bool, } impl Default for Config { @@ -69,6 +71,7 @@ impl Default for Config { db_compaction: CompactionProfile::default(), db_wal: true, verify_full: true, + check_seal: true, } } } @@ -168,7 +171,7 @@ impl Client { let gh = ::rlp::encode(&spec.genesis_header()); Ok(Client { - queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, true), + queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, config.check_seal), engine: spec.engine.clone(), chain: HeaderChain::new(db.clone(), chain_col, &gh, cache)?, report: RwLock::new(ClientReport::default()), @@ -282,6 +285,7 @@ impl Client { let mut good = Vec::new(); for verified_header in self.queue.drain(MAX) { let (num, hash) = (verified_header.number(), verified_header.hash()); + trace!(target: "client", "importing block {}", num); if self.verify_full && !self.check_header(&mut bad, &verified_header) { continue @@ -381,13 +385,17 @@ impl Client { } } - // return true if should skip, false otherwise. may push onto bad if + // return false if should skip, true otherwise. may push onto bad if // should skip. fn check_header(&self, bad: &mut Vec, verified_header: &Header) -> bool { let hash = verified_header.hash(); let parent_header = match self.chain.block_header(BlockId::Hash(*verified_header.parent_hash())) { Some(header) => header, - None => return false, // skip import of block with missing parent. + None => { + trace!(target: "client", "No parent for block ({}, {})", + verified_header.number(), hash); + return false // skip import of block with missing parent. + } }; // Verify Block Family diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 49928bd98..b172134cf 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -80,6 +80,7 @@ extern crate serde; extern crate smallvec; extern crate stats; extern crate time; +extern crate vm; #[cfg(feature = "ipc")] extern crate ethcore_ipc as ipc; diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 27afed3d5..046dc68bd 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -21,7 +21,7 @@ use ethcore::transaction::UnverifiedTransaction; use io::TimerToken; -use network::{NetworkProtocolHandler, NetworkContext, PeerId}; +use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId}; use rlp::{RlpStream, UntrustedRlp}; use util::hash::H256; use util::{DBValue, Mutex, RwLock, U256}; @@ -806,6 +806,9 @@ impl LightProtocol { trace!(target: "pip", "Connected peer with chain head {:?}", (status.head_hash, status.head_num)); if (status.network_id, status.genesis_hash) != (self.network_id, self.genesis_hash) { + trace!(target: "pip", "peer {} wrong network: network_id is {} vs our {}, gh is {} vs our {}", + peer, status.network_id, self.network_id, status.genesis_hash, self.genesis_hash); + return Err(Error::WrongNetwork); } @@ -1074,7 +1077,7 @@ fn punish(peer: PeerId, io: &IoContext, e: Error) { } impl NetworkProtocolHandler for LightProtocol { - fn initialize(&self, io: &NetworkContext) { + fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) { io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS) .expect("Error registering sync timer."); io.register_timer(TICK_TIMEOUT, TICK_TIMEOUT_INTERVAL_MS) diff --git a/ethcore/light/src/on_demand/mod.rs b/ethcore/light/src/on_demand/mod.rs index c1919ebd1..42469725b 100644 --- a/ethcore/light/src/on_demand/mod.rs +++ b/ethcore/light/src/on_demand/mod.rs @@ -54,13 +54,21 @@ struct Peer { } impl Peer { - // whether this peer can fulfill the - fn can_fulfill(&self, c: &Capabilities) -> bool { - let caps = &self.capabilities; + // whether this peer can fulfill the necessary capabilities for the given + // request. + fn can_fulfill(&self, request: &Capabilities) -> bool { + let local_caps = &self.capabilities; + let can_serve_since = |req, local| { + match (req, local) { + (Some(request_block), Some(serve_since)) => request_block >= serve_since, + (Some(_), None) => false, + (None, _) => true, + } + }; - caps.serve_headers == c.serve_headers && - caps.serve_chain_since >= c.serve_chain_since && - caps.serve_state_since >= c.serve_chain_since + local_caps.serve_headers >= request.serve_headers && + can_serve_since(request.serve_chain_since, local_caps.serve_chain_since) && + can_serve_since(request.serve_state_since, local_caps.serve_state_since) } } @@ -244,7 +252,7 @@ impl OnDemand { peers: RwLock::new(HashMap::new()), in_transit: RwLock::new(HashMap::new()), cache: cache, - no_immediate_dispatch: true, + no_immediate_dispatch: false, } } @@ -266,7 +274,6 @@ impl OnDemand { -> Result>, basic_request::NoSuchOutput> { let (sender, receiver) = oneshot::channel(); - if requests.is_empty() { assert!(sender.send(Vec::new()).is_ok(), "receiver still in scope; qed"); return Ok(receiver); @@ -335,6 +342,7 @@ impl OnDemand { // dispatch pending requests, and discard those for which the corresponding // receiver has been dropped. fn dispatch_pending(&self, ctx: &BasicContext) { + // wrapper future for calling `poll_cancel` on our `Senders` to preserve // the invariant that it's always within a task. struct CheckHangup<'a, T: 'a>(&'a mut Sender); @@ -360,6 +368,8 @@ impl OnDemand { if self.pending.read().is_empty() { return } let mut pending = self.pending.write(); + debug!(target: "on_demand", "Attempting to dispatch {} pending requests", pending.len()); + // iterate over all pending requests, and check them for hang-up. // then, try and find a peer who can serve it. let peers = self.peers.read(); @@ -378,16 +388,21 @@ impl OnDemand { match ctx.request_from(*peer_id, pending.net_requests.clone()) { Ok(req_id) => { + trace!(target: "on_demand", "Dispatched request {} to peer {}", req_id, peer_id); self.in_transit.write().insert(req_id, pending); return None } - Err(net::Error::NoCredits) => {} + Err(net::Error::NoCredits) | Err(net::Error::NotServer) => {} Err(e) => debug!(target: "on_demand", "Error dispatching request to peer: {}", e), } } + + // TODO: maximum number of failures _when we have peers_. Some(pending) }) .collect(); // `pending` now contains all requests we couldn't dispatch. + + debug!(target: "on_demand", "Was unable to dispatch {} requests.", pending.len()); } // submit a pending request set. attempts to answer from cache before @@ -395,6 +410,7 @@ impl OnDemand { fn submit_pending(&self, ctx: &BasicContext, mut pending: Pending) { // answer as many requests from cache as we can, and schedule for dispatch // if incomplete. + pending.answer_from_cache(&*self.cache); if let Some(mut pending) = pending.try_complete() { pending.update_net_requests(); diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 9587dd8ed..6a2201349 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -24,7 +24,7 @@ use ethcore::engines::Engine; use ethcore::receipt::Receipt; use ethcore::state::{self, ProvedExecution}; use ethcore::transaction::SignedTransaction; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; diff --git a/ethcore/native_contracts/Cargo.toml b/ethcore/native_contracts/Cargo.toml index 5dc18c8f5..2f91a4848 100644 --- a/ethcore/native_contracts/Cargo.toml +++ b/ethcore/native_contracts/Cargo.toml @@ -9,7 +9,7 @@ build = "build.rs" ethabi = "2.0" futures = "0.1" byteorder = "1.0" -ethcore-util = { path = "../../util" } +ethcore-bigint = { path = "../../util/bigint" } [build-dependencies] native-contract-generator = { path = "generator" } diff --git a/ethcore/native_contracts/generator/src/lib.rs b/ethcore/native_contracts/generator/src/lib.rs index 793ad6085..996ee4969 100644 --- a/ethcore/native_contracts/generator/src/lib.rs +++ b/ethcore/native_contracts/generator/src/lib.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . //! Rust code contract generator. -//! The code generated will require a dependence on the `ethcore-util`, +//! The code generated will require a dependence on the `ethcore-bigint::prelude`, //! `ethabi`, `byteorder`, and `futures` crates. //! This currently isn't hygienic, so compilation of generated code may fail //! due to missing crates or name collisions. This will change when @@ -48,14 +48,14 @@ pub fn generate_module(struct_name: &str, abi: &str) -> Result { use byteorder::{{BigEndian, ByteOrder}}; use futures::{{future, Future, IntoFuture, BoxFuture}}; use ethabi::{{Contract, Interface, Token, Event}}; -use util; +use bigint; /// Generated Rust bindings to an Ethereum contract. #[derive(Clone, Debug)] pub struct {name} {{ contract: Contract, /// Address to make calls to. - pub address: util::Address, + pub address: bigint::prelude::H160, }} const ABI: &'static str = r#"{abi_str}"#; @@ -63,7 +63,7 @@ const ABI: &'static str = r#"{abi_str}"#; impl {name} {{ /// Create a new instance of `{name}` with an address. /// Calls can be made, given a callback for dispatching calls asynchronously. - pub fn new(address: util::Address) -> Self {{ + pub fn new(address: bigint::prelude::H160) -> Self {{ let contract = Contract::new(Interface::load(ABI.as_bytes()) .expect("ABI checked at generation-time; qed")); {name} {{ @@ -108,7 +108,7 @@ fn generate_functions(contract: &Contract) -> Result { /// Outputs: {abi_outputs:?} pub fn {snake_name}(&self, call: F, {params}) -> BoxFuture<{output_type}, String> where - F: FnOnce(util::Address, Vec) -> U, + F: FnOnce(bigint::prelude::H160, Vec) -> U, U: IntoFuture, Error=String>, U::Future: Send + 'static {{ @@ -217,8 +217,8 @@ fn output_params_codegen(outputs: &[ParamType]) -> Result<(String, String), Para // create code for an argument type from param type. fn rust_type(input: ParamType) -> Result { Ok(match input { - ParamType::Address => "util::Address".into(), - ParamType::FixedBytes(len) if len <= 32 => format!("util::H{}", len * 8), + ParamType::Address => "bigint::prelude::H160".into(), + ParamType::FixedBytes(len) if len <= 32 => format!("bigint::prelude::H{}", len * 8), ParamType::Bytes | ParamType::FixedBytes(_) => "Vec".into(), ParamType::Int(width) => match width { 8 | 16 | 32 | 64 => format!("i{}", width), @@ -226,7 +226,7 @@ fn rust_type(input: ParamType) -> Result { }, ParamType::Uint(width) => match width { 8 | 16 | 32 | 64 => format!("u{}", width), - 128 | 160 | 256 => format!("util::U{}", width), + 128 | 160 | 256 => format!("bigint::prelude::U{}", width), _ => return Err(ParamType::Uint(width)), }, ParamType::Bool => "bool".into(), @@ -259,8 +259,8 @@ fn tokenize(name: &str, input: ParamType) -> (bool, String) { }, ParamType::Uint(width) => format!( "let mut r = [0; 32]; {}.to_big_endian(&mut r); Token::Uint(r)", - if width <= 64 { format!("util::U256::from({} as u64)", name) } - else { format!("util::U256::from({})", name) } + if width <= 64 { format!("bigint::prelude::U256::from({} as u64)", name) } + else { format!("bigint::prelude::U256::from({})", name) } ), ParamType::Bool => format!("Token::Bool({})", name), ParamType::String => format!("Token::String({})", name), @@ -281,11 +281,11 @@ fn tokenize(name: &str, input: ParamType) -> (bool, String) { // panics on unsupported types. fn detokenize(name: &str, output_type: ParamType) -> String { match output_type { - ParamType::Address => format!("{}.to_address().map(util::H160)", name), + ParamType::Address => format!("{}.to_address().map(bigint::prelude::H160)", name), ParamType::Bytes => format!("{}.to_bytes()", name), ParamType::FixedBytes(len) if len <= 32 => { // ensure no panic on slice too small. - let read_hash = format!("b.resize({}, 0); util::H{}::from_slice(&b[..{}])", + let read_hash = format!("b.resize({}, 0); bigint::prelude::H{}::from_slice(&b[..{}])", len, len * 8, len); format!("{}.to_fixed_bytes().map(|mut b| {{ {} }})", @@ -302,8 +302,8 @@ fn detokenize(name: &str, output_type: ParamType) -> String { } ParamType::Uint(width) => { let read_uint = match width { - 8 | 16 | 32 | 64 => format!("util::U256(u).low_u64() as u{}", width), - _ => format!("util::U{}::from(&u[..])", width), + 8 | 16 | 32 | 64 => format!("bigint::prelude::U256(u).low_u64() as u{}", width), + _ => format!("bigint::prelude::U{}::from(&u[..])", width), }; format!("{}.to_uint().map(|u| {})", name, read_uint) @@ -328,30 +328,30 @@ mod tests { #[test] fn input_types() { assert_eq!(::input_params_codegen(&[]).unwrap().0, ""); - assert_eq!(::input_params_codegen(&[ParamType::Address]).unwrap().0, "param_0: util::Address, "); + assert_eq!(::input_params_codegen(&[ParamType::Address]).unwrap().0, "param_0: bigint::prelude::H160, "); assert_eq!(::input_params_codegen(&[ParamType::Address, ParamType::Bytes]).unwrap().0, - "param_0: util::Address, param_1: Vec, "); + "param_0: bigint::prelude::H160, param_1: Vec, "); } #[test] fn output_types() { assert_eq!(::output_params_codegen(&[]).unwrap().0, "()"); - assert_eq!(::output_params_codegen(&[ParamType::Address]).unwrap().0, "(util::Address)"); + assert_eq!(::output_params_codegen(&[ParamType::Address]).unwrap().0, "(bigint::prelude::H160)"); assert_eq!(::output_params_codegen(&[ParamType::Address, ParamType::Array(Box::new(ParamType::Bytes))]).unwrap().0, - "(util::Address, Vec>)"); + "(bigint::prelude::H160, Vec>)"); } #[test] fn rust_type() { - assert_eq!(::rust_type(ParamType::FixedBytes(32)).unwrap(), "util::H256"); + assert_eq!(::rust_type(ParamType::FixedBytes(32)).unwrap(), "bigint::prelude::H256"); assert_eq!(::rust_type(ParamType::Array(Box::new(ParamType::FixedBytes(32)))).unwrap(), - "Vec"); + "Vec"); assert_eq!(::rust_type(ParamType::Uint(64)).unwrap(), "u64"); assert!(::rust_type(ParamType::Uint(63)).is_err()); assert_eq!(::rust_type(ParamType::Int(32)).unwrap(), "i32"); - assert_eq!(::rust_type(ParamType::Uint(256)).unwrap(), "util::U256"); + assert_eq!(::rust_type(ParamType::Uint(256)).unwrap(), "bigint::prelude::U256"); } // codegen tests will need bootstrapping of some kind. diff --git a/ethcore/native_contracts/src/lib.rs b/ethcore/native_contracts/src/lib.rs index 33cb91563..58875f8a2 100644 --- a/ethcore/native_contracts/src/lib.rs +++ b/ethcore/native_contracts/src/lib.rs @@ -21,7 +21,7 @@ extern crate futures; extern crate byteorder; extern crate ethabi; -extern crate ethcore_util as util; +extern crate ethcore_bigint as bigint; mod key_server_set; mod registry; diff --git a/ethcore/res/authority_round.json b/ethcore/res/authority_round.json index d8014ff25..a56618d1c 100644 --- a/ethcore/res/authority_round.json +++ b/ethcore/res/authority_round.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 2, "validators": { @@ -17,6 +16,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/basic_authority.json b/ethcore/res/basic_authority.json index 6b9f4c0ed..192b48cad 100644 --- a/ethcore/res/basic_authority.json +++ b/ethcore/res/basic_authority.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "list": ["0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6"] @@ -12,6 +11,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0100000", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/constructor.json b/ethcore/res/constructor.json index 0be5b3be4..9b1de7020 100644 --- a/ethcore/res/constructor.json +++ b/ethcore/res/constructor.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 6edfef460..bfd64248e 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": 1150000, "eip150Transition": 2500000, - "eip155Transition": 3000000, "eip160Transition": 3000000, "ecip1010PauseTransition": 3000000, "ecip1010ContinueTransition": 5000000, @@ -24,6 +20,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -31,6 +30,8 @@ "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", + "eip155Transition": 3000000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/eip150_test.json b/ethcore/res/ethereum/eip150_test.json index 3091ee27b..22ebf5500 100644 --- a/ethcore/res/ethereum/eip150_test.json +++ b/ethcore/res/ethereum/eip150_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff", @@ -20,12 +16,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffffff", - "eip86Transition": "0x7fffffffffffffff" + "eip86Transition": "0x7fffffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/eip161_test.json b/ethcore/res/ethereum/eip161_test.json index e6e8bf3bb..50d28570b 100644 --- a/ethcore/res/ethereum/eip161_test.json +++ b/ethcore/res/ethereum/eip161_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x0", "eip161abcTransition": "0x0", "eip161dTransition": "0x0", @@ -20,12 +16,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffffff", - "eip86Transition": "0x7fffffffffffffff" + "eip86Transition": "0x7fffffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json index b7d22ac3e..d79ab6b3c 100644 --- a/ethcore/res/ethereum/expanse.json +++ b/ethcore/res/ethereum/expanse.json @@ -4,19 +4,15 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "difficultyIncrementDivisor": "60", "durationLimit": "0x3C", - "blockReward": "0x6f05b59d3b200000", - "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", "homesteadTransition": "0x30d40", "difficultyHardforkTransition": "0x59d9", "difficultyHardforkBoundDivisor": "0x0200", "bombDefuseTransition": "0x30d40", "eip150Transition": "0x927C0", - "eip155Transition": "0x927C0", "eip160Transition": "0x927C0", "eip161abcTransition": "0x927C0", "eip161dTransition": "0x927C0" @@ -24,6 +20,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x6f05b59d3b200000", + "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -31,7 +30,8 @@ "chainID": "0x2", "subprotocolName": "exp", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x927C0" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index a77b39934..b30453082 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -4,12 +4,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142", "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -132,7 +129,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0x259518", - "eip155Transition": 2675000, "eip160Transition": 2675000, "eip161abcTransition": 2675000, "eip161dTransition": 2675000, @@ -141,12 +137,17 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "forkBlock": "0x1d4c00", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", + "eip155Transition": 2675000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index fde04f6b5..0f4b8850f 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -3,12 +3,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x118c30", "daoHardforkTransition": "0x1d4c00", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -131,7 +128,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -139,12 +135,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 6761c79f3..802a77f8d 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index 25b061857..557a48a64 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x0", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 7cdb79e16..ca7638e33 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -4,10 +4,7 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x400", - "registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3", "stepDuration": "4", - "blockReward": "0x4563918244F40000", "validators" : { "list": [ "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", @@ -25,16 +22,19 @@ ] }, "validateScoreTransition": 1000000, - "eip155Transition": 1000000, "validateStepTransition": 1500000 } } }, "params": { - "maximumExtraDataSize": "0x20", + "gasLimitBoundDivisor": "0x400", + "registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3", + "blockReward": "0x4563918244F40000", + "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2A", - "validateReceiptsTransition" : 1000000 + "validateReceiptsTransition" : 1000000, + "eip155Transition": 1000000 }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/metropolis_test.json b/ethcore/res/ethereum/metropolis_test.json index 76189e731..a452e5a80 100644 --- a/ethcore/res/ethereum/metropolis_test.json +++ b/ethcore/res/ethereum/metropolis_test.json @@ -3,15 +3,12 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "homesteadTransition": "0x0", "eip150Transition": "0x0", - "eip155Transition": "0x0", "eip160Transition": "0x0", "eip161abcTransition": "0x0", "eip161dTransition": "0x0", @@ -20,6 +17,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -27,7 +27,8 @@ "eip98Transition": "0x0", "eip86Transition": "0x0", "eip140Transition": "0x0", - "eip210Transition": "0x0" + "eip210Transition": "0x0", + "eip155Transition": "0x0" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 495849daf..f316fdf5f 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "homesteadTransition": 494000, "eip150Transition": 1783000, - "eip155Transition": 1915000, "eip160Transition": 1915000, "ecip1010PauseTransition": 1915000, "ecip1010ContinueTransition": 3415000, @@ -23,6 +19,9 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "accountStartNonce": "0x0100000", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", @@ -30,6 +29,8 @@ "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", + "eip155Transition": 1915000, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 3d2e7baf9..c73dcb815 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -3,15 +3,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x08", - "blockReward": "0x14D1120D7B160000", - "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", "homesteadTransition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -19,12 +15,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x14D1120D7B160000", + "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x0400", "minGasLimit": "125000", "networkID" : "0x0", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 1e350d636..1706c433b 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -4,15 +4,11 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2", "homesteadTransition": 0, "eip150Transition": 0, - "eip155Transition": 10, "eip160Transition": 10, "eip161abcTransition": 10, "eip161dTransition": 10, @@ -21,12 +17,17 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x3", "forkBlock": 641350, "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", + "eip155Transition": 10, + "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests index 4e8b9be3f..ef191fdc6 160000 --- a/ethcore/res/ethereum/tests +++ b/ethcore/res/ethereum/tests @@ -1 +1 @@ -Subproject commit 4e8b9be3fba16ec32e0cdf50b8f9329826283aaa +Subproject commit ef191fdc61cf76cdb9cdc147465fb447304b0ed2 diff --git a/ethcore/res/ethereum/transition_test.json b/ethcore/res/ethereum/transition_test.json index 7709ba015..409210a76 100644 --- a/ethcore/res/ethereum/transition_test.json +++ b/ethcore/res/ethereum/transition_test.json @@ -3,12 +3,9 @@ "engine": { "Ethash": { "params": { - "gasLimitBoundDivisor": "0x0400", "minimumDifficulty": "0x020000", "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", - "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "homesteadTransition": "0x5", "daoHardforkTransition": "0x8", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", @@ -131,7 +128,6 @@ "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" ], "eip150Transition": "0xa", - "eip155Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" @@ -139,12 +135,16 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", "eip98Transition": "0x7fffffffffffff", - "eip86Transition": "0x7fffffffffffff" + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index c791b9a2d..f59feb0bd 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -1,13 +1,10 @@ { "name": "DevelopmentChain", "engine": { - "instantSeal": { - "params": { - "registrar": "0x0000000000000000000000000000000000000005" - } - } + "instantSeal": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/null.json b/ethcore/res/null.json index ffb0ea061..97ce1afc5 100644 --- a/ethcore/res/null.json +++ b/ethcore/res/null.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/null_morden.json b/ethcore/res/null_morden.json index 96d804b5b..b615cdc29 100644 --- a/ethcore/res/null_morden.json +++ b/ethcore/res/null_morden.json @@ -4,6 +4,7 @@ "null": null }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/tendermint.json b/ethcore/res/tendermint.json index 642f5b385..e7fa69ea0 100644 --- a/ethcore/res/tendermint.json +++ b/ethcore/res/tendermint.json @@ -3,7 +3,6 @@ "engine": { "tendermint": { "params": { - "gasLimitBoundDivisor": "0x0400", "validators" : { "list": [ "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1", @@ -18,6 +17,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_contract.json b/ethcore/res/validator_contract.json index 3faec7665..9d007ac23 100644 --- a/ethcore/res/validator_contract.json +++ b/ethcore/res/validator_contract.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 2, "validators": { @@ -14,6 +13,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_multi.json b/ethcore/res/validator_multi.json index 5d51b73da..9eba2d5ba 100644 --- a/ethcore/res/validator_multi.json +++ b/ethcore/res/validator_multi.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "multi": { @@ -15,6 +14,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/validator_safe_contract.json b/ethcore/res/validator_safe_contract.json index 3f5241c96..63dfb948d 100644 --- a/ethcore/res/validator_safe_contract.json +++ b/ethcore/res/validator_safe_contract.json @@ -3,7 +3,6 @@ "engine": { "basicAuthority": { "params": { - "gasLimitBoundDivisor": "0x0400", "durationLimit": "0x0d", "validators": { "safeContract": "0x0000000000000000000000000000000000000005" @@ -12,6 +11,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/res/wasm-tests b/ethcore/res/wasm-tests index 9ed630431..18dad7912 160000 --- a/ethcore/res/wasm-tests +++ b/ethcore/res/wasm-tests @@ -1 +1 @@ -Subproject commit 9ed6304313fa949ed92aa0570fb2bc759fb6dc58 +Subproject commit 18dad7912cf42937ff725ffd944d01ff7ca1cce7 diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index 10e63dba3..5ce555aef 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! DB backend wrapper for Account trie +use std::collections::HashMap; use util::*; use rlp::NULL_RLP; diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 8cd1e22b6..64958700e 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL use util::error::{Mismatch, OutOfBounds}; use basic_types::{LogBloom, Seal}; -use evm::env_info::{EnvInfo, LastHashes}; +use vm::{EnvInfo, LastHashes}; use engines::Engine; use error::{Error, BlockError, TransactionError}; use factory::Factories; @@ -667,7 +667,7 @@ mod tests { use tests::helpers::*; use super::*; use engines::Engine; - use evm::env_info::LastHashes; + use vm::LastHashes; use error::Error; use header::Header; use factory::Factories; diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 4412df567..bd0defa47 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -16,6 +16,9 @@ //! Blockchain database. +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; +use std::mem; use bloomchain as bc; use util::*; use rlp::*; diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index 04c12d53a..ed3a5009b 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -16,6 +16,8 @@ //! Blockchain DB extras. +use std::ops; +use std::io::Write; use bloomchain; use blooms::{GroupPosition, BloomGroup}; use db::Key; @@ -56,7 +58,7 @@ fn with_index(hash: &H256, i: ExtrasIndex) -> H264 { pub struct BlockNumberKey([u8; 5]); -impl Deref for BlockNumberKey { +impl ops::Deref for BlockNumberKey { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -88,7 +90,7 @@ impl Key for H256 { pub struct LogGroupKey([u8; 6]); -impl Deref for LogGroupKey { +impl ops::Deref for LogGroupKey { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -160,7 +162,8 @@ pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[ ]; pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]); -impl Deref for EpochTransitionsKey { + +impl ops::Deref for EpochTransitionsKey { type Target = [u8]; fn deref(&self) -> &[u8] { &self.0[..] } diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index d5dc459b2..9e49e610c 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -36,9 +36,9 @@ impl From<&'static str> for Error { } } -impl Into<::evm::Error> for Error { - fn into(self) -> ::evm::Error { - ::evm::Error::BuiltIn(self.0) +impl Into<::vm::Error> for Error { + fn into(self) -> ::vm::Error { + ::vm::Error::BuiltIn(self.0) } } @@ -352,7 +352,7 @@ fn read_point(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<::bn::G1, Err let px = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point x coordinate"))?; reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed"); - let py = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point x coordinate"))?; + let py = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point y coordinate"))?; Ok( if px == Fq::zero() && py == Fq::zero() { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 48cf481f1..7141c7bdb 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -42,9 +42,8 @@ use client::{ }; use encoded; use engines::{Engine, EpochTransition}; -use evm::env_info::EnvInfo; -use evm::env_info::LastHashes; use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; +use vm::{EnvInfo, LastHashes}; use evm::{Factory as EvmFactory, Schedule}; use executive::{Executive, Executed, TransactOptions, contract_address}; use factory::Factories; @@ -907,7 +906,7 @@ impl Client { pub fn state_at(&self, id: BlockId) -> Option> { // fast path for latest state. match id.clone() { - BlockId::Pending => return self.miner.pending_state().or_else(|| Some(self.state())), + BlockId::Pending => return self.miner.pending_state(self.chain.read().best_block_number()).or_else(|| Some(self.state())), BlockId::Latest => return Some(self.state()), _ => {}, } @@ -1056,19 +1055,20 @@ impl Client { self.history } - fn block_hash(chain: &BlockChain, id: BlockId) -> Option { + fn block_hash(chain: &BlockChain, miner: &Miner, id: BlockId) -> Option { match id { BlockId::Hash(hash) => Some(hash), BlockId::Number(number) => chain.block_hash(number), BlockId::Earliest => chain.block_hash(0), - BlockId::Latest | BlockId::Pending => Some(chain.best_block_hash()), + BlockId::Latest => Some(chain.best_block_hash()), + BlockId::Pending => miner.pending_block_header(chain.best_block_number()).map(|header| header.hash()) } } fn transaction_address(&self, id: TransactionId) -> Option { match id { TransactionId::Hash(ref hash) => self.chain.read().transaction_address(hash), - TransactionId::Location(id, index) => Self::block_hash(&self.chain.read(), id).map(|hash| TransactionAddress { + TransactionId::Location(id, index) => Self::block_hash(&self.chain.read(), &self.miner, id).map(|hash| TransactionAddress { block_hash: hash, index: index, }) @@ -1111,6 +1111,31 @@ impl Client { data: data, }.fake_sign(from) } + + fn do_call(&self, env_info: &EnvInfo, state: &mut State, increase_balance: bool, t: &SignedTransaction, analytics: CallAnalytics) -> Result { + let original_state = if analytics.state_diffing { Some(state.clone()) } else { None }; + + // give the sender a sufficient balance (if calling in pending block) + if increase_balance { + let sender = t.sender(); + let balance = state.balance(&sender).map_err(ExecutionError::from)?; + let needed_balance = t.value + t.gas * t.gas_price; + if balance < needed_balance { + state.add_balance(&sender, &(needed_balance - balance), state::CleanupMode::NoEmpty) + .map_err(ExecutionError::from)?; + } + } + + let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false }; + let mut ret = Executive::new(state, env_info, &*self.engine).transact_virtual(t, options)?; + + // TODO gav move this into Executive. + if let Some(original) = original_state { + ret.state_diff = Some(state.diff_from(original).map_err(ExecutionError::from)?); + } + + Ok(ret) + } } impl snapshot::DatabaseRestore for Client { @@ -1135,23 +1160,31 @@ impl snapshot::DatabaseRestore for Client { } impl BlockChainClient for Client { - fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result { + fn call(&self, transaction: &SignedTransaction, analytics: CallAnalytics, block: BlockId) -> Result { let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?; env_info.gas_limit = U256::max_value(); // that's just a copy of the state. let mut state = self.state_at(block).ok_or(CallError::StatePruned)?; - let original_state = if analytics.state_diffing { Some(state.clone()) } else { None }; - let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false }; - let mut ret = Executive::new(&mut state, &env_info, &*self.engine).transact_virtual(t, options)?; + self.do_call(&env_info, &mut state, block == BlockId::Pending, transaction, analytics) + } - // TODO gav move this into Executive. - if let Some(original) = original_state { - ret.state_diff = Some(state.diff_from(original).map_err(ExecutionError::from)?); + fn call_many(&self, transactions: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result, CallError> { + let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?; + env_info.gas_limit = U256::max_value(); + + // that's just a copy of the state. + let mut state = self.state_at(block).ok_or(CallError::StatePruned)?; + let mut results = Vec::with_capacity(transactions.len()); + + for &(ref t, analytics) in transactions { + let ret = self.do_call(&env_info, &mut state, block == BlockId::Pending, t, analytics)?; + env_info.gas_used = ret.cumulative_gas_used; + results.push(ret); } - Ok(ret) + Ok(results) } fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result { @@ -1304,7 +1337,16 @@ impl BlockChainClient for Client { fn block_header(&self, id: BlockId) -> Option<::encoded::Header> { let chain = self.chain.read(); - Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash)) + + if let BlockId::Pending = id { + if let Some(block) = self.miner.pending_block(chain.best_block_number()) { + return Some(encoded::Header::new(block.header.rlp(Seal::Without))); + } + // fall back to latest + return self.block_header(BlockId::Latest); + } + + Self::block_hash(&chain, &self.miner, id).and_then(|hash| chain.block_header_data(&hash)) } fn block_number(&self, id: BlockId) -> Option { @@ -1312,30 +1354,48 @@ impl BlockChainClient for Client { BlockId::Number(number) => Some(number), BlockId::Hash(ref hash) => self.chain.read().block_number(hash), BlockId::Earliest => Some(0), - BlockId::Latest | BlockId::Pending => Some(self.chain.read().best_block_number()), + BlockId::Latest => Some(self.chain.read().best_block_number()), + BlockId::Pending => Some(self.chain.read().best_block_number() + 1), } } fn block_body(&self, id: BlockId) -> Option { let chain = self.chain.read(); - Self::block_hash(&chain, id).and_then(|hash| chain.block_body(&hash)) + + if let BlockId::Pending = id { + if let Some(block) = self.miner.pending_block(chain.best_block_number()) { + return Some(encoded::Body::new(BlockChain::block_to_body(&block.rlp_bytes(Seal::Without)))); + } + // fall back to latest + return self.block_body(BlockId::Latest); + } + + Self::block_hash(&chain, &self.miner, id).and_then(|hash| chain.block_body(&hash)) } fn block(&self, id: BlockId) -> Option { + let chain = self.chain.read(); + if let BlockId::Pending = id { - if let Some(block) = self.miner.pending_block() { + if let Some(block) = self.miner.pending_block(chain.best_block_number()) { return Some(encoded::Block::new(block.rlp_bytes(Seal::Without))); } + // fall back to latest + return self.block(BlockId::Latest); } - let chain = self.chain.read(); - Self::block_hash(&chain, id).and_then(|hash| { + + Self::block_hash(&chain, &self.miner, id).and_then(|hash| { chain.block(&hash) }) } fn block_status(&self, id: BlockId) -> BlockStatus { + if let BlockId::Pending = id { + return BlockStatus::Pending; + } + let chain = self.chain.read(); - match Self::block_hash(&chain, id) { + match Self::block_hash(&chain, &self.miner, id) { Some(ref hash) if chain.is_known(hash) => BlockStatus::InChain, Some(hash) => self.block_queue.status(&hash).into(), None => BlockStatus::Unknown @@ -1343,13 +1403,18 @@ impl BlockChainClient for Client { } fn block_total_difficulty(&self, id: BlockId) -> Option { - if let BlockId::Pending = id { - if let Some(block) = self.miner.pending_block() { - return Some(*block.header.difficulty() + self.block_total_difficulty(BlockId::Latest).expect("blocks in chain have details; qed")); - } - } let chain = self.chain.read(); - Self::block_hash(&chain, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_difficulty) + if let BlockId::Pending = id { + let latest_difficulty = self.block_total_difficulty(BlockId::Latest).expect("blocks in chain have details; qed"); + let pending_difficulty = self.miner.pending_block_header(chain.best_block_number()).map(|header| *header.difficulty()); + if let Some(difficulty) = pending_difficulty { + return Some(difficulty + latest_difficulty); + } + // fall back to latest + return Some(latest_difficulty); + } + + Self::block_hash(&chain, &self.miner, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_difficulty) } fn nonce(&self, address: &Address, id: BlockId) -> Option { @@ -1362,7 +1427,7 @@ impl BlockChainClient for Client { fn block_hash(&self, id: BlockId) -> Option { let chain = self.chain.read(); - Self::block_hash(&chain, id) + Self::block_hash(&chain, &self.miner, id) } fn code(&self, address: &Address, id: BlockId) -> Option> { @@ -1527,7 +1592,8 @@ impl BlockChainClient for Client { if self.chain.read().is_known(&unverified.hash()) { return Err(BlockImportError::Import(ImportError::AlreadyInChain)); } - if self.block_status(BlockId::Hash(unverified.parent_hash())) == BlockStatus::Unknown { + let status = self.block_status(BlockId::Hash(unverified.parent_hash())); + if status == BlockStatus::Unknown || status == BlockStatus::Pending { return Err(BlockImportError::Block(BlockError::UnknownParent(unverified.parent_hash()))); } } @@ -1541,7 +1607,8 @@ impl BlockChainClient for Client { if self.chain.read().is_known(&header.hash()) { return Err(BlockImportError::Import(ImportError::AlreadyInChain)); } - if self.block_status(BlockId::Hash(header.parent_hash())) == BlockStatus::Unknown { + let status = self.block_status(BlockId::Hash(header.parent_hash())); + if status == BlockStatus::Unknown || status == BlockStatus::Pending { return Err(BlockImportError::Block(BlockError::UnknownParent(header.parent_hash()))); } } @@ -1687,7 +1754,7 @@ impl BlockChainClient for Client { fn call_contract(&self, block_id: BlockId, address: Address, data: Bytes) -> Result { let transaction = self.contract_call_tx(block_id, address, data); - self.call(&transaction, block_id, Default::default()) + self.call(&transaction, Default::default(), block_id) .map_err(|e| format!("{:?}", e)) .map(|executed| { executed.output diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index 5f23f449d..cd8501c31 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB}; use {state, state_db, client, executive, trace, db, spec}; use factory::Factories; use evm::{self, VMType}; -use evm::action_params::ActionParams; +use vm::{self, ActionParams}; /// EVM test Error. #[derive(Debug)] @@ -31,7 +31,7 @@ pub enum EvmTestError { /// Trie integrity error. Trie(util::TrieError), /// EVM error. - Evm(evm::Error), + Evm(vm::Error), /// Initialization error. Initialization(::error::Error), /// Low-level database error. diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index b2d1ce991..f7c7417ad 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -40,7 +40,7 @@ pub use types::pruning_info::PruningInfo; pub use types::call_analytics::CallAnalytics; pub use executive::{Executed, Executive, TransactOptions}; -pub use evm::env_info::{LastHashes, EnvInfo}; +pub use vm::{LastHashes, EnvInfo}; pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; pub use verification::VerifierType; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5dfdf5c25..2a205868d 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -17,6 +17,9 @@ //! Test client. use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; +use std::sync::Arc; +use std::collections::{HashMap, BTreeMap}; +use std::mem; use rustc_hex::FromHex; use util::*; use rlp::*; @@ -36,7 +39,8 @@ use log_entry::LocalizedLogEntry; use receipt::{Receipt, LocalizedReceipt}; use blockchain::extras::BlockReceipts; use error::{ImportResult, Error as EthcoreError}; -use evm::{Factory as EvmFactory, VMType, Schedule}; +use evm::{Factory as EvmFactory, VMType}; +use vm::Schedule; use miner::{Miner, MinerService, TransactionImportResult}; use spec::Spec; use types::basic_account::BasicAccount; @@ -397,10 +401,18 @@ impl MiningBlockChainClient for TestBlockChainClient { } impl BlockChainClient for TestBlockChainClient { - fn call(&self, _t: &SignedTransaction, _block: BlockId, _analytics: CallAnalytics) -> Result { + fn call(&self, _t: &SignedTransaction, _analytics: CallAnalytics, _block: BlockId) -> Result { self.execution_result.read().clone().unwrap() } + fn call_many(&self, txs: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result, CallError> { + let mut res = Vec::with_capacity(txs.len()); + for &(ref tx, analytics) in txs { + res.push(self.call(tx, analytics, block)?); + } + Ok(res) + } + fn estimate_gas(&self, _t: &SignedTransaction, _block: BlockId) -> Result { Ok(21000.into()) } @@ -419,7 +431,7 @@ impl BlockChainClient for TestBlockChainClient { fn nonce(&self, address: &Address, id: BlockId) -> Option { match id { - BlockId::Latest => Some(self.nonces.read().get(address).cloned().unwrap_or(self.spec.params().account_start_nonce)), + BlockId::Latest | BlockId::Pending => Some(self.nonces.read().get(address).cloned().unwrap_or(self.spec.params().account_start_nonce)), _ => None, } } @@ -434,16 +446,15 @@ impl BlockChainClient for TestBlockChainClient { fn code(&self, address: &Address, id: BlockId) -> Option> { match id { - BlockId::Latest => Some(self.code.read().get(address).cloned()), + BlockId::Latest | BlockId::Pending => Some(self.code.read().get(address).cloned()), _ => None, } } fn balance(&self, address: &Address, id: BlockId) -> Option { - if let BlockId::Latest = id { - Some(self.balances.read().get(address).cloned().unwrap_or_else(U256::zero)) - } else { - None + match id { + BlockId::Latest | BlockId::Pending => Some(self.balances.read().get(address).cloned().unwrap_or_else(U256::zero)), + _ => None, } } @@ -452,10 +463,9 @@ impl BlockChainClient for TestBlockChainClient { } fn storage_at(&self, address: &Address, position: &H256, id: BlockId) -> Option { - if let BlockId::Latest = id { - Some(self.storage.read().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)) - } else { - None + match id { + BlockId::Latest | BlockId::Pending => Some(self.storage.read().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)), + _ => None, } } @@ -544,7 +554,8 @@ impl BlockChainClient for TestBlockChainClient { match id { BlockId::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain, BlockId::Hash(ref hash) if self.blocks.read().get(hash).is_some() => BlockStatus::InChain, - BlockId::Latest | BlockId::Pending | BlockId::Earliest => BlockStatus::InChain, + BlockId::Latest | BlockId::Earliest => BlockStatus::InChain, + BlockId::Pending => BlockStatus::Pending, _ => BlockStatus::Unknown, } } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index aca369b21..8e1bd8b18 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use block::{OpenBlock, SealedBlock, ClosedBlock}; use blockchain::TreeRoute; use encoded; -use evm::env_info::LastHashes; +use vm::LastHashes; use error::{ImportResult, CallError, Error as EthcoreError}; use error::{TransactionImportResult, BlockImportError}; use evm::{Factory as EvmFactory, Schedule}; @@ -182,7 +182,11 @@ pub trait BlockChainClient : Sync + Send { fn logs(&self, filter: Filter) -> Vec; /// Makes a non-persistent transaction call. - fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result; + fn call(&self, tx: &SignedTransaction, analytics: CallAnalytics, block: BlockId) -> Result; + + /// Makes multiple non-persistent but dependent transaction calls. + /// Returns a vector of successes or a failure if any of the transaction fails. + fn call_many(&self, txs: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result, CallError>; /// Estimates how much gas will be necessary for a call. fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result; diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 018489f26..e7284bfbe 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -17,8 +17,10 @@ //! A blockchain engine that supports a non-instant BFT proof-of-authority. use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, Duration}; +use std::collections::{BTreeMap, HashSet, HashMap}; +use std::cmp; use account_provider::AccountProvider; use block::*; @@ -47,22 +49,14 @@ mod finality; /// `AuthorityRound` params. pub struct AuthorityRoundParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Time to wait before next block or authority switching. pub step_duration: Duration, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, /// Starting step, pub start_step: Option, /// Valid validators. pub validators: Box, /// Chain score validation transition block. pub validate_score_transition: u64, - /// Number of first block where EIP-155 rules are validated. - pub eip155_transition: u64, /// Monotonic step validation transition block. pub validate_step_transition: u64, /// Immediate transitions. @@ -72,14 +66,10 @@ pub struct AuthorityRoundParams { impl From for AuthorityRoundParams { fn from(p: ethjson::spec::AuthorityRoundParams) -> Self { AuthorityRoundParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), step_duration: Duration::from_secs(p.step_duration.into()), validators: new_validator_set(p.validators), - block_reward: p.block_reward.map_or_else(U256::zero, Into::into), - registrar: p.registrar.map_or_else(Address::new, Into::into), start_step: p.start_step.map(Into::into), validate_score_transition: p.validate_score_transition.map_or(0, Into::into), - eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_step_transition: p.validate_step_transition.map_or(0, Into::into), immediate_transitions: p.immediate_transitions.unwrap_or(false), } @@ -214,9 +204,6 @@ impl EpochManager { /// Engine using `AuthorityRound` proof-of-authority BFT consensus. pub struct AuthorityRound { params: CommonParams, - gas_limit_bound_divisor: U256, - block_reward: U256, - registrar: Address, builtins: BTreeMap, transition_service: IoService<()>, step: Arc, @@ -225,7 +212,6 @@ pub struct AuthorityRound { signer: RwLock, validators: Box, validate_score_transition: u64, - eip155_transition: u64, validate_step_transition: u64, epoch_manager: Mutex, immediate_transitions: bool, @@ -362,9 +348,6 @@ impl AuthorityRound { let engine = Arc::new( AuthorityRound { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, - block_reward: our_params.block_reward, - registrar: our_params.registrar, builtins: builtins, transition_service: IoService::<()>::start()?, step: Arc::new(Step { @@ -377,7 +360,6 @@ impl AuthorityRound { signer: Default::default(), validators: our_params.validators, validate_score_transition: our_params.validate_score_transition, - eip155_transition: our_params.eip155_transition, validate_step_transition: our_params.validate_step_transition, epoch_manager: Mutex::new(EpochManager::blank()), immediate_transitions: our_params.immediate_transitions, @@ -433,7 +415,9 @@ impl Engine for AuthorityRound { fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.registrar.hex()] } + fn additional_params(&self) -> HashMap { + hash_map!["registrar".to_owned() => self.params().registrar.hex()] + } fn builtins(&self) -> &BTreeMap { &self.builtins } @@ -461,11 +445,11 @@ impl Engine for AuthorityRound { header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -476,8 +460,8 @@ impl Engine for AuthorityRound { /// Attempt to seal the block internally. /// - /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will - /// be returned. + /// This operation is synchronous and may (quite reasonably) not be available, in which case + /// `Seal::None` will be returned. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { // first check to avoid generating signature most of the time // (but there's still a race to the `compare_and_swap`) @@ -532,7 +516,7 @@ impl Engine for AuthorityRound { fn on_new_block( &self, block: &mut ExecutedBlock, - last_hashes: Arc<::evm::env_info::LastHashes>, + last_hashes: Arc<::vm::LastHashes>, epoch_begin: bool, ) -> Result<(), Error> { let parent_hash = block.fields().header.parent_hash().clone(); @@ -564,7 +548,8 @@ impl Engine for AuthorityRound { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { let fields = block.fields_mut(); // Bestow block reward - let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) + let reward = self.params().block_reward; + let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty) .map_err(::error::Error::from) .and_then(|_| fields.state.commit()); // Commit state so that we can actually figure out the state root. @@ -629,7 +614,7 @@ impl Engine for AuthorityRound { } } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { @@ -705,6 +690,7 @@ impl Engine for AuthorityRound { // apply immediate transitions. if let Some(change) = self.validators.is_epoch_end(first, chain_head) { + let change = combine_proofs(chain_head.number(), &change, &[]); return Some(change) } @@ -815,11 +801,11 @@ impl Engine for AuthorityRound { } } - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> { t.check_low_s()?; if let Some(n) = t.network_id() { - if header.number() >= self.eip155_transition && n != self.params().chain_id { + if header.number() >= self.params().eip155_transition && n != self.params().chain_id { return Err(TransactionError::InvalidNetworkId.into()); } } @@ -851,6 +837,7 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { + use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use util::*; use header::Header; @@ -941,10 +928,10 @@ mod tests { let addr = tap.insert_account("0".sha3().into(), "0").unwrap(); let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&0usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -967,10 +954,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&0usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -993,10 +980,10 @@ mod tests { let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&4usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_author(addr); let engine = Spec::new_test_round().engine; @@ -1014,25 +1001,26 @@ mod tests { fn reports_skipped() { let last_benign = Arc::new(AtomicUsize::new(0)); let params = AuthorityRoundParams { - gas_limit_bound_divisor: U256::from_str("400").unwrap(), step_duration: Default::default(), - block_reward: Default::default(), - registrar: Default::default(), start_step: Some(1), validators: Box::new(TestSet::new(Default::default(), last_benign.clone())), validate_score_transition: 0, validate_step_transition: 0, - eip155_transition: 0, immediate_transitions: true, }; - let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap(); + + let aura = { + let mut c_params = ::spec::CommonParams::default(); + c_params.gas_limit_bound_divisor = 5.into(); + AuthorityRound::new(c_params, params, Default::default()).unwrap() + }; let mut parent_header: Header = Header::default(); parent_header.set_seal(vec![encode(&1usize).into_vec()]); - parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + parent_header.set_gas_limit("222222".parse::().unwrap()); let mut header: Header = Header::default(); header.set_number(1); - header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_gas_limit("222222".parse::().unwrap()); header.set_seal(vec![encode(&3usize).into_vec()]); // Do not report when signer not present. diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 68759131d..5d6a44fc5 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -16,7 +16,9 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. -use std::sync::Weak; +use std::sync::{Weak, Arc}; +use std::collections::BTreeMap; +use std::cmp; use util::*; use ethkey::{recover, public_to_address, Signature}; use account_provider::AccountProvider; @@ -35,8 +37,6 @@ use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `BasicAuthority` params. #[derive(Debug, PartialEq)] pub struct BasicAuthorityParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Valid signatories. pub validators: ethjson::spec::ValidatorSet, } @@ -44,7 +44,6 @@ pub struct BasicAuthorityParams { impl From for BasicAuthorityParams { fn from(p: ethjson::spec::BasicAuthorityParams) -> Self { BasicAuthorityParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), validators: p.validators, } } @@ -80,7 +79,6 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err /// Engine using `BasicAuthority`, trivial proof-of-authority consensus. pub struct BasicAuthority { params: CommonParams, - gas_limit_bound_divisor: U256, builtins: BTreeMap, signer: RwLock, validators: Box, @@ -91,7 +89,6 @@ impl BasicAuthority { pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap) -> Self { BasicAuthority { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, validators: new_validator_set(our_params.validators), signer: Default::default(), @@ -119,11 +116,11 @@ impl Engine for BasicAuthority { header.set_difficulty(parent.difficulty().clone()); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -147,7 +144,7 @@ impl Engine for BasicAuthority { Seal::None } - fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // check the seal fields. // TODO: pull this out into common code. if header.seal().len() != self.seal_fields() { @@ -158,11 +155,11 @@ impl Engine for BasicAuthority { Ok(()) } - fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) } - fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // Do not calculate difficulty for genesis blocks. if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); @@ -172,7 +169,7 @@ impl Engine for BasicAuthority { if header.difficulty() != parent.difficulty() { return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() }))) } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { @@ -254,6 +251,7 @@ impl Engine for BasicAuthority { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use block::*; use error::{BlockError, Error}; diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 38834622c..976f815e0 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -14,26 +14,24 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::collections::BTreeMap; -use util::{Address, HashMap}; +use std::collections::{BTreeMap, HashMap}; +use util::Address; use builtin::Builtin; use engines::{Engine, Seal}; use spec::CommonParams; -use block::ExecutedBlock; +use block::{ExecutedBlock, IsBlock}; /// An engine which does not provide any consensus mechanism, just seals blocks internally. pub struct InstantSeal { params: CommonParams, - registrar: Address, builtins: BTreeMap, } impl InstantSeal { /// Returns new instance of InstantSeal with default VM Factory - pub fn new(params: CommonParams, registrar: Address, builtins: BTreeMap) -> Self { + pub fn new(params: CommonParams, builtins: BTreeMap) -> Self { InstantSeal { params: params, - registrar: registrar, builtins: builtins, } } @@ -49,7 +47,7 @@ impl Engine for InstantSeal { } fn additional_params(&self) -> HashMap { - hash_map!["registrar".to_owned() => self.registrar.hex()] + hash_map!["registrar".to_owned() => self.params().registrar.hex()] } fn builtins(&self) -> &BTreeMap { @@ -58,13 +56,14 @@ impl Engine for InstantSeal { fn seals_internally(&self) -> Option { Some(true) } - fn generate_seal(&self, _block: &ExecutedBlock) -> Seal { - Seal::Regular(Vec::new()) + fn generate_seal(&self, block: &ExecutedBlock) -> Seal { + if block.transactions().is_empty() { Seal::None } else { Seal::Regular(Vec::new()) } } } #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use tests::helpers::*; use spec::Spec; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index c5fa4818e..a293963d7 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -35,7 +35,9 @@ pub use self::instant_seal::InstantSeal; pub use self::null_engine::NullEngine; pub use self::tendermint::Tendermint; -use std::sync::Weak; +use std::sync::{Weak, Arc}; +use std::collections::{BTreeMap, HashMap}; +use std::fmt; use self::epoch::PendingTransition; @@ -43,15 +45,13 @@ use account_provider::AccountProvider; use block::ExecutedBlock; use builtin::Builtin; use client::Client; -use evm::env_info::{EnvInfo, LastHashes}; +use vm::{EnvInfo, LastHashes, Schedule, CreateContractAddress}; use error::Error; -use evm::Schedule; use header::{Header, BlockNumber}; use receipt::Receipt; use snapshot::SnapshotComponents; use spec::CommonParams; use transaction::{UnverifiedTransaction, SignedTransaction}; -use evm::CreateContractAddress; use ethkey::Signature; use util::*; @@ -393,13 +393,12 @@ pub trait Engine : Sync + Send { /// Common engine utilities pub mod common { + use std::sync::Arc; use block::ExecutedBlock; - use evm::env_info::{EnvInfo, LastHashes}; use error::Error; use transaction::SYSTEM_ADDRESS; use executive::Executive; - use evm::CallType; - use evm::action_params::{ActionParams, ActionValue}; + use vm::{CallType, ActionParams, ActionValue, EnvInfo, LastHashes}; use trace::{NoopTracer, NoopVMTracer}; use state::Substate; diff --git a/ethcore/src/engines/signer.rs b/ethcore/src/engines/signer.rs index 4ec4318c9..4069488ab 100644 --- a/ethcore/src/engines/signer.rs +++ b/ethcore/src/engines/signer.rs @@ -16,7 +16,8 @@ //! A signer used by Engines which need to sign messages. -use util::{Arc, H256, Address}; +use std::sync::Arc; +use util::{H256, Address}; use ethkey::Signature; use account_provider::{self, AccountProvider}; diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index b9465f429..68bdcb0f7 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -16,6 +16,7 @@ //! Tendermint message handling. +use std::cmp; use util::*; use super::{Height, View, BlockHash, Step}; use error::Error; @@ -110,13 +111,13 @@ impl Default for VoteStep { } impl PartialOrd for VoteStep { - fn partial_cmp(&self, m: &VoteStep) -> Option { + fn partial_cmp(&self, m: &VoteStep) -> Option { Some(self.cmp(m)) } } impl Ord for VoteStep { - fn cmp(&self, m: &VoteStep) -> Ordering { + fn cmp(&self, m: &VoteStep) -> cmp::Ordering { if self.height != m.height { self.height.cmp(&m.height) } else if self.view != m.view { @@ -198,6 +199,7 @@ pub fn message_hash(vote_step: VoteStep, block_hash: H256) -> H256 { #[cfg(test)] mod tests { + use std::sync::Arc; use util::*; use rlp::*; use account_provider::AccountProvider; diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index f40c7539e..cc75e99c3 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -25,23 +25,25 @@ mod message; mod params; -use std::sync::Weak; +use std::sync::{Weak, Arc}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; +use std::collections::{HashSet, BTreeMap, HashMap}; +use std::cmp; use util::*; use client::{Client, EngineClient}; use error::{Error, BlockError}; use header::{Header, BlockNumber}; use builtin::Builtin; use rlp::UntrustedRlp; -use ethkey::{recover, public_to_address, Signature}; +use ethkey::{Message, public_to_address, recover, Signature}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; -use engines::{Engine, Seal, EngineError}; +use engines::{Engine, Seal, EngineError, ConstructedVerifier}; use state::CleanupMode; use io::IoService; use super::signer::EngineSigner; -use super::validator_set::ValidatorSet; +use super::validator_set::{ValidatorSet, SimpleList}; use super::transition::TransitionHandler; use super::vote_collector::VoteCollector; use self::message::*; @@ -71,12 +73,9 @@ pub type BlockHash = H256; /// Engine using `Tendermint` consensus algorithm, suitable for EVM chain. pub struct Tendermint { params: CommonParams, - gas_limit_bound_divisor: U256, builtins: BTreeMap, step_service: IoService, client: RwLock>>, - block_reward: U256, - registrar: Address, /// Blockchain height. height: AtomicUsize, /// Consensus view. @@ -101,18 +100,74 @@ pub struct Tendermint { validators: Box, } +struct EpochVerifier + where F: Fn(&Signature, &Message) -> Result + Send + Sync +{ + subchain_validators: SimpleList, + recover: F +} + +impl super::EpochVerifier for EpochVerifier + where F: Fn(&Signature, &Message) -> Result + Send + Sync +{ + fn verify_light(&self, header: &Header) -> Result<(), Error> { + let message = header.bare_hash(); + + let mut addresses = HashSet::new(); + let ref header_signatures_field = header.seal().get(2).ok_or(BlockError::InvalidSeal)?; + for rlp in UntrustedRlp::new(header_signatures_field).iter() { + let signature: H520 = rlp.as_val()?; + let address = (self.recover)(&signature.into(), &message)?; + + if !self.subchain_validators.contains(header.parent_hash(), &address) { + return Err(EngineError::NotAuthorized(address.to_owned()).into()); + } + addresses.insert(address); + } + + let n = addresses.len(); + let threshold = self.subchain_validators.len() * 2/3; + if n > threshold { + Ok(()) + } else { + Err(EngineError::BadSealFieldSize(OutOfBounds { + min: Some(threshold), + max: None, + found: n + }).into()) + } + } + + fn check_finality_proof(&self, proof: &[u8]) -> Option> { + let header: Header = ::rlp::decode(proof); + self.verify_light(&header).ok().map(|_| vec![header.hash()]) + } +} + +fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof: &[u8]) -> Vec { + let mut stream = ::rlp::RlpStream::new_list(3); + stream.append(&signal_number).append(&set_proof).append(&finality_proof); + stream.out() +} + +fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> { + let rlp = UntrustedRlp::new(combined); + Ok(( + rlp.at(0)?.as_val()?, + rlp.at(1)?.data()?, + rlp.at(2)?.data()?, + )) +} + impl Tendermint { /// Create a new instance of Tendermint engine pub fn new(params: CommonParams, our_params: TendermintParams, builtins: BTreeMap) -> Result, Error> { let engine = Arc::new( Tendermint { params: params, - gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, client: RwLock::new(None), step_service: IoService::::start()?, - block_reward: our_params.block_reward, - registrar: our_params.registrar, height: AtomicUsize::new(1), view: AtomicUsize::new(0), step: RwLock::new(Step::Propose), @@ -387,7 +442,9 @@ impl Engine for Tendermint { fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.registrar.hex()] } + fn additional_params(&self) -> HashMap { + hash_map!["registrar".to_owned() => self.params().registrar.hex()] + } fn builtins(&self) -> &BTreeMap { &self.builtins } @@ -412,11 +469,11 @@ impl Engine for Tendermint { header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; if gas_limit < gas_floor_target { - min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) + cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); } @@ -427,6 +484,9 @@ impl Engine for Tendermint { } /// Attempt to seal generate a proposal seal. + /// + /// This operation is synchronous and may (quite reasonably) not be available, in which case + /// `Seal::None` will be returned. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { let header = block.header(); let author = header.author(); @@ -483,7 +543,8 @@ impl Engine for Tendermint { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{ let fields = block.fields_mut(); // Bestow block reward - let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) + let reward = self.params().block_reward; + let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty) .map_err(::error::Error::from) .and_then(|_| fields.state.commit()); // Commit state so that we can actually figure out the state root. @@ -555,7 +616,7 @@ impl Engine for Tendermint { self.check_above_threshold(origins.len())? } - let gas_limit_divisor = self.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { @@ -566,6 +627,58 @@ impl Engine for Tendermint { Ok(()) } + fn signals_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> super::EpochChange + { + let first = header.number() == 0; + self.validators.signals_epoch_end(first, header, block, receipts) + } + + fn is_epoch_end( + &self, + chain_head: &Header, + _chain: &super::Headers, + transition_store: &super::PendingTransitionStore, + ) -> Option> { + let first = chain_head.number() == 0; + + if let Some(change) = self.validators.is_epoch_end(first, chain_head) { + let change = combine_proofs(chain_head.number(), &change, &[]); + return Some(change) + } else if let Some(pending) = transition_store(chain_head.hash()) { + let signal_number = chain_head.number(); + let finality_proof = ::rlp::encode(chain_head); + return Some(combine_proofs(signal_number, &pending.proof, &finality_proof)) + } + + None + } + + fn epoch_verifier<'a>(&self, _header: &Header, proof: &'a [u8]) -> ConstructedVerifier<'a> { + let (signal_number, set_proof, finality_proof) = match destructure_proofs(proof) { + Ok(x) => x, + Err(e) => return ConstructedVerifier::Err(e), + }; + + let first = signal_number == 0; + match self.validators.epoch_set(first, self, signal_number, set_proof) { + Ok((list, finalize)) => { + let verifier = Box::new(EpochVerifier { + subchain_validators: list, + recover: |signature: &Signature, message: &Message| { + Ok(public_to_address(&::ethkey::recover(&signature, &message)?)) + }, + }); + + match finalize { + Some(finalize) => ConstructedVerifier::Unconfirmed(verifier, finality_proof, finalize), + None => ConstructedVerifier::Trusted(verifier), + } + } + Err(e) => ConstructedVerifier::Err(e), + } + } + fn set_signer(&self, ap: Arc, address: Address, password: String) { { self.signer.write().set(ap, address, password); @@ -577,6 +690,10 @@ impl Engine for Tendermint { self.signer.read().sign(hash).map_err(Into::into) } + fn snapshot_components(&self) -> Option> { + Some(Box::new(::snapshot::PoaSnapshot)) + } + fn stop(&self) { self.step_service.stop() } @@ -654,6 +771,7 @@ impl Engine for Tendermint { #[cfg(test)] mod tests { + use std::str::FromStr; use rustc_hex::FromHex; use util::*; use block::*; @@ -665,6 +783,7 @@ mod tests { use account_provider::AccountProvider; use spec::Spec; use engines::{Engine, EngineError, Seal}; + use engines::epoch::EpochVerifier; use super::*; /// Accounts inserted with "0" and "1" are validators. First proposer is "0". @@ -932,7 +1051,7 @@ mod tests { client.miner().import_own_transaction(client.as_ref(), transaction.into()).unwrap(); // Propose - let proposal = Some(client.miner().pending_block().unwrap().header.bare_hash()); + let proposal = Some(client.miner().pending_block(0).unwrap().header.bare_hash()); // Propose timeout engine.step(); @@ -949,4 +1068,76 @@ mod tests { vote(engine, |mh| tap.sign(v0, None, mh).map(H520::from), h, r, Step::Precommit, proposal); assert_eq!(client.chain_info().best_block_number, 1); } + + #[test] + fn epoch_verifier_verify_light() { + use ethkey::Error as EthkeyError; + + let (spec, tap) = setup(); + let engine = spec.engine; + + let mut parent_header: Header = Header::default(); + parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + + let mut header = Header::default(); + header.set_number(2); + header.set_gas_limit(U256::from_str("222222").unwrap()); + let proposer = insert_and_unlock(&tap, "1"); + header.set_author(proposer); + let mut seal = proposal_seal(&tap, &header, 0); + + let vote_info = message_info_rlp(&VoteStep::new(2, 0, Step::Precommit), Some(header.bare_hash())); + let signature1 = tap.sign(proposer, None, vote_info.sha3()).unwrap(); + + let voter = insert_and_unlock(&tap, "0"); + let signature0 = tap.sign(voter, None, vote_info.sha3()).unwrap(); + + seal[1] = ::rlp::NULL_RLP.to_vec(); + seal[2] = ::rlp::encode_list(&vec![H520::from(signature1.clone())]).into_vec(); + header.set_seal(seal.clone()); + + let epoch_verifier = super::EpochVerifier { + subchain_validators: SimpleList::new(vec![proposer.clone(), voter.clone()]), + recover: { + let signature1 = signature1.clone(); + let signature0 = signature0.clone(); + let proposer = proposer.clone(); + let voter = voter.clone(); + move |s: &Signature, _: &Message| { + if *s == signature1 { + Ok(proposer) + } else if *s == signature0 { + Ok(voter) + } else { + Err(Error::Ethkey(EthkeyError::InvalidSignature)) + } + } + }, + }; + + // One good signature is not enough. + match epoch_verifier.verify_light(&header) { + Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}, + _ => panic!(), + } + + seal[2] = ::rlp::encode_list(&vec![H520::from(signature1.clone()), H520::from(signature0.clone())]).into_vec(); + header.set_seal(seal.clone()); + + assert!(epoch_verifier.verify_light(&header).is_ok()); + + let bad_voter = insert_and_unlock(&tap, "101"); + let bad_signature = tap.sign(bad_voter, None, vote_info.sha3()).unwrap(); + + seal[2] = ::rlp::encode_list(&vec![H520::from(signature1), H520::from(bad_signature)]).into_vec(); + header.set_seal(seal); + + // One good and one bad signature. + match epoch_verifier.verify_light(&header) { + Err(Error::Ethkey(EthkeyError::InvalidSignature)) => {}, + _ => panic!(), + }; + + engine.stop(); + } } diff --git a/ethcore/src/engines/tendermint/params.rs b/ethcore/src/engines/tendermint/params.rs index 16b47a0fb..7ff3d697f 100644 --- a/ethcore/src/engines/tendermint/params.rs +++ b/ethcore/src/engines/tendermint/params.rs @@ -17,7 +17,6 @@ //! Tendermint specific parameters. use ethjson; -use util::{U256, Address}; use time::Duration; use super::super::validator_set::{ValidatorSet, new_validator_set}; use super::super::transition::Timeouts; @@ -25,16 +24,10 @@ use super::Step; /// `Tendermint` params. pub struct TendermintParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// List of validators. pub validators: Box, /// Timeout durations for different steps. pub timeouts: TendermintTimeouts, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, } /// Base timeout of each step in ms. @@ -81,7 +74,6 @@ impl From for TendermintParams { fn from(p: ethjson::spec::TendermintParams) -> Self { let dt = TendermintTimeouts::default(); TendermintParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), validators: new_validator_set(p.validators), timeouts: TendermintTimeouts { propose: p.timeout_propose.map_or(dt.propose, to_duration), @@ -89,8 +81,6 @@ impl From for TendermintParams { precommit: p.timeout_precommit.map_or(dt.precommit, to_duration), commit: p.timeout_commit.map_or(dt.commit, to_duration), }, - block_reward: p.block_reward.map_or_else(U256::zero, Into::into), - registrar: p.registrar.map_or_else(Address::new, Into::into), } } } diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 46f5c8512..7c1890379 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -126,6 +126,7 @@ impl ValidatorSet for ValidatorContract { #[cfg(test)] mod tests { + use std::sync::Arc; use rustc_hex::FromHex; use util::*; use rlp::encode; @@ -142,11 +143,11 @@ mod tests { #[test] fn fetches_validators() { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None); - let vc = Arc::new(ValidatorContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); + let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_contract(Arc::downgrade(&client)); let last_hash = client.best_block_header().hash(); - assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); - assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); + assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::
().unwrap())); + assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::
().unwrap())); } #[test] @@ -155,7 +156,7 @@ mod tests { let v1 = tap.insert_account("1".sha3().into(), "").unwrap(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone())); client.engine().register_client(Arc::downgrade(&client)); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); // Make sure reporting can be done. client.miner().set_gas_floor_target(1_000_000.into()); diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 5835dbcdb..9acf6050b 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -142,6 +142,8 @@ impl ValidatorSet for Multi { #[cfg(test)] mod tests { + use std::sync::Arc; + use std::collections::BTreeMap; use account_provider::AccountProvider; use client::{BlockChainClient, EngineClient}; use engines::EpochChange; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 2c42323be..96790dca7 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -16,7 +16,7 @@ /// Validator set maintained in a contract, updated using `getValidators` method. -use std::sync::Weak; +use std::sync::{Weak, Arc}; use futures::Future; use native_contracts::ValidatorSet as Provider; @@ -299,7 +299,7 @@ impl ValidatorSet for ValidatorSafeContract { let (old_header, state_items) = decode_first_proof(&rlp)?; let old_hash = old_header.hash(); - let env_info = ::evm::env_info::EnvInfo { + let env_info = ::vm::EnvInfo { number: old_header.number(), author: *old_header.author(), difficulty: *old_header.difficulty(), @@ -422,6 +422,7 @@ impl ValidatorSet for ValidatorSafeContract { #[cfg(test)] mod tests { + use std::sync::Arc; use rustc_hex::FromHex; use util::*; use types::ids::BlockId; @@ -438,11 +439,11 @@ mod tests { #[test] fn fetches_validators() { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); - let vc = Arc::new(ValidatorSafeContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); + let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::
().unwrap())); vc.register_contract(Arc::downgrade(&client)); let last_hash = client.best_block_header().hash(); - assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); - assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); + assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::
().unwrap())); + assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::
().unwrap())); } #[test] @@ -454,7 +455,7 @@ mod tests { let network_id = Spec::new_validator_safe_contract().network_id(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); client.engine().register_client(Arc::downgrade(&client)); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); client.miner().set_engine_signer(v1, "".into()).unwrap(); // Remove "1" validator. @@ -520,7 +521,7 @@ mod tests { let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); let engine = client.engine().clone(); - let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + let validator_contract = "0000000000000000000000000000000000000005".parse::
().unwrap(); let last_hash = client.best_block_header().hash(); let mut new_header = Header::default(); diff --git a/ethcore/src/engines/validator_set/test.rs b/ethcore/src/engines/validator_set/test.rs index 4960ee7be..25eeff66e 100644 --- a/ethcore/src/engines/validator_set/test.rs +++ b/ethcore/src/engines/validator_set/test.rs @@ -17,8 +17,9 @@ /// Used for Engine testing. use std::str::FromStr; +use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; -use util::{Arc, Bytes, H256, Address, HeapSizeOf}; +use util::{Bytes, H256, Address, HeapSizeOf}; use engines::{Call, Engine}; use header::{Header, BlockNumber}; diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index d01d07f15..b934fdb2e 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -17,6 +17,8 @@ //! Collects votes on hashes at each Message::Round. use std::fmt::Debug; +use std::collections::{BTreeMap, HashSet, HashMap}; +use std::hash::Hash; use util::*; use rlp::{Encodable, RlpStream}; diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 2d908cdb6..194cbcb38 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -16,6 +16,7 @@ //! General error types for use in ethcore. +use std::fmt; use util::*; use io::*; use header::BlockNumber; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 1fbd711c9..7e275cf98 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -15,11 +15,14 @@ // along with Parity. If not, see . use std::path::Path; +use std::cmp; +use std::collections::{BTreeMap, HashMap}; +use std::sync::Arc; use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use util::*; use block::*; use builtin::Builtin; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use error::{BlockError, Error, TransactionError}; use header::{Header, BlockNumber}; use state::CleanupMode; @@ -29,7 +32,7 @@ use engines::{self, Engine}; use evm::Schedule; use ethjson; use rlp::{self, UntrustedRlp}; -use evm::env_info::LastHashes; +use vm::LastHashes; /// Parity tries to round block.gas_limit to multiple of this constant pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); @@ -41,8 +44,6 @@ const SNAPSHOT_BLOCKS: u64 = 30000; /// Ethash params. #[derive(Debug, PartialEq)] pub struct EthashParams { - /// Gas limit divisor. - pub gas_limit_bound_divisor: U256, /// Minimum difficulty. pub minimum_difficulty: U256, /// Difficulty bound divisor. @@ -53,10 +54,6 @@ pub struct EthashParams { pub metropolis_difficulty_increment_divisor: u64, /// Block duration. pub duration_limit: u64, - /// Block reward. - pub block_reward: U256, - /// Namereg contract address. - pub registrar: Address, /// Homestead transition block number. pub homestead_transition: u64, /// DAO hard-fork transition block (X). @@ -75,8 +72,6 @@ pub struct EthashParams { pub eip100b_transition: u64, /// Number of first block where EIP-150 rules begin. pub eip150_transition: u64, - /// Number of first block where EIP-155 rules begin. - pub eip155_transition: u64, /// Number of first block where EIP-160 rules begin. pub eip160_transition: u64, /// Number of first block where EIP-161.abc begin. @@ -104,14 +99,11 @@ pub struct EthashParams { impl From for EthashParams { fn from(p: ethjson::spec::EthashParams) -> Self { EthashParams { - gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), minimum_difficulty: p.minimum_difficulty.into(), difficulty_bound_divisor: p.difficulty_bound_divisor.into(), difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into), metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into), duration_limit: p.duration_limit.map_or(0, Into::into), - block_reward: p.block_reward.into(), - registrar: p.registrar.map_or_else(Address::new, Into::into), homestead_transition: p.homestead_transition.map_or(0, Into::into), dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into), dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into), @@ -121,7 +113,6 @@ impl From for EthashParams { bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into), eip100b_transition: p.eip100b_transition.map_or(u64::max_value(), Into::into), eip150_transition: p.eip150_transition.map_or(0, Into::into), - eip155_transition: p.eip155_transition.map_or(0, Into::into), eip160_transition: p.eip160_transition.map_or(0, Into::into), eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into), eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into), @@ -185,7 +176,7 @@ impl Engine for Arc { fn seal_fields(&self) -> usize { 2 } fn params(&self) -> &CommonParams { &self.params } - fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.ethash_params.registrar.hex()] } + fn additional_params(&self) -> HashMap { hash_map!["registrar".to_owned() => self.params().registrar.hex()] } fn builtins(&self) -> &BTreeMap { &self.builtins @@ -216,7 +207,7 @@ impl Engine for Arc { } fn signing_network_id(&self, env_info: &EnvInfo) -> Option { - if env_info.number >= self.ethash_params.eip155_transition { + if env_info.number >= self.params().eip155_transition { Some(self.params().chain_id) } else { None @@ -231,19 +222,19 @@ impl Engine for Arc { } let gas_limit = { let gas_limit = parent.gas_limit().clone(); - let bound_divisor = self.ethash_params.gas_limit_bound_divisor; + let bound_divisor = self.params().gas_limit_bound_divisor; let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into(); let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into(); let gas_limit = if gas_limit < gas_floor_target { - let gas_limit = min(gas_floor_target, upper_limit); + let gas_limit = cmp::min(gas_floor_target, upper_limit); round_block_gas_limit(gas_limit, lower_limit, upper_limit) } else if gas_limit > gas_ceil_target { - let gas_limit = max(gas_ceil_target, lower_limit); + let gas_limit = cmp::max(gas_ceil_target, lower_limit); round_block_gas_limit(gas_limit, lower_limit, upper_limit) } else { - let total_lower_limit = max(lower_limit, gas_floor_target); - let total_upper_limit = min(upper_limit, gas_ceil_target); - let gas_limit = max(gas_floor_target, min(total_upper_limit, + let total_lower_limit = cmp::max(lower_limit, gas_floor_target); + let total_upper_limit = cmp::min(upper_limit, gas_ceil_target); + let gas_limit = cmp::max(gas_floor_target, cmp::min(total_upper_limit, lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor)); round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit) }; @@ -284,7 +275,7 @@ impl Engine for Arc { /// Apply the block reward on finalisation of the block. /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { - let reward = self.ethash_params.block_reward; + let reward = self.params().block_reward; let fields = block.fields_mut(); let eras_rounds = self.ethash_params.ecip1017_era_rounds; let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number()); @@ -319,7 +310,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // check the seal fields. if header.seal().len() != self.seal_fields() { return Err(From::from(BlockError::InvalidSealArity( @@ -357,7 +348,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { if header.seal().len() != self.seal_fields() { return Err(From::from(BlockError::InvalidSealArity( Mismatch { expected: self.seal_fields(), found: header.seal().len() } @@ -376,7 +367,7 @@ impl Engine for Arc { Ok(()) } - fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { + fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { // we should not calculate difficulty for genesis blocks if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); @@ -387,7 +378,7 @@ impl Engine for Arc { if header.difficulty() != &expected_difficulty { return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() }))) } - let gas_limit_divisor = self.ethash_params.gas_limit_bound_divisor; + let gas_limit_divisor = self.params().gas_limit_bound_divisor; let parent_gas_limit = *parent.gas_limit(); let min_gas = parent_gas_limit - parent_gas_limit / gas_limit_divisor; let max_gas = parent_gas_limit + parent_gas_limit / gas_limit_divisor; @@ -400,13 +391,13 @@ impl Engine for Arc { Ok(()) } - fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> { if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price { return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into()); } let check_low_s = header.number() >= self.ethash_params.homestead_transition; - let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None }; + let network_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None }; t.verify_basic(check_low_s, network_id, false)?; Ok(()) } @@ -493,28 +484,28 @@ impl Ethash { if diff_inc <= threshold { *parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into() } else { - let multiplier = min(diff_inc - threshold, 99).into(); + let multiplier = cmp::min(diff_inc - threshold, 99).into(); parent.difficulty().saturating_sub( *parent.difficulty() / difficulty_bound_divisor * multiplier ) } }; - target = max(min_difficulty, target); + target = cmp::max(min_difficulty, target); if header.number() < self.ethash_params.bomb_defuse_transition { if header.number() < self.ethash_params.ecip1010_pause_transition { let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; if period > 1 { - target = max(min_difficulty, target + (U256::from(1) << (period - 2))); + target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2))); } } else if header.number() < self.ethash_params.ecip1010_continue_transition { let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize; - target = max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); + target = cmp::max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); } else { let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize; - target = max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); + target = cmp::max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); } } target @@ -559,6 +550,9 @@ impl Header { #[cfg(test)] mod tests { + use std::str::FromStr; + use std::collections::BTreeMap; + use std::sync::Arc; use util::*; use block::*; use tests::helpers::*; @@ -809,36 +803,32 @@ mod tests { #[test] fn has_valid_ecip1017_eras_block_reward() { - let ethparams = EthashParams { - // see ethcore/res/ethereum/classic.json - ecip1017_era_rounds: 5000000, - block_reward: U256::from_str("4563918244F40000").unwrap(), - ..get_default_ethash_params() - }; - let eras_rounds = ethparams.ecip1017_era_rounds; - let reward = ethparams.block_reward; + let eras_rounds = 5000000; + + let start_reward: U256 = "4563918244F40000".parse().unwrap(); + let block_number = 0; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(0, eras); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 5000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(0, eras); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 10000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(1, eras); assert_eq!(U256::from_str("3782DACE9D900000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 20000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(3, eras); assert_eq!(U256::from_str("2386F26FC1000000").unwrap(), reward); - let reward = ethparams.block_reward; + let block_number = 80000000; - let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); + let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number); assert_eq!(15, eras); assert_eq!(U256::from_str("271000000000000").unwrap(), reward); } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index e731ef7db..dee86883b 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -134,23 +134,4 @@ mod tests { let _ = frontier.engine; } - - #[test] - fn all_spec_files_valid() { - let tmp = ::std::env::temp_dir(); - new_olympic(&tmp); - new_foundation(&tmp); - new_classic(&tmp); - new_expanse(&tmp); - new_kovan(&tmp); - new_ropsten(&tmp); - new_morden(&tmp); - new_frontier_test(); - new_homestead_test(); - new_eip150_test(); - new_eip161_test(); - new_transition_test(); - new_mainnet_like(); - new_metropolis_test(); - } } diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index f6508668f..3154903ca 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -17,7 +17,7 @@ //! Transaction execution format module. use util::{Bytes, U256, Address, U512, trie}; -use evm; +use vm; use trace::{VMTrace, FlatTrace}; use log_entry::LogEntry; use state_diff::StateDiff; @@ -28,7 +28,7 @@ use std::fmt; #[derive(Debug, PartialEq, Clone)] pub struct Executed { /// True if the outer call/create resulted in an exceptional exit. - pub exception: Option, + pub exception: Option, /// Gas paid up front for execution of transaction. pub gas: U256, diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9e25b6671..bd7cf28c1 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -15,14 +15,16 @@ // along with Parity. If not, see . //! Transaction Execution environment. +use std::cmp; +use std::sync::Arc; use util::*; -use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; use engines::Engine; -use evm::CallType; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use error::ExecutionError; -use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode}; +use evm::{CallType, Factory, Finalize, FinalizationResult}; +use vm::{self, Ext, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, ActionValue}; +use wasm; use externalities::*; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; use transaction::{Action, SignedTransaction}; @@ -74,8 +76,8 @@ pub struct TransactOptions { pub check_nonce: bool, } -pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) - -> Box where E: Engine + ?Sized +pub fn executor(engine: &E, vm_factory: &Factory, params: &ActionParams) + -> Box where E: Engine + ?Sized { if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) { Box::new( @@ -269,7 +271,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { output_policy: OutputPolicy, tracer: &mut T, vm_tracer: &mut V - ) -> evm::Result where T: Tracer, V: VMTracer { + ) -> vm::Result where T: Tracer, V: VMTracer { let depth_threshold = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get() / STACK_SIZE_PER_DEPTH); let static_call = params.call_type == CallType::StaticCall; @@ -299,7 +301,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { /// Calls contract function with given contract params. /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). /// Modifies the substate and the output. - /// Returns either gas_left or `evm::Error`. + /// Returns either gas_left or `vm::Error`. pub fn call( &mut self, params: ActionParams, @@ -307,14 +309,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { mut output: BytesRef, tracer: &mut T, vm_tracer: &mut V - ) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { + ) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); if (params.call_type == CallType::StaticCall || ((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) && self.static_flag)) && params.value.value() > 0.into() { - return Err(evm::Error::MutableCallInStaticContext); + return Err(vm::Error::MutableCallInStaticContext); } // backup used in case of running out of gas @@ -344,7 +346,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { if cost <= params.gas { if let Err(e) = builtin.execute(data, &mut output) { self.state.revert_to_checkpoint(); - let evm_err: evm::evm::Error = e.into(); + let evm_err: vm::Error = e.into(); tracer.trace_failed_call(trace_info, vec![], evm_err.clone().into()); Err(evm_err) } else { @@ -371,9 +373,9 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { // just drain the whole gas self.state.revert_to_checkpoint(); - tracer.trace_failed_call(trace_info, vec![], evm::Error::OutOfGas.into()); + tracer.trace_failed_call(trace_info, vec![], vm::Error::OutOfGas.into()); - Err(evm::Error::OutOfGas) + Err(vm::Error::OutOfGas) } } else { let trace_info = tracer.prepare_trace_call(¶ms); @@ -432,17 +434,17 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { substate: &mut Substate, tracer: &mut T, vm_tracer: &mut V, - ) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { + ) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { let scheme = self.engine.create_address_scheme(self.info.number); if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(¶ms.address)? { - return Err(evm::Error::OutOfGas); + return Err(vm::Error::OutOfGas); } if params.call_type == CallType::StaticCall || self.static_flag { let trace_info = tracer.prepare_trace_create(¶ms); - tracer.trace_failed_create(trace_info, vec![], evm::Error::MutableCallInStaticContext.into()); - return Err(evm::Error::MutableCallInStaticContext); + tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into()); + return Err(vm::Error::MutableCallInStaticContext); } // backup used in case of running out of gas @@ -496,7 +498,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { &mut self, t: &SignedTransaction, mut substate: Substate, - result: evm::Result<(U256, ReturnData)>, + result: vm::Result<(U256, ReturnData)>, output: Bytes, trace: Vec, vm_trace: Option @@ -538,7 +540,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; match result { - Err(evm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), + Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), Err(exception) => { Ok(Executed { exception: Some(exception), @@ -572,20 +574,20 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { } } - fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate) { + fn enact_result(&mut self, result: &vm::Result, substate: &mut Substate, un_substate: Substate) { match *result { - Err(evm::Error::OutOfGas) - | Err(evm::Error::BadJumpDestination {..}) - | Err(evm::Error::BadInstruction {.. }) - | Err(evm::Error::StackUnderflow {..}) - | Err(evm::Error::BuiltIn {..}) - | Err(evm::Error::Wasm {..}) - | Err(evm::Error::OutOfStack {..}) - | Err(evm::Error::MutableCallInStaticContext) + Err(vm::Error::OutOfGas) + | Err(vm::Error::BadJumpDestination {..}) + | Err(vm::Error::BadInstruction {.. }) + | Err(vm::Error::StackUnderflow {..}) + | Err(vm::Error::BuiltIn {..}) + | Err(vm::Error::Wasm {..}) + | Err(vm::Error::OutOfStack {..}) + | Err(vm::Error::MutableCallInStaticContext) | Ok(FinalizationResult { apply_state: false, .. }) => { self.state.revert_to_checkpoint(); }, - Ok(_) | Err(evm::Error::Internal(_)) => { + Ok(_) | Err(vm::Error::Internal(_)) => { self.state.discard_checkpoint(); substate.accrue(un_substate); } @@ -597,14 +599,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { #[allow(dead_code)] mod tests { use std::sync::Arc; + use std::str::FromStr; use rustc_hex::FromHex; use ethkey::{Generator, Random}; use super::*; - use util::{H256, U256, U512, Address, FromStr}; + use util::{H256, U256, U512, Address}; use util::bytes::BytesRef; - use evm::action_params::{ActionParams, ActionValue}; - use evm::env_info::EnvInfo; - use evm::{Factory, VMType, CreateContractAddress}; + use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; + use evm::{Factory, VMType}; use error::ExecutionError; use state::{Substate, CleanupMode}; use tests::helpers::*; @@ -613,8 +615,6 @@ mod tests { use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; use transaction::{Action, Transaction}; - use evm::CallType; - #[test] fn test_contract_address() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 39c8673a9..eae981f1b 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -15,14 +15,17 @@ // along with Parity. If not, see . //! Transaction Execution environment. +use std::cmp; +use std::sync::Arc; use util::*; -use evm::action_params::{ActionParams, ActionValue}; use state::{Backend as StateBackend, State, Substate, CleanupMode}; use engines::Engine; -use evm::env_info::EnvInfo; use executive::*; -use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; -use evm::CallType; +use vm::{ + self, ActionParams, ActionValue, EnvInfo, CallType, Schedule, + Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, + ReturnData +}; use transaction::UNSIGNED_SENDER; use trace::{Tracer, VMTracer}; @@ -109,31 +112,31 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E> impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized { - fn storage_at(&self, key: &H256) -> evm::Result { + fn storage_at(&self, key: &H256) -> vm::Result { self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) } - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { + fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { if self.static_flag { - Err(evm::Error::MutableCallInStaticContext) + Err(vm::Error::MutableCallInStaticContext) } else { self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) } } - fn exists(&self, address: &Address) -> evm::Result { + fn exists(&self, address: &Address) -> vm::Result { self.state.exists(address).map_err(Into::into) } - fn exists_and_not_null(&self, address: &Address) -> evm::Result { + fn exists_and_not_null(&self, address: &Address) -> vm::Result { self.state.exists_and_not_null(address).map_err(Into::into) } - fn origin_balance(&self) -> evm::Result { + fn origin_balance(&self) -> vm::Result { self.balance(&self.origin_info.address).map_err(Into::into) } - fn balance(&self, address: &Address) -> evm::Result { + fn balance(&self, address: &Address) -> vm::Result { self.state.balance(address).map_err(Into::into) } @@ -274,16 +277,16 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> } } - fn extcode(&self, address: &Address) -> evm::Result> { + fn extcode(&self, address: &Address) -> vm::Result> { Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![]))) } - fn extcodesize(&self, address: &Address) -> evm::Result { + fn extcodesize(&self, address: &Address) -> vm::Result { Ok(self.state.code_size(address)?.unwrap_or(0)) } #[cfg_attr(feature="dev", allow(match_ref_pats))] - fn ret(mut self, gas: &U256, data: &ReturnData) -> evm::Result + fn ret(mut self, gas: &U256, data: &ReturnData) -> vm::Result where Self: Sized { let handle_copy = |to: &mut Option<&mut Bytes>| { to.as_mut().map(|b| **b = data.to_vec()); @@ -307,7 +310,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); if return_cost > *gas || data.len() > self.schedule.create_data_limit { return match self.schedule.exceptional_failed_code_deposit { - true => Err(evm::Error::OutOfGas), + true => Err(vm::Error::OutOfGas), false => Ok(*gas) } } @@ -320,11 +323,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> } } - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()> { + fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { use log_entry::LogEntry; if self.static_flag { - return Err(evm::Error::MutableCallInStaticContext); + return Err(vm::Error::MutableCallInStaticContext); } let address = self.origin_info.address.clone(); @@ -337,9 +340,9 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> Ok(()) } - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { + fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { if self.static_flag { - return Err(evm::Error::MutableCallInStaticContext); + return Err(vm::Error::MutableCallInStaticContext); } let address = self.origin_info.address.clone(); @@ -396,13 +399,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> mod tests { use util::*; use engines::Engine; - use evm::env_info::EnvInfo; - use evm::Ext; + use evm::{EnvInfo, Ext, CallType}; use state::{State, Substate}; use tests::helpers::*; use super::*; use trace::{NoopTracer, NoopVMTracer}; - use evm::CallType; fn get_test_origin() -> OriginInfo { OriginInfo { @@ -470,7 +471,7 @@ mod tests { let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); - let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); assert_eq!(hash, H256::zero()); } @@ -494,7 +495,7 @@ mod tests { let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); - let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); + let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap()); assert_eq!(test_hash, hash); } @@ -513,10 +514,10 @@ mod tests { // this should panic because we have no balance on any account ext.call( - &U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap(), + &"0000000000000000000000000000000000000000000000000000000000120000".parse::().unwrap(), &Address::new(), &Address::new(), - Some(U256::from_str("0000000000000000000000000000000000000000000000000000000000150000").unwrap()), + Some("0000000000000000000000000000000000000000000000000000000000150000".parse::().unwrap()), &[], &Address::new(), &mut output, diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 83c69e97d..a9a4f948d 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -16,13 +16,13 @@ //! Block header. +use std::cmp; +use std::cell::RefCell; use util::*; use basic_types::{LogBloom, ZERO_LOGBLOOM}; use time::get_time; use rlp::*; -use std::cell::RefCell; - pub use basic_types::Seal; pub use types::BlockNumber; @@ -175,7 +175,7 @@ impl Header { /// Set the timestamp field of the header. pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); } /// Set the timestamp field of the header to the current time. - pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } + pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = cmp::max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } /// Set the number field of the header. pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); } /// Set the author field of the header. @@ -275,7 +275,7 @@ impl Decodable for Header { number: r.val_at(8)?, gas_limit: r.val_at(9)?, gas_used: r.val_at(10)?, - timestamp: min(r.val_at::(11)?, u64::max_value().into()).as_u64(), + timestamp: cmp::min(r.val_at::(11)?, u64::max_value().into()).as_u64(), extra_data: r.val_at(12)?, seal: vec![], hash: RefCell::new(Some(r.as_raw().sha3())), diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index ccdd7d499..7047c9882 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use super::test_common::*; +use std::sync::Arc; use client::{BlockChainClient, Client, ClientConfig}; use block::Block; use ethereum; diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 0c5a6a90d..f7b4bbe81 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -14,16 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::sync::Arc; use super::test_common::*; -use evm::action_params::ActionParams; use state::{Backend as StateBackend, State, Substate}; use executive::*; use engines::Engine; -use evm::env_info::EnvInfo; -use evm; -use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; +use evm::{VMType, Finalize}; +use vm::{ + self, ActionParams, CallType, Schedule, Ext, + ContractCreateResult, EnvInfo, MessageCallResult, + CreateContractAddress, ReturnData, +}; use externalities::*; -use evm::CallType; use tests::helpers::*; use ethjson; use trace::{Tracer, NoopTracer}; @@ -88,27 +90,27 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> TestExt<'a, T, V, B, E> impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E> where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized { - fn storage_at(&self, key: &H256) -> evm::Result { + fn storage_at(&self, key: &H256) -> vm::Result { self.ext.storage_at(key) } - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { + fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { self.ext.set_storage(key, value) } - fn exists(&self, address: &Address) -> evm::Result { + fn exists(&self, address: &Address) -> vm::Result { self.ext.exists(address) } - fn exists_and_not_null(&self, address: &Address) -> evm::Result { + fn exists_and_not_null(&self, address: &Address) -> vm::Result { self.ext.exists_and_not_null(address) } - fn balance(&self, address: &Address) -> evm::Result { + fn balance(&self, address: &Address) -> vm::Result { self.ext.balance(address) } - fn origin_balance(&self) -> evm::Result { + fn origin_balance(&self) -> vm::Result { self.ext.origin_balance() } @@ -146,23 +148,23 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E> MessageCallResult::Success(*gas, ReturnData::empty()) } - fn extcode(&self, address: &Address) -> evm::Result> { + fn extcode(&self, address: &Address) -> vm::Result> { self.ext.extcode(address) } - fn extcodesize(&self, address: &Address) -> evm::Result { + fn extcodesize(&self, address: &Address) -> vm::Result { self.ext.extcodesize(address) } - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()> { + fn log(&mut self, topics: Vec, data: &[u8]) -> vm::Result<()> { self.ext.log(topics, data) } - fn ret(self, gas: &U256, data: &ReturnData) -> Result { + fn ret(self, gas: &U256, data: &ReturnData) -> Result { self.ext.ret(gas, data) } - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { + fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> { self.ext.suicide(refund_address) } diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index 74bbfb266..2fdf8875f 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -22,7 +22,7 @@ use spec::Spec; use ethjson; use ethjson::state::test::ForkSpec; use transaction::SignedTransaction; -use evm::env_info::EnvInfo; +use vm::EnvInfo; lazy_static! { pub static ref FRONTIER: Spec = ethereum::new_frontier_test(); diff --git a/ethcore/src/json_tests/test_common.rs b/ethcore/src/json_tests/test_common.rs index f9716d221..fa1078776 100644 --- a/ethcore/src/json_tests/test_common.rs +++ b/ethcore/src/json_tests/test_common.rs @@ -15,6 +15,8 @@ // along with Parity. If not, see . pub use util::*; +use std::collections::HashSet; +use std::io::Read; use std::fs::{File, read_dir}; use std::path::Path; use std::ffi::OsString; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index af7922c20..6c862ecda 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -98,14 +98,19 @@ extern crate lru_cache; extern crate native_contracts; extern crate num_cpus; extern crate num; +extern crate price_info; extern crate rand; extern crate rlp; extern crate rustc_hex; -extern crate rustc_serialize; extern crate semver; extern crate stats; extern crate time; extern crate transient_hashmap; +extern crate using_queue; +extern crate table; +extern crate bloomable; +extern crate vm; +extern crate wasm; #[macro_use] extern crate log; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 4b7671946..02463d929 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -15,12 +15,14 @@ // along with Parity. If not, see . use std::time::{Instant, Duration}; +use std::collections::{BTreeMap, HashSet}; +use std::sync::Arc; use util::*; -use util::using_queue::{UsingQueue, GetAction}; +use using_queue::{UsingQueue, GetAction}; use account_provider::{AccountProvider, SignError as AccountError}; -use state::{State, CleanupMode}; -use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockId, CallAnalytics, TransactionId}; +use state::State; +use client::{MiningBlockChainClient, BlockId, TransactionId}; use client::TransactionImportResult; use executive::contract_address; use block::{ClosedBlock, IsBlock, Block}; @@ -33,10 +35,11 @@ use miner::{MinerService, MinerStatus, TransactionQueue, RemovalReason, Transact AccountDetails, TransactionOrigin}; use miner::banning_queue::{BanningTransactionQueue, Threshold}; use miner::work_notify::{WorkPoster, NotifyWork}; -use miner::price_info::PriceInfo; use miner::local_transactions::{Status as LocalTransactionStatus}; use miner::service_transaction_checker::ServiceTransactionChecker; -use header::BlockNumber; +use price_info::{Client as PriceInfoClient, PriceInfo}; +use price_info::fetch::Client as FetchClient; +use header::{Header, BlockNumber}; /// Different possible definitions for pending transaction set. #[derive(Debug, PartialEq)] @@ -154,6 +157,7 @@ pub struct GasPriceCalibratorOptions { pub struct GasPriceCalibrator { options: GasPriceCalibratorOptions, next_calibration: Instant, + price_info: PriceInfoClient, } impl GasPriceCalibrator { @@ -163,7 +167,7 @@ impl GasPriceCalibrator { let usd_per_tx = self.options.usd_per_tx; trace!(target: "miner", "Getting price info"); - PriceInfo::get(move |price: PriceInfo| { + self.price_info.get(move |price: PriceInfo| { trace!(target: "miner", "Price info arrived: {:?}", price); let usd_per_eth = price.ethusd; let wei_per_usd: f32 = 1.0e18 / usd_per_eth; @@ -189,10 +193,11 @@ pub enum GasPricer { impl GasPricer { /// Create a new Calibrated `GasPricer`. - pub fn new_calibrated(options: GasPriceCalibratorOptions) -> GasPricer { + pub fn new_calibrated(options: GasPriceCalibratorOptions, fetch: FetchClient) -> GasPricer { GasPricer::Calibrated(GasPriceCalibrator { options: options, next_calibration: Instant::now(), + price_info: PriceInfoClient::new(fetch), }) } @@ -326,13 +331,28 @@ impl Miner { } /// Get `Some` `clone()` of the current pending block's state or `None` if we're not sealing. - pub fn pending_state(&self) -> Option> { - self.sealing_work.lock().queue.peek_last_ref().map(|b| b.block().fields().state.clone()) + pub fn pending_state(&self, latest_block_number: BlockNumber) -> Option> { + self.map_pending_block(|b| b.state().clone(), latest_block_number) } /// Get `Some` `clone()` of the current pending block or `None` if we're not sealing. - pub fn pending_block(&self) -> Option { - self.sealing_work.lock().queue.peek_last_ref().map(|b| b.to_base()) + pub fn pending_block(&self, latest_block_number: BlockNumber) -> Option { + self.map_pending_block(|b| b.to_base(), latest_block_number) + } + + /// Get `Some` `clone()` of the current pending block header or `None` if we're not sealing. + pub fn pending_block_header(&self, latest_block_number: BlockNumber) -> Option
{ + self.map_pending_block(|b| b.header().clone(), latest_block_number) + } + + fn map_pending_block(&self, f: F, latest_block_number: BlockNumber) -> Option where + F: FnOnce(&ClosedBlock) -> T, + { + self.from_pending_block( + latest_block_number, + || None, + |block| Some(f(block)), + ) } #[cfg_attr(feature="dev", allow(match_same_arms))] @@ -674,7 +694,7 @@ impl Miner { #[cfg_attr(feature="dev", allow(wrong_self_convention))] #[cfg_attr(feature="dev", allow(redundant_closure))] fn from_pending_block(&self, latest_block_number: BlockNumber, from_chain: F, map_block: G) -> H - where F: Fn() -> H, G: Fn(&ClosedBlock) -> H { + where F: Fn() -> H, G: FnOnce(&ClosedBlock) -> H { let sealing_work = self.sealing_work.lock(); sealing_work.queue.peek_last_ref().map_or_else( || from_chain(), @@ -712,84 +732,6 @@ impl MinerService for Miner { } } - fn call(&self, client: &MiningBlockChainClient, t: &SignedTransaction, analytics: CallAnalytics) -> Result { - let sealing_work = self.sealing_work.lock(); - match sealing_work.queue.peek_last_ref() { - Some(work) => { - let block = work.block(); - - // TODO: merge this code with client.rs's fn call somwhow. - let header = block.header(); - let last_hashes = Arc::new(client.last_hashes()); - let env_info = EnvInfo { - number: header.number(), - author: *header.author(), - timestamp: header.timestamp(), - difficulty: *header.difficulty(), - last_hashes: last_hashes, - gas_used: U256::zero(), - gas_limit: U256::max_value(), - }; - // that's just a copy of the state. - let mut state = block.state().clone(); - let original_state = if analytics.state_diffing { Some(state.clone()) } else { None }; - - let sender = t.sender(); - let balance = state.balance(&sender).map_err(ExecutionError::from)?; - let needed_balance = t.value + t.gas * t.gas_price; - if balance < needed_balance { - // give the sender a sufficient balance - state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty) - .map_err(ExecutionError::from)?; - } - let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false }; - let mut ret = Executive::new(&mut state, &env_info, &*self.engine).transact(t, options)?; - - // TODO gav move this into Executive. - if let Some(original) = original_state { - ret.state_diff = Some(state.diff_from(original).map_err(ExecutionError::from)?); - } - - Ok(ret) - }, - None => client.call(t, BlockId::Latest, analytics) - } - } - - // TODO: The `chain.latest_x` actually aren't infallible, they just panic on corruption. - // TODO: return trie::Result here, or other. - fn balance(&self, chain: &MiningBlockChainClient, address: &Address) -> Option { - self.from_pending_block( - chain.chain_info().best_block_number, - || Some(chain.latest_balance(address)), - |b| b.block().fields().state.balance(address).ok(), - ) - } - - fn storage_at(&self, chain: &MiningBlockChainClient, address: &Address, position: &H256) -> Option { - self.from_pending_block( - chain.chain_info().best_block_number, - || Some(chain.latest_storage_at(address, position)), - |b| b.block().fields().state.storage_at(address, position).ok(), - ) - } - - fn nonce(&self, chain: &MiningBlockChainClient, address: &Address) -> Option { - self.from_pending_block( - chain.chain_info().best_block_number, - || Some(chain.latest_nonce(address)), - |b| b.block().fields().state.nonce(address).ok(), - ) - } - - fn code(&self, chain: &MiningBlockChainClient, address: &Address) -> Option> { - self.from_pending_block( - chain.chain_info().best_block_number, - || Some(chain.latest_code(address)), - |b| b.block().fields().state.code(address).ok().map(|c| c.map(|c| (&*c).clone())) - ) - } - fn set_author(&self, author: Address) { if self.engine.seals_internally().is_some() { let mut sealing_work = self.sealing_work.lock(); @@ -1109,6 +1051,8 @@ impl MinerService for Miner { /// Prepare the block and work if the Engine does not seal internally. fn update_sealing(&self, chain: &MiningBlockChainClient) { trace!(target: "miner", "update_sealing"); + const NO_NEW_CHAIN_WITH_FORKS: &str = "Your chain specification contains one or more hard forks which are required to be \ + on by default. Please remove these forks and start your chain again."; if self.requires_reseal(chain.chain_info().best_block_number) { // -------------------------------------------------------------------------- @@ -1117,6 +1061,14 @@ impl MinerService for Miner { // -------------------------------------------------------------------------- trace!(target: "miner", "update_sealing: preparing a block"); let (block, original_work_hash) = self.prepare_block(chain); + + // refuse to seal the first block of the chain if it contains hard forks + // which should be on by default. + if block.block().fields().header.number() == 1 && self.engine.params().contains_bugfix_hard_fork() { + warn!("{}", NO_NEW_CHAIN_WITH_FORKS); + return; + } + match self.engine.seals_internally() { Some(true) => { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); @@ -1124,11 +1076,11 @@ impl MinerService for Miner { trace!(target: "miner", "update_sealing: imported internally sealed block"); } }, + Some(false) => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now"), None => { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); self.prepare_work(block, original_work_hash) }, - _ => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now") } } } @@ -1451,14 +1403,14 @@ mod tests { miner.update_sealing(&*client); client.flush_queue(); - assert!(miner.pending_block().is_none()); + assert!(miner.pending_block(0).is_none()); assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber); assert_eq!(miner.import_own_transaction(&*client, PendingTransaction::new(transaction_with_network_id(spec.network_id()).into(), None)).unwrap(), TransactionImportResult::Current); miner.update_sealing(&*client); client.flush_queue(); - assert!(miner.pending_block().is_none()); + assert!(miner.pending_block(0).is_none()); assert_eq!(client.chain_info().best_block_number, 4 as BlockNumber); } diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 78c16ab88..b4cb065fd 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -45,7 +45,6 @@ mod banning_queue; mod external; mod local_transactions; mod miner; -mod price_info; mod service_transaction_checker; mod transaction_queue; mod work_notify; @@ -63,12 +62,12 @@ pub use self::stratum::{Stratum, Error as StratumError, Options as StratumOption use std::collections::BTreeMap; use util::{H256, U256, Address, Bytes}; -use client::{MiningBlockChainClient, Executed, CallAnalytics}; +use client::{MiningBlockChainClient}; use block::ClosedBlock; use header::BlockNumber; use receipt::{RichReceipt, Receipt}; -use error::{Error, CallError}; -use transaction::{UnverifiedTransaction, PendingTransaction, SignedTransaction}; +use error::{Error}; +use transaction::{UnverifiedTransaction, PendingTransaction}; /// Miner client API pub trait MinerService : Send + Sync { @@ -186,21 +185,6 @@ pub trait MinerService : Send + Sync { /// Suggested gas limit. fn sensible_gas_limit(&self) -> U256 { 21000.into() } - - /// Latest account balance in pending state. - fn balance(&self, chain: &MiningBlockChainClient, address: &Address) -> Option; - - /// Call into contract code using pending state. - fn call(&self, chain: &MiningBlockChainClient, t: &SignedTransaction, analytics: CallAnalytics) -> Result; - - /// Get storage value in pending state. - fn storage_at(&self, chain: &MiningBlockChainClient, address: &Address, position: &H256) -> Option; - - /// Get account nonce in pending state. - fn nonce(&self, chain: &MiningBlockChainClient, address: &Address) -> Option; - - /// Get contract code in pending state. - fn code(&self, chain: &MiningBlockChainClient, address: &Address) -> Option>; } /// Mining status diff --git a/ethcore/src/miner/price_info.rs b/ethcore/src/miner/price_info.rs deleted file mode 100644 index 29994afb4..000000000 --- a/ethcore/src/miner/price_info.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use rustc_serialize::json::Json; -use std::thread; -use std::io::Read; -use std::time::Duration; -use std::str::FromStr; -use std::sync::mpsc; -use hyper::client::{Handler, Request, Response, Client}; -use hyper::{Url, Next, Encoder, Decoder}; -use hyper::net::HttpStream; - -#[derive(Debug)] -pub struct PriceInfo { - pub ethusd: f32, -} - -pub struct SetPriceHandler { - set_price: F, - channel: mpsc::Sender<()>, -} - -impl Drop for SetPriceHandler { - fn drop(&mut self) { - let _ = self.channel.send(()); - } -} - -impl Handler for SetPriceHandler { - fn on_request(&mut self, _: &mut Request) -> Next { Next::read().timeout(Duration::from_secs(3)) } - fn on_request_writable(&mut self, _: &mut Encoder) -> Next { Next::read().timeout(Duration::from_secs(3)) } - fn on_response(&mut self, _: Response) -> Next { Next::read().timeout(Duration::from_secs(3)) } - - fn on_response_readable(&mut self, r: &mut Decoder) -> Next { - let mut body = String::new(); - let info = r.read_to_string(&mut body) - .map_err(|e| format!("Unable to read response: {:?}", e)) - .and_then(|_| self.process_response(&body)); - - if let Err(e) = info { - warn!("Failed to auto-update latest ETH price: {:?}", e); - } - Next::end() - } -} - -impl SetPriceHandler { - fn process_response(&self, body: &str) -> Result<(), String> { - let json = Json::from_str(body).map_err(|e| format!("Invalid JSON returned: {:?}", e))?; - let obj = json.find_path(&["result", "ethusd"]).ok_or("USD price not found".to_owned())?; - let ethusd = match *obj { - Json::String(ref s) => FromStr::from_str(s).ok(), - _ => None, - }.ok_or("Unexpected price format.".to_owned())?; - - (self.set_price)(PriceInfo { - ethusd: ethusd, - }); - Ok(()) - } -} - -impl PriceInfo { - pub fn get(set_price: F) { - thread::spawn(move || { - let url = FromStr::from_str("http://api.etherscan.io/api?module=stats&action=ethprice") - .expect("string known to be a valid URL; qed"); - - if let Err(e) = Self::request(url, set_price) { - warn!("Failed to auto-update latest ETH price: {:?}", e); - } - }); - } - - fn request(url: Url, set_price: F) -> Result<(), String> { - let (tx, rx) = mpsc::channel(); - let client = Client::new().map_err(|e| format!("Unable to start client: {:?}", e))?; - - client.request( - url, - SetPriceHandler { - set_price: set_price, - channel: tx, - }, - ).map_err(|_| "Request failed.".to_owned())?; - - // Wait for exit - let _ = rx.recv().map_err(|e| format!("Request interrupted: {:?}", e))?; - client.close(); - - Ok(()) - } -} - -#[test] #[ignore] -fn should_get_price_info() { - use std::sync::Arc; - use std::time::Duration; - use ethcore_logger::init_log; - use util::{Condvar, Mutex}; - - init_log(); - let done = Arc::new((Mutex::new(PriceInfo { ethusd: 0f32 }), Condvar::new())); - let rdone = done.clone(); - - PriceInfo::get(move |price| { let mut p = rdone.0.lock(); *p = price; rdone.1.notify_one(); }); - let mut p = done.0.lock(); - let t = done.1.wait_for(&mut p, Duration::from_millis(10000)); - assert!(!t.timed_out()); - assert!(p.ethusd != 0f32); -} diff --git a/ethcore/src/miner/stratum.rs b/ethcore/src/miner/stratum.rs index e419247f0..0031bb715 100644 --- a/ethcore/src/miner/stratum.rs +++ b/ethcore/src/miner/stratum.rs @@ -32,7 +32,6 @@ use util::Mutex; use miner::{self, Miner, MinerService}; use client::Client; use block::IsBlock; -use std::str::FromStr; use rlp::encode; /// Configures stratum server options. @@ -60,7 +59,7 @@ impl SubmitPayload { return Err(PayloadError::ArgumentsAmountUnexpected(payload.len())); } - let nonce = match H64::from_str(clean_0x(&payload[0])) { + let nonce = match clean_0x(&payload[0]).parse::() { Ok(nonce) => nonce, Err(e) => { warn!(target: "stratum", "submit_work ({}): invalid nonce ({:?})", &payload[0], e); @@ -68,7 +67,7 @@ impl SubmitPayload { } }; - let pow_hash = match H256::from_str(clean_0x(&payload[1])) { + let pow_hash = match clean_0x(&payload[1]).parse::() { Ok(pow_hash) => pow_hash, Err(e) => { warn!(target: "stratum", "submit_work ({}): invalid hash ({:?})", &payload[1], e); @@ -76,7 +75,7 @@ impl SubmitPayload { } }; - let mix_hash = match H256::from_str(clean_0x(&payload[2])) { + let mix_hash = match clean_0x(&payload[2]).parse::() { Ok(mix_hash) => mix_hash, Err(e) => { warn!(target: "stratum", "submit_work ({}): invalid mix-hash ({:?})", &payload[2], e); @@ -133,7 +132,7 @@ impl JobDispatcher for StratumJobDispatcher { fn submit(&self, payload: Vec) -> Result<(), StratumServiceError> { let payload = SubmitPayload::from_args(payload).map_err(|e| - StratumServiceError::Dispatch(format!("{}", e)) + StratumServiceError::Dispatch(e.to_string()) )?; trace!( @@ -144,14 +143,16 @@ impl JobDispatcher for StratumJobDispatcher { payload.mix_hash, ); - self.with_core_void(|client, miner| { + self.with_core_result(|client, miner| { let seal = vec![encode(&payload.mix_hash).into_vec(), encode(&payload.nonce).into_vec()]; - if let Err(e) = miner.submit_seal(&*client, payload.pow_hash, seal) { - warn!(target: "stratum", "submit_seal error: {:?}", e); - }; - }); - - Ok(()) + match miner.submit_seal(&*client, payload.pow_hash, seal) { + Ok(_) => Ok(()), + Err(e) => { + warn!(target: "stratum", "submit_seal error: {:?}", e); + Err(StratumServiceError::Dispatch(e.to_string())) + } + } + }) } } @@ -181,8 +182,11 @@ impl StratumJobDispatcher { self.client.upgrade().and_then(|client| self.miner.upgrade().and_then(|miner| (f)(client, miner))) } - fn with_core_void(&self, f: F) where F: Fn(Arc, Arc) { - self.client.upgrade().map(|client| self.miner.upgrade().map(|miner| (f)(client, miner))); + fn with_core_result(&self, f: F) -> Result<(), StratumServiceError> where F: Fn(Arc, Arc) -> Result<(), StratumServiceError> { + match (self.client.upgrade(), self.miner.upgrade()) { + (Some(client), Some(miner)) => f(client, miner), + _ => Ok(()), + } } } @@ -230,7 +234,7 @@ impl Stratum { let dispatcher = Arc::new(StratumJobDispatcher::new(miner, client)); let stratum_svc = StratumService::start( - &SocketAddr::new(IpAddr::from_str(&options.listen_addr)?, options.port), + &SocketAddr::new(options.listen_addr.parse::()?, options.port), dispatcher.clone(), options.secret.clone(), )?; diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 542b42b93..263143ee8 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -106,7 +106,7 @@ use std::cmp; use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap}; use linked_hash_map::LinkedHashMap; use util::{Address, H256, U256, HeapSizeOf}; -use util::table::Table; +use table::Table; use transaction::*; use error::{Error, TransactionError}; use client::TransactionImportResult; @@ -1447,7 +1447,7 @@ fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option. +use std::fmt; +use std::collections::BTreeMap; use util::*; use state::Account; use ethjson; @@ -166,7 +168,7 @@ pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option StateDiff { #[cfg(test)] mod test { - use util::*; + use std::collections::BTreeMap; use types::state_diff::*; use types::account_diff::*; use pod_account::PodAccount; diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index e4c3d7519..5e65a4de8 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -16,6 +16,8 @@ //! Creates and registers client and network services. +use std::sync::Arc; +use std::path::Path; use util::*; use io::*; use spec::Spec; diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index fd4c2cc1e..47bbb5997 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -46,6 +46,9 @@ struct Guard(bool, PathBuf); impl Guard { fn new(path: PathBuf) -> Self { Guard(true, path) } + #[cfg(test)] + fn benign() -> Self { Guard(false, PathBuf::default()) } + fn disarm(mut self) { self.0 = false } } @@ -123,7 +126,7 @@ impl Restoration { // feeds a state chunk, aborts early if `flag` becomes false. fn feed_state(&mut self, hash: H256, chunk: &[u8], flag: &AtomicBool) -> Result<(), Error> { - if self.state_chunks_left.remove(&hash) { + if self.state_chunks_left.contains(&hash) { let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?; self.state.feed(&self.snappy_buffer[..len], flag)?; @@ -131,6 +134,8 @@ impl Restoration { if let Some(ref mut writer) = self.writer.as_mut() { writer.write_state_chunk(hash, chunk)?; } + + self.state_chunks_left.remove(&hash); } Ok(()) @@ -138,13 +143,15 @@ impl Restoration { // feeds a block chunk fn feed_blocks(&mut self, hash: H256, chunk: &[u8], engine: &Engine, flag: &AtomicBool) -> Result<(), Error> { - if self.block_chunks_left.remove(&hash) { + if self.block_chunks_left.contains(&hash) { let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?; self.secondary.feed(&self.snappy_buffer[..len], engine, flag)?; if let Some(ref mut writer) = self.writer.as_mut() { writer.write_block_chunk(hash, chunk)?; } + + self.block_chunks_left.remove(&hash); } Ok(()) @@ -558,9 +565,9 @@ impl SnapshotService for Service { self.reader.read().as_ref().map(|r| r.manifest().clone()) } - fn min_supported_version(&self) -> Option { + fn supported_versions(&self) -> Option<(u64, u64)> { self.engine.snapshot_components() - .map(|c| c.min_supported_version()) + .map(|c| (c.min_supported_version(), c.current_version())) } fn chunk(&self, hash: H256) -> Option { @@ -668,4 +675,50 @@ mod tests { service.restore_state_chunk(Default::default(), vec![]); service.restore_block_chunk(Default::default(), vec![]); } + + #[test] + fn cannot_finish_with_invalid_chunks() { + use util::H256; + use util::kvdb::DatabaseConfig; + + let spec = get_test_spec(); + let dir = RandomTempPath::new(); + + let state_hashes: Vec<_> = (0..5).map(|_| H256::random()).collect(); + let block_hashes: Vec<_> = (0..5).map(|_| H256::random()).collect(); + let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); + let gb = spec.genesis_block(); + let flag = ::std::sync::atomic::AtomicBool::new(true); + + let params = RestorationParams { + manifest: ManifestData { + version: 2, + state_hashes: state_hashes.clone(), + block_hashes: block_hashes.clone(), + state_root: H256::default(), + block_number: 100000, + block_hash: H256::default(), + }, + pruning: Algorithm::Archive, + db_path: dir.as_path().to_owned(), + db_config: &db_config, + writer: None, + genesis: &gb, + guard: Guard::benign(), + engine: &*spec.engine.clone(), + }; + + let mut restoration = Restoration::new(params).unwrap(); + let definitely_bad_chunk = [1, 2, 3, 4, 5]; + + for hash in state_hashes { + assert!(restoration.feed_state(hash, &definitely_bad_chunk, &flag).is_err()); + assert!(!restoration.is_done()); + } + + for hash in block_hashes { + assert!(restoration.feed_blocks(hash, &definitely_bad_chunk, &*spec.engine, &flag).is_err()); + assert!(!restoration.is_done()); + } + } } diff --git a/ethcore/src/snapshot/snapshot_service_trait.rs b/ethcore/src/snapshot/snapshot_service_trait.rs index e57b39da1..9df366250 100644 --- a/ethcore/src/snapshot/snapshot_service_trait.rs +++ b/ethcore/src/snapshot/snapshot_service_trait.rs @@ -27,9 +27,9 @@ pub trait SnapshotService : Sync + Send { /// Query the most recent manifest data. fn manifest(&self) -> Option; - /// Get the minimum supported snapshot version number. + /// Get the supported range of snapshot version numbers. /// `None` indicates warp sync isn't supported by the consensus engine. - fn min_supported_version(&self) -> Option; + fn supported_versions(&self) -> Option<(u64, u64)>; /// Get raw chunk for a given hash. fn chunk(&self, hash: H256) -> Option; diff --git a/ethcore/src/snapshot/tests/test_validator_contract.json b/ethcore/src/snapshot/tests/test_validator_contract.json index e2485fe82..b0aeb8785 100644 --- a/ethcore/src/snapshot/tests/test_validator_contract.json +++ b/ethcore/src/snapshot/tests/test_validator_contract.json @@ -3,7 +3,6 @@ "engine": { "authorityRound": { "params": { - "gasLimitBoundDivisor": "0x0400", "stepDuration": 1, "startStep": 0, "validators": { @@ -17,6 +16,7 @@ } }, "params": { + "gasLimitBoundDivisor": "0x0400", "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 40893ad6d..395f8ef9c 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -16,14 +16,17 @@ //! Parameters for a block chain. +use std::io::Read; +use std::collections::BTreeMap; +use std::path::Path; +use std::sync::Arc; use rustc_hex::FromHex; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; -use evm::action_params::{ActionValue, ActionParams}; use builtin::Builtin; use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT}; -use evm::env_info::EnvInfo; +use vm::{EnvInfo, CallType, ActionValue, ActionParams}; use error::Error; use ethereum; use ethjson; @@ -36,10 +39,14 @@ use state_db::StateDB; use state::{Backend, State, Substate}; use state::backend::Basic as BasicBackend; use trace::{NoopTracer, NoopVMTracer}; -use evm::CallType; use util::*; -/// Parameters common to all engines. +/// Parameters common to ethereum-like blockchains. +/// NOTE: when adding bugfix hard-fork parameters, +/// add to `contains_bugfix_hard_fork` +/// +/// we define a "bugfix" hard fork as any hard fork which +/// you would put on-by-default in a new chain. #[derive(Debug, PartialEq, Default)] #[cfg_attr(test, derive(Clone))] pub struct CommonParams { @@ -59,8 +66,10 @@ pub struct CommonParams { pub fork_block: Option<(BlockNumber, H256)>, /// Number of first block where EIP-98 rules begin. pub eip98_transition: BlockNumber, + /// Number of first block where EIP-155 rules begin. + pub eip155_transition: BlockNumber, /// Validate block receipts root. - pub validate_receipts_transition: u64, + pub validate_receipts_transition: BlockNumber, /// Number of first block where EIP-86 (Metropolis) rules begin. pub eip86_transition: BlockNumber, /// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin. @@ -85,31 +94,51 @@ pub struct CommonParams { pub remove_dust_contracts: bool, /// Wasm support pub wasm: bool, + /// Gas limit bound divisor (how much gas limit can change per block) + pub gas_limit_bound_divisor: U256, + /// Block reward in wei. + pub block_reward: U256, + /// Registrar contract address. + pub registrar: Address, } impl CommonParams { /// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net. - pub fn schedule(&self, block_number: u64) -> ::evm::Schedule { - let mut schedule = ::evm::Schedule::new_post_eip150(usize::max_value(), true, true, true); + pub fn schedule(&self, block_number: u64) -> ::vm::Schedule { + let mut schedule = ::vm::Schedule::new_post_eip150(usize::max_value(), true, true, true); self.update_schedule(block_number, &mut schedule); schedule } /// Apply common spec config parameters to the schedule. - pub fn update_schedule(&self, block_number: u64, schedule: &mut ::evm::Schedule) { + pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) { schedule.have_create2 = block_number >= self.eip86_transition; schedule.have_revert = block_number >= self.eip140_transition; schedule.have_static_call = block_number >= self.eip214_transition; + schedule.have_return_data = block_number >= self.eip211_transition; if block_number >= self.eip210_transition { schedule.blockhash_gas = 350; } if block_number >= self.dust_protection_transition { schedule.kill_dust = match self.remove_dust_contracts { - true => ::evm::CleanDustMode::WithCodeAndStorage, - false => ::evm::CleanDustMode::BasicOnly, + true => ::vm::CleanDustMode::WithCodeAndStorage, + false => ::vm::CleanDustMode::BasicOnly, }; } } + + /// Whether these params contain any bug-fix hard forks. + pub fn contains_bugfix_hard_fork(&self) -> bool { + self.eip98_transition != 0 && + self.eip155_transition != 0 && + self.validate_receipts_transition != 0 && + self.eip86_transition != 0 && + self.eip140_transition != 0 && + self.eip210_transition != 0 && + self.eip211_transition != 0 && + self.eip214_transition != 0 && + self.dust_protection_transition != 0 + } } impl From for CommonParams { @@ -123,6 +152,7 @@ impl From for CommonParams { min_gas_limit: p.min_gas_limit.into(), fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, eip98_transition: p.eip98_transition.map_or(0, Into::into), + eip155_transition: p.eip155_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), eip86_transition: p.eip86_transition.map_or(BlockNumber::max_value(), Into::into), eip140_transition: p.eip140_transition.map_or(BlockNumber::max_value(), Into::into), @@ -138,6 +168,9 @@ impl From for CommonParams { nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), wasm: p.wasm.unwrap_or(false), + gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), + block_reward: p.block_reward.map_or_else(U256::zero, Into::into), + registrar: p.registrar.map_or_else(Address::new, Into::into), } } } @@ -241,7 +274,7 @@ impl Spec { ) -> Arc { match engine_spec { ethjson::spec::Engine::Null => Arc::new(NullEngine::new(params, builtins)), - ethjson::spec::Engine::InstantSeal(instant) => Arc::new(InstantSeal::new(params, instant.params.registrar.map_or_else(Address::new, Into::into), builtins)), + ethjson::spec::Engine::InstantSeal => Arc::new(InstantSeal::new(params, builtins)), ethjson::spec::Engine::Ethash(ethash) => Arc::new(ethereum::Ethash::new(cache_dir, params, From::from(ethash.params), builtins)), ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(params, From::from(basic_authority.params), builtins)), ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(params, From::from(authority_round.params), builtins).expect("Failed to start AuthorityRound consensus engine."), @@ -483,6 +516,7 @@ impl Spec { #[cfg(test)] mod tests { + use std::str::FromStr; use util::*; use views::*; use tests::helpers::get_temp_state_db; @@ -495,19 +529,6 @@ mod tests { assert!(Spec::load(::std::env::temp_dir(), &[] as &[u8]).is_err()); } - #[test] - fn all_spec_files_valid() { - Spec::new_test(); - Spec::new_null(); - Spec::new_test_constructor(); - Spec::new_instant(); - Spec::new_test_round(); - Spec::new_test_tendermint(); - Spec::new_validator_safe_contract(); - Spec::new_validator_contract(); - Spec::new_validator_multi(); - } - #[test] fn test_chain() { let test_spec = Spec::new_test(); diff --git a/ethcore/src/state/account.rs b/ethcore/src/state/account.rs index 9e58f2ec0..1235fd289 100644 --- a/ethcore/src/state/account.rs +++ b/ethcore/src/state/account.rs @@ -16,6 +16,9 @@ //! Single account in the system. +use std::fmt; +use std::sync::Arc; +use std::collections::HashMap; use util::*; use pod_account::*; use rlp::*; diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index 354da2cc3..ad884d91b 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -21,10 +21,13 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; +use std::collections::{HashMap, BTreeMap, HashSet}; +use std::fmt; +use std::sync::Arc; use receipt::Receipt; use engines::Engine; -use evm::env_info::EnvInfo; +use vm::EnvInfo; use error::Error; use executive::{Executive, TransactOptions}; use factory::Factories; @@ -982,7 +985,7 @@ mod tests { use ethkey::Secret; use util::{U256, H256, Address, Hashable}; use tests::helpers::*; - use evm::env_info::EnvInfo; + use vm::EnvInfo; use spec::*; use transaction::*; use ethcore_logger::init_log; diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index de5a3f75b..e2f6fdaf0 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . use std::collections::{VecDeque, HashSet}; +use std::sync::Arc; use lru_cache::LruCache; use util::cache::MemoryLruCache; use util::journaldb::JournalDB; @@ -23,7 +24,7 @@ use util::hash::{H256}; use util::hashdb::HashDB; use state::{self, Account}; use header::BlockNumber; -use util::{Arc, Address, DBTransaction, UtilError, Mutex, Hashable}; +use util::{Address, DBTransaction, UtilError, Mutex, Hashable}; use bloom_journal::{Bloom, BloomJournal}; use db::COL_ACCOUNT_BLOOM; use byteorder::{LittleEndian, ByteOrder}; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 3b32f9094..639fce3ab 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::str::FromStr; +use std::sync::Arc; use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockId}; use state::{self, State, CleanupMode}; diff --git a/ethcore/src/tests/evm.rs b/ethcore/src/tests/evm.rs index c97fd4ac0..7b0e03d24 100644 --- a/ethcore/src/tests/evm.rs +++ b/ethcore/src/tests/evm.rs @@ -1,9 +1,8 @@ //! Tests of EVM integration with transaction execution. -use evm::action_params::{ActionParams, ActionValue}; -use evm::env_info::EnvInfo; +use std::sync::Arc; +use vm::{EnvInfo, ActionParams, ActionValue, CallType}; use evm::{Factory, VMType}; -use evm::call_type::CallType; use executive::Executive; use state::Substate; use tests::helpers::*; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index f8e412073..5d05e66f5 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::collections::BTreeMap; +use std::sync::Arc; use ethkey::KeyPair; use io::*; use client::{BlockChainClient, Client, ClientConfig}; @@ -347,7 +349,7 @@ pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_h for i in start_number .. start_number + count + 1 { let mut block_header = Header::new(); block_header.set_gas_limit(test_engine.params().min_gas_limit); - block_header.set_difficulty(U256::from(i).mul(U256([0, 1, 0, 0]))); + block_header.set_difficulty(U256::from(i) * U256([0, 1, 0, 0])); block_header.set_timestamp(rolling_timestamp); block_header.set_number(i as u64); block_header.set_parent_hash(parent); @@ -394,16 +396,13 @@ pub fn get_bad_state_dummy_block() -> Bytes { create_test_block(&block_header) } -pub fn get_default_ethash_params() -> EthashParams{ +pub fn get_default_ethash_params() -> EthashParams { EthashParams { - gas_limit_bound_divisor: U256::from(1024), minimum_difficulty: U256::from(131072), difficulty_bound_divisor: U256::from(2048), difficulty_increment_divisor: 10, metropolis_difficulty_increment_divisor: 9, duration_limit: 13, - block_reward: U256::from(0), - registrar: "0000000000000000000000000000000000000001".into(), homestead_transition: 1150000, dao_hardfork_transition: u64::max_value(), dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(), @@ -413,7 +412,6 @@ pub fn get_default_ethash_params() -> EthashParams{ bomb_defuse_transition: u64::max_value(), eip100b_transition: u64::max_value(), eip150_transition: u64::max_value(), - eip155_transition: u64::max_value(), eip160_transition: u64::max_value(), eip161abc_transition: u64::max_value(), eip161d_transition: u64::max_value(), diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index cdfe1e004..860c74223 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -17,7 +17,7 @@ //! Simple executive tracer. use util::{Bytes, Address, U256}; -use evm::action_params::ActionParams; +use vm::ActionParams; use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide}; use trace::{Tracer, VMTracer, FlatTrace, TraceError}; diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index 39af8a08a..be830430b 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -39,7 +39,7 @@ pub use self::types::filter::{Filter, AddressesFilter}; use util::{Bytes, Address, U256, H256, DBTransaction}; use self::trace::{Call, Create}; -use evm::action_params::ActionParams; +use vm::ActionParams; use header::BlockNumber; /// This trait is used by executive to build traces. diff --git a/ethcore/src/trace/noop_tracer.rs b/ethcore/src/trace/noop_tracer.rs index 5fb8a7c55..2c0e1b830 100644 --- a/ethcore/src/trace/noop_tracer.rs +++ b/ethcore/src/trace/noop_tracer.rs @@ -17,7 +17,7 @@ //! Nonoperative tracer. use util::{Bytes, Address, U256}; -use evm::action_params::ActionParams; +use vm::ActionParams; use trace::{Tracer, VMTracer, FlatTrace, TraceError}; use trace::trace::{Call, Create, VMTrace}; diff --git a/ethcore/src/trace/types/error.rs b/ethcore/src/trace/types/error.rs index 4242bfad4..5cedefd09 100644 --- a/ethcore/src/trace/types/error.rs +++ b/ethcore/src/trace/types/error.rs @@ -18,7 +18,7 @@ use std::fmt; use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp}; -use evm::Error as EvmError; +use vm::Error as VmError; /// Trace evm errors. #[derive(Debug, PartialEq, Clone)] @@ -45,24 +45,24 @@ pub enum Error { Wasm, } -impl<'a> From<&'a EvmError> for Error { - fn from(e: &'a EvmError) -> Self { +impl<'a> From<&'a VmError> for Error { + fn from(e: &'a VmError) -> Self { match *e { - EvmError::OutOfGas => Error::OutOfGas, - EvmError::BadJumpDestination { .. } => Error::BadJumpDestination, - EvmError::BadInstruction { .. } => Error::BadInstruction, - EvmError::StackUnderflow { .. } => Error::StackUnderflow, - EvmError::OutOfStack { .. } => Error::OutOfStack, - EvmError::BuiltIn { .. } => Error::BuiltIn, - EvmError::Wasm { .. } => Error::Wasm, - EvmError::Internal(_) => Error::Internal, - EvmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, + VmError::OutOfGas => Error::OutOfGas, + VmError::BadJumpDestination { .. } => Error::BadJumpDestination, + VmError::BadInstruction { .. } => Error::BadInstruction, + VmError::StackUnderflow { .. } => Error::StackUnderflow, + VmError::OutOfStack { .. } => Error::OutOfStack, + VmError::BuiltIn { .. } => Error::BuiltIn, + VmError::Wasm { .. } => Error::Wasm, + VmError::Internal(_) => Error::Internal, + VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, } } } -impl From for Error { - fn from(e: EvmError) -> Self { +impl From for Error { + fn from(e: VmError) -> Self { Error::from(&e) } } diff --git a/ethcore/src/trace/types/filter.rs b/ethcore/src/trace/types/filter.rs index 2dc810442..1b2e2077a 100644 --- a/ethcore/src/trace/types/filter.rs +++ b/ethcore/src/trace/types/filter.rs @@ -20,7 +20,7 @@ use std::ops::Range; use bloomchain::{Filter as BloomFilter, Bloom, Number}; use util::Address; use util::sha3::Hashable; -use util::bloom::Bloomable; +use bloomable::Bloomable; use basic_types::LogBloom; use trace::flat::FlatTrace; use super::trace::{Action, Res}; @@ -137,7 +137,7 @@ impl Filter { mod tests { use util::Address; use util::sha3::Hashable; - use util::bloom::Bloomable; + use bloomable::Bloomable; use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide}; use trace::flat::FlatTrace; use trace::{Filter, AddressesFilter, TraceError}; diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 24250935f..3863a935e 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -18,10 +18,10 @@ use util::{U256, Bytes, Address}; use util::sha3::Hashable; -use util::bloom::Bloomable; +use bloomable::Bloomable; use rlp::*; -use evm::action_params::ActionParams; +use vm::ActionParams; use basic_types::LogBloom; use evm::CallType; use super::error::Error; diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 7e9a70f7c..ce0cb4179 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -19,7 +19,9 @@ use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; -use std::sync::{Condvar as SCondvar, Mutex as SMutex}; +use std::sync::{Condvar as SCondvar, Mutex as SMutex, Arc}; +use std::cmp; +use std::collections::{VecDeque, HashSet, HashMap}; use util::*; use io::*; use error::*; @@ -234,8 +236,8 @@ impl VerificationQueue { let scale_verifiers = config.verifier_settings.scale_verifiers; let num_cpus = ::num_cpus::get(); - let max_verifiers = min(num_cpus, MAX_VERIFIERS); - let default_amount = max(1, min(max_verifiers, config.verifier_settings.num_verifiers)); + let max_verifiers = cmp::min(num_cpus, MAX_VERIFIERS); + let default_amount = cmp::max(1, cmp::min(max_verifiers, config.verifier_settings.num_verifiers)); let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new())); let mut verifier_handles = Vec::with_capacity(max_verifiers); @@ -278,8 +280,8 @@ impl VerificationQueue { processing: RwLock::new(HashMap::new()), empty: empty, ticks_since_adjustment: AtomicUsize::new(0), - max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT), - max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT), + max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT), + max_mem_use: cmp::max(config.max_mem_use, MIN_MEM_LIMIT), scale_verifiers: scale_verifiers, verifier_handles: verifier_handles, state: state, @@ -567,7 +569,7 @@ impl VerificationQueue { /// Removes up to `max` verified items from the queue pub fn drain(&self, max: usize) -> Vec { let mut verified = self.verification.verified.lock(); - let count = min(max, verified.len()); + let count = cmp::min(max, verified.len()); let result = verified.drain(..count).collect::>(); let drained_size = result.iter().map(HeapSizeOf::heap_size_of_children).fold(0, |a, c| a + c); @@ -687,8 +689,8 @@ impl VerificationQueue { // or below 1. fn scale_verifiers(&self, target: usize) { let current = self.num_verifiers(); - let target = min(self.verifier_handles.len(), target); - let target = max(1, target); + let target = cmp::min(self.verifier_handles.len(), target); + let target = cmp::max(1, target); debug!(target: "verification", "Scaling from {} to {} verifiers", current, target); @@ -725,7 +727,6 @@ impl Drop for VerificationQueue { #[cfg(test)] mod tests { - use util::*; use io::*; use spec::*; use super::{BlockQueue, Config, State}; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 823d2ef70..00976dca7 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -21,6 +21,7 @@ //! 2. Signatures verification done in the queue. //! 3. Final verification against the blockchain done before enactment. +use std::collections::HashSet; use util::*; use engines::Engine; use error::{BlockError, Error}; @@ -264,6 +265,7 @@ fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: & #[cfg(test)] mod tests { + use std::collections::{BTreeMap, HashMap}; use util::*; use ethkey::{Random, Generator}; use header::*; diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 2a3ac6a80..77f392bf6 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Parity Technologies "] rlp = { path = "../../util/rlp" } ethcore-util = { path = "../../util" } ethjson = { path = "../../json" } +bloomable = { path = "../../util/bloomable" } [dev-dependencies] rustc-hex= "1.0" diff --git a/ethcore/types/src/block_status.rs b/ethcore/types/src/block_status.rs index 937077795..d330b9ed1 100644 --- a/ethcore/types/src/block_status.rs +++ b/ethcore/types/src/block_status.rs @@ -23,6 +23,8 @@ pub enum BlockStatus { Queued, /// Known as bad. Bad, + /// Pending block. + Pending, /// Unknown. Unknown, } diff --git a/ethcore/types/src/filter.rs b/ethcore/types/src/filter.rs index 6ab53b536..6e344b4ef 100644 --- a/ethcore/types/src/filter.rs +++ b/ethcore/types/src/filter.rs @@ -17,7 +17,7 @@ //! Blockchain filter use util::{Address, H256, Hashable, H2048}; -use util::bloom::Bloomable; +use bloomable::Bloomable; use ids::BlockId; use log_entry::LogEntry; diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 589034066..7650cf651 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -19,6 +19,7 @@ extern crate ethcore_util as util; extern crate ethjson; extern crate rlp; +extern crate bloomable; #[cfg(test)] extern crate rustc_hex; diff --git a/ethcore/types/src/log_entry.rs b/ethcore/types/src/log_entry.rs index 724e6a7dc..f917a4dab 100644 --- a/ethcore/types/src/log_entry.rs +++ b/ethcore/types/src/log_entry.rs @@ -18,7 +18,7 @@ use std::ops::Deref; use util::{H256, Address, Bytes, HeapSizeOf, Hashable}; -use util::bloom::Bloomable; +use bloomable::Bloomable; use rlp::*; use {BlockNumber}; @@ -114,8 +114,8 @@ mod tests { #[test] fn test_empty_log_bloom() { - let bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let bloom = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap(); + let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse::
().unwrap(); let log = LogEntry { address: address, topics: vec![], diff --git a/ethcore/vm/Cargo.toml b/ethcore/vm/Cargo.toml new file mode 100644 index 000000000..50efe936c --- /dev/null +++ b/ethcore/vm/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "vm" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +byteorder = "1.0" +ethcore-util = { path = "../../util" } +log = "0.3" +common-types = { path = "../types" } +evmjit = { path = "../../evmjit", optional = true } +ethjson = { path = "../../json" } +lazy_static = "0.2" +rlp = { path = "../../util/rlp" } \ No newline at end of file diff --git a/ethcore/evm/src/action_params.rs b/ethcore/vm/src/action_params.rs similarity index 98% rename from ethcore/evm/src/action_params.rs rename to ethcore/vm/src/action_params.rs index 62bb7fa5b..401d7ee57 100644 --- a/ethcore/evm/src/action_params.rs +++ b/ethcore/vm/src/action_params.rs @@ -20,7 +20,7 @@ use util::hash::{H256}; use util::sha3::{Hashable, SHA3_EMPTY}; use ethjson; -use {CallType}; +use call_type::CallType; use std::sync::Arc; @@ -48,7 +48,7 @@ impl ActionValue { /// Returns the apparent action value of the U256-convertable raw value pub fn apparent>(apparent_value: T) -> ActionValue { - ActionValue::Apparent(apparent_value.into()) + ActionValue::Apparent(apparent_value.into()) } } diff --git a/ethcore/evm/src/call_type.rs b/ethcore/vm/src/call_type.rs similarity index 100% rename from ethcore/evm/src/call_type.rs rename to ethcore/vm/src/call_type.rs diff --git a/ethcore/evm/src/env_info.rs b/ethcore/vm/src/env_info.rs similarity index 100% rename from ethcore/evm/src/env_info.rs rename to ethcore/vm/src/env_info.rs diff --git a/ethcore/vm/src/error.rs b/ethcore/vm/src/error.rs new file mode 100644 index 000000000..e4b199438 --- /dev/null +++ b/ethcore/vm/src/error.rs @@ -0,0 +1,100 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! VM errors module + +use util::trie; +use std::fmt; + +/// VM errors. +#[derive(Debug, Clone, PartialEq)] +pub enum Error { + /// `OutOfGas` is returned when transaction execution runs out of gas. + /// The state should be reverted to the state from before the + /// transaction execution. But it does not mean that transaction + /// was invalid. Balance still should be transfered and nonce + /// should be increased. + OutOfGas, + /// `BadJumpDestination` is returned when execution tried to move + /// to position that wasn't marked with JUMPDEST instruction + BadJumpDestination { + /// Position the code tried to jump to. + destination: usize + }, + /// `BadInstructions` is returned when given instruction is not supported + BadInstruction { + /// Unrecognized opcode + instruction: u8, + }, + /// `StackUnderflow` when there is not enough stack elements to execute instruction + StackUnderflow { + /// Invoked instruction + instruction: &'static str, + /// How many stack elements was requested by instruction + wanted: usize, + /// How many elements were on stack + on_stack: usize + }, + /// When execution would exceed defined Stack Limit + OutOfStack { + /// Invoked instruction + instruction: &'static str, + /// How many stack elements instruction wanted to push + wanted: usize, + /// What was the stack limit + limit: usize + }, + /// Built-in contract failed on given input + BuiltIn(&'static str), + /// When execution tries to modify the state in static context + MutableCallInStaticContext, + /// Likely to cause consensus issues. + Internal(String), + /// Wasm runtime error + Wasm(String), +} + + +impl From> for Error { + fn from(err: Box) -> Self { + Error::Internal(format!("Internal error: {}", err)) + } +} + +// impl From for Error { +// fn from(err: wasm::RuntimeError) -> Self { +// Error::Wasm(format!("Runtime error: {:?}", err)) +// } +// } + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::Error::*; + match *self { + OutOfGas => write!(f, "Out of gas"), + BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination), + BadInstruction { instruction } => write!(f, "Bad instruction {:x}", instruction), + StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack), + OutOfStack { instruction, wanted, limit } => write!(f, "Out of stack {} {}/{}", instruction, wanted, limit), + BuiltIn(name) => write!(f, "Built-in failed: {}", name), + Internal(ref msg) => write!(f, "Internal error: {}", msg), + MutableCallInStaticContext => write!(f, "Mutable call in static context"), + Wasm(ref msg) => write!(f, "Internal error: {}", msg), + } + } +} + +pub type Result = ::std::result::Result; diff --git a/ethcore/evm/src/ext.rs b/ethcore/vm/src/ext.rs similarity index 85% rename from ethcore/evm/src/ext.rs rename to ethcore/vm/src/ext.rs index 1c3ddb317..54871e511 100644 --- a/ethcore/evm/src/ext.rs +++ b/ethcore/vm/src/ext.rs @@ -16,11 +16,13 @@ //! Interface for Evm externalities. +use std::sync::Arc; use util::*; use call_type::CallType; use env_info::EnvInfo; use schedule::Schedule; -use evm::{self, ReturnData}; +use return_data::ReturnData; +use error::Result; /// Result of externalities create function. pub enum ContractCreateResult { @@ -56,22 +58,22 @@ pub enum CreateContractAddress { /// Externalities interface for EVMs pub trait Ext { /// Returns a value for given key. - fn storage_at(&self, key: &H256) -> evm::Result; + fn storage_at(&self, key: &H256) -> Result; /// Stores a value for given key. - fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()>; + fn set_storage(&mut self, key: H256, value: H256) -> Result<()>; /// Determine whether an account exists. - fn exists(&self, address: &Address) -> evm::Result; + fn exists(&self, address: &Address) -> Result; /// Determine whether an account exists and is not null (zero balance/nonce, no code). - fn exists_and_not_null(&self, address: &Address) -> evm::Result; + fn exists_and_not_null(&self, address: &Address) -> Result; /// Balance of the origin account. - fn origin_balance(&self) -> evm::Result; + fn origin_balance(&self) -> Result; /// Returns address balance. - fn balance(&self, address: &Address) -> evm::Result; + fn balance(&self, address: &Address) -> Result; /// Returns the hash of one of the 256 most recent complete blocks. fn blockhash(&mut self, number: &U256) -> H256; @@ -99,21 +101,21 @@ pub trait Ext { ) -> MessageCallResult; /// Returns code at given address - fn extcode(&self, address: &Address) -> evm::Result>; + fn extcode(&self, address: &Address) -> Result>; /// Returns code size at given address - fn extcodesize(&self, address: &Address) -> evm::Result; + fn extcodesize(&self, address: &Address) -> Result; /// Creates log entry with given topics and data - fn log(&mut self, topics: Vec, data: &[u8]) -> evm::Result<()>; + fn log(&mut self, topics: Vec, data: &[u8]) -> Result<()>; /// Should be called when transaction calls `RETURN` opcode. /// Returns gas_left if cost of returning the data is not too high. - fn ret(self, gas: &U256, data: &ReturnData) -> evm::Result; + fn ret(self, gas: &U256, data: &ReturnData) -> Result; /// Should be called when contract commits suicide. /// Address to which funds should be refunded. - fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> ; + fn suicide(&mut self, refund_address: &Address) -> Result<()> ; /// Returns schedule. fn schedule(&self) -> &Schedule; diff --git a/ethcore/vm/src/lib.rs b/ethcore/vm/src/lib.rs new file mode 100644 index 000000000..0c9e32dc6 --- /dev/null +++ b/ethcore/vm/src/lib.rs @@ -0,0 +1,48 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Virtual machines support library + +extern crate ethcore_util as util; +extern crate common_types as types; +extern crate ethjson; +extern crate rlp; + +mod action_params; +mod call_type; +mod env_info; +mod schedule; +mod ext; +mod return_data; +mod error; + +pub mod tests; + +pub use action_params::{ActionParams, ActionValue}; +pub use call_type::CallType; +pub use env_info::{EnvInfo, LastHashes}; +pub use schedule::{Schedule, CleanDustMode}; +pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress}; +pub use return_data::{ReturnData, GasLeft}; +pub use error::{Error, Result}; + +/// Virtual Machine interface +pub trait Vm { + /// This function should be used to execute transaction. + /// It returns either an error, a known amount of gas left, or parameters to be used + /// to compute the final gas left. + fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result; +} \ No newline at end of file diff --git a/ethcore/vm/src/return_data.rs b/ethcore/vm/src/return_data.rs new file mode 100644 index 000000000..3c8bd182f --- /dev/null +++ b/ethcore/vm/src/return_data.rs @@ -0,0 +1,68 @@ + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Return data structures + +use util::U256; + +/// Return data buffer. Holds memory from a previous call and a slice into that memory. +#[derive(Debug)] +pub struct ReturnData { + mem: Vec, + offset: usize, + size: usize, +} + +impl ::std::ops::Deref for ReturnData { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.mem[self.offset..self.offset + self.size] + } +} + +impl ReturnData { + /// Create empty `ReturnData`. + pub fn empty() -> Self { + ReturnData { + mem: Vec::new(), + offset: 0, + size: 0, + } + } + /// Create `ReturnData` from give buffer and slice. + pub fn new(mem: Vec, offset: usize, size: usize) -> Self { + ReturnData { + mem: mem, + offset: offset, + size: size, + } + } +} + +/// Gas Left: either it is a known value, or it needs to be computed by processing +/// a return instruction. +#[derive(Debug)] +pub enum GasLeft { + /// Known gas left + Known(U256), + /// Return or Revert instruction must be processed. + NeedsReturn { + /// Amount of gas left. + gas_left: U256, + /// Return data buffer. + data: ReturnData, + /// Apply or revert state changes on revert. + apply_state: bool + }, +} \ No newline at end of file diff --git a/ethcore/evm/src/schedule.rs b/ethcore/vm/src/schedule.rs similarity index 96% rename from ethcore/evm/src/schedule.rs rename to ethcore/vm/src/schedule.rs index a8dd09645..6966c26e6 100644 --- a/ethcore/evm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -107,6 +107,8 @@ pub struct Schedule { pub blockhash_gas: usize, /// Static Call opcode enabled. pub have_static_call: bool, + /// RETURNDATA and RETURNDATASIZE opcodes enabled. + pub have_return_data: bool, /// Kill basic accounts below this balance if touched. pub kill_dust: CleanDustMode, } @@ -140,6 +142,7 @@ impl Schedule { have_delegate_call: true, have_create2: false, have_revert: false, + have_return_data: false, stack_limit: 1024, max_depth: 1024, tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], @@ -190,6 +193,7 @@ impl Schedule { schedule.have_create2 = true; schedule.have_revert = true; schedule.have_static_call = true; + schedule.have_return_data = true; schedule.blockhash_gas = 350; schedule } @@ -200,6 +204,7 @@ impl Schedule { have_delegate_call: hdc, have_create2: false, have_revert: false, + have_return_data: false, stack_limit: 1024, max_depth: 1024, tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], @@ -245,6 +250,12 @@ impl Schedule { } } +impl Default for Schedule { + fn default() -> Self { + Schedule::new_frontier() + } +} + #[test] #[cfg(test)] fn schedule_evm_assumptions() { @@ -255,3 +266,4 @@ fn schedule_evm_assumptions() { assert_eq!(s1.quad_coeff_div, 512); assert_eq!(s2.quad_coeff_div, 512); } + diff --git a/ethcore/vm/src/tests.rs b/ethcore/vm/src/tests.rs new file mode 100644 index 000000000..c8afedaff --- /dev/null +++ b/ethcore/vm/src/tests.rs @@ -0,0 +1,187 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::sync::Arc; +use std::collections::{HashMap, HashSet}; + +use util::{H256, U256, Address, Bytes}; +use { + CallType, Schedule, EnvInfo, + ReturnData, Ext, ContractCreateResult, MessageCallResult, + CreateContractAddress, Result, GasLeft, +}; + +pub struct FakeLogEntry { + pub topics: Vec, + pub data: Bytes +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub enum FakeCallType { + Call, Create +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub struct FakeCall { + pub call_type: FakeCallType, + pub gas: U256, + pub sender_address: Option
, + pub receive_address: Option
, + pub value: Option, + pub data: Bytes, + pub code_address: Option
, +} + +/// Fake externalities test structure. +/// +/// Can't do recursive calls. +#[derive(Default)] +pub struct FakeExt { + pub store: HashMap, + pub suicides: HashSet
, + pub calls: HashSet, + pub sstore_clears: usize, + pub depth: usize, + pub blockhashes: HashMap, + pub codes: HashMap>, + pub logs: Vec, + pub info: EnvInfo, + pub schedule: Schedule, + pub balances: HashMap, +} + +// similar to the normal `finalize` function, but ignoring NeedsReturn. +pub fn test_finalize(res: Result) -> Result { + match res { + Ok(GasLeft::Known(gas)) => Ok(gas), + Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. + Err(e) => Err(e), + } +} + +impl FakeExt { + pub fn new() -> Self { + FakeExt::default() + } +} + +impl Ext for FakeExt { + fn storage_at(&self, key: &H256) -> Result { + Ok(self.store.get(key).unwrap_or(&H256::new()).clone()) + } + + fn set_storage(&mut self, key: H256, value: H256) -> Result<()> { + self.store.insert(key, value); + Ok(()) + } + + fn exists(&self, address: &Address) -> Result { + Ok(self.balances.contains_key(address)) + } + + fn exists_and_not_null(&self, address: &Address) -> Result { + Ok(self.balances.get(address).map_or(false, |b| !b.is_zero())) + } + + fn origin_balance(&self) -> Result { + unimplemented!() + } + + fn balance(&self, address: &Address) -> Result { + Ok(self.balances[address]) + } + + fn blockhash(&mut self, number: &U256) -> H256 { + self.blockhashes.get(number).unwrap_or(&H256::new()).clone() + } + + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult { + self.calls.insert(FakeCall { + call_type: FakeCallType::Create, + gas: *gas, + sender_address: None, + receive_address: None, + value: Some(*value), + data: code.to_vec(), + code_address: None + }); + ContractCreateResult::Failed + } + + fn call(&mut self, + gas: &U256, + sender_address: &Address, + receive_address: &Address, + value: Option, + data: &[u8], + code_address: &Address, + _output: &mut [u8], + _call_type: CallType + ) -> MessageCallResult { + + self.calls.insert(FakeCall { + call_type: FakeCallType::Call, + gas: *gas, + sender_address: Some(sender_address.clone()), + receive_address: Some(receive_address.clone()), + value: value, + data: data.to_vec(), + code_address: Some(code_address.clone()) + }); + MessageCallResult::Success(*gas, ReturnData::empty()) + } + + fn extcode(&self, address: &Address) -> Result> { + Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone()) + } + + fn extcodesize(&self, address: &Address) -> Result { + Ok(self.codes.get(address).map_or(0, |c| c.len())) + } + + fn log(&mut self, topics: Vec, data: &[u8]) -> Result<()> { + self.logs.push(FakeLogEntry { + topics: topics, + data: data.to_vec() + }); + Ok(()) + } + + fn ret(self, _gas: &U256, _data: &ReturnData) -> Result { + unimplemented!(); + } + + fn suicide(&mut self, refund_address: &Address) -> Result<()> { + self.suicides.insert(refund_address.clone()); + Ok(()) + } + + fn schedule(&self) -> &Schedule { + &self.schedule + } + + fn env_info(&self) -> &EnvInfo { + &self.info + } + + fn depth(&self) -> usize { + self.depth + } + + fn inc_sstore_clears(&mut self) { + self.sstore_clears += 1; + } +} diff --git a/ethcore/wasm/Cargo.toml b/ethcore/wasm/Cargo.toml new file mode 100644 index 000000000..bbeeeffc5 --- /dev/null +++ b/ethcore/wasm/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "wasm" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +byteorder = "1.0" +ethcore-util = { path = "../../util" } +log = "0.3" +parity-wasm = "0.12" +wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } +vm = { path = "../vm" } +ethcore-logger = { path = "../../logger" } \ No newline at end of file diff --git a/ethcore/evm/src/wasm/call_args.rs b/ethcore/wasm/src/call_args.rs similarity index 100% rename from ethcore/evm/src/wasm/call_args.rs rename to ethcore/wasm/src/call_args.rs diff --git a/ethcore/evm/src/wasm/env.rs b/ethcore/wasm/src/env.rs similarity index 71% rename from ethcore/evm/src/wasm/env.rs rename to ethcore/wasm/src/env.rs index cabd38bd9..cb7462046 100644 --- a/ethcore/evm/src/wasm/env.rs +++ b/ethcore/wasm/src/env.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Wasm env module bindings +//! Wasm env module bindings use parity_wasm::elements::ValueType::*; use parity_wasm::interpreter::UserFunctionDescriptor; @@ -61,6 +61,21 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ &[I32; 4], Some(I32), ), + Static( + "_ccall", + &[I32; 6], + Some(I32), + ), + Static( + "_dcall", + &[I32; 5], + Some(I32), + ), + Static( + "_scall", + &[I32; 5], + Some(I32), + ), Static( "abort", &[I32], @@ -72,48 +87,57 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ None, ), Static( - "invoke_vii", - &[I32; 3], - None, - ), - Static( - "invoke_vi", - &[I32; 2], - None, - ), - Static( - "invoke_v", - &[I32], - None, - ), - Static( - "invoke_iii", - &[I32; 3], - Some(I32), - ), - Static( - "___resumeException", - &[I32], - None, + "abortOnCannotGrowMemory", + &[I32; 0], + Some(I32) ), + + /* + THIS IS EXPERIMENTAL RUST-ONLY RUNTIME EXTERNS, THEY ARE SUBJECT TO CHANGE + + AVOID YOUR WASM CONTAINS ANY OF THESE OTHERWISE + EITHER FACE THE NEED OF HARDFORK + OR YOU CAN STUCK ON SPECIFIC RUST VERSION FOR WASM COMPILATION + */ + Static( "_rust_begin_unwind", &[I32; 4], None, ), - Static( - "___cxa_find_matching_catch_2", - &[], - Some(I32), - ), - Static( - "___gxx_personality_v0", - &[I32; 6], - Some(I32), - ), Static( "_emscripten_memcpy_big", &[I32; 3], Some(I32), - ) + ), + Static( + "___syscall6", + &[I32; 2], + Some(I32), + ), + Static( + "___syscall140", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall146", + &[I32; 2], + Some(I32) + ), + Static( + "___syscall54", + &[I32; 2], + Some(I32) + ), + Static( + "_llvm_trap", + &[I32; 0], + None + ), + Static( + "___setErrNo", + &[I32; 1], + None + ), ]; diff --git a/ethcore/evm/src/wasm/mod.rs b/ethcore/wasm/src/lib.rs similarity index 80% rename from ethcore/evm/src/wasm/mod.rs rename to ethcore/wasm/src/lib.rs index a7186add5..ec6e67405 100644 --- a/ethcore/evm/src/wasm/mod.rs +++ b/ethcore/wasm/src/lib.rs @@ -16,6 +16,14 @@ //! Wasm Interpreter +extern crate vm; +extern crate ethcore_util as util; +#[macro_use] extern crate log; +extern crate ethcore_logger; +extern crate byteorder; +extern crate parity_wasm; +extern crate wasm_utils; + mod runtime; mod ptr; mod call_args; @@ -30,11 +38,9 @@ const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024; use parity_wasm::{interpreter, elements}; use parity_wasm::interpreter::ModuleInstanceInterface; -use wasm_utils; -use evm::{self, GasLeft, ReturnData}; -use action_params::ActionParams; -use self::runtime::Runtime; +use vm::{GasLeft, ReturnData, ActionParams}; +use self::runtime::{Runtime, RuntimeContext}; pub use self::runtime::Error as RuntimeError; @@ -56,9 +62,9 @@ impl WasmInterpreter { } } -impl evm::Evm for WasmInterpreter { +impl vm::Vm for WasmInterpreter { - fn exec(&mut self, params: ActionParams, ext: &mut ::ext::Ext) -> evm::Result { + fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result { use parity_wasm::elements::Deserialize; let code = params.code.expect("exec is only called on contract with code; qed"); @@ -74,7 +80,7 @@ impl evm::Evm for WasmInterpreter { .expect("Linear memory to exist in wasm runtime"); if params.gas > ::std::u64::MAX.into() { - return Err(evm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); + return Err(vm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned())); } let mut runtime = Runtime::with_params( @@ -82,6 +88,7 @@ impl evm::Evm for WasmInterpreter { env_memory, DEFAULT_STACK_SPACE, params.gas.low_u64(), + RuntimeContext::new(params.address, params.sender), ); let mut cursor = ::std::io::Cursor::new(&*code); @@ -90,7 +97,7 @@ impl evm::Evm for WasmInterpreter { elements::Module::deserialize( &mut cursor ).map_err(|err| { - evm::Error::Wasm(format!("Error deserializing contract code ({:?})", err)) + vm::Error::Wasm(format!("Error deserializing contract code ({:?})", err)) })? ); @@ -111,7 +118,7 @@ impl evm::Evm for WasmInterpreter { interpreter::env_native_module(env_instance, native_bindings(&mut runtime)) .map_err(|err| { // todo: prefer explicit panic here also? - evm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err)) + vm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err)) })? ) ).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32)); @@ -119,13 +126,13 @@ impl evm::Evm for WasmInterpreter { let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals)) .map_err(|err| { trace!(target: "wasm", "Error adding contract module: {:?}", err); - evm::Error::from(RuntimeError::Interpreter(err)) + vm::Error::from(RuntimeError::Interpreter(err)) })?; module_instance.execute_export("_call", execution_params) .map_err(|err| { trace!(target: "wasm", "Error executing contract: {:?}", err); - evm::Error::from(RuntimeError::Interpreter(err)) + vm::Error::from(RuntimeError::Interpreter(err)) })?; } @@ -157,3 +164,9 @@ fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<' functions: ::std::borrow::Cow::from(env::SIGNATURES), } } + +impl From for vm::Error { + fn from(err: runtime::Error) -> vm::Error { + vm::Error::Wasm(format!("WASM runtime-error: {:?}", err)) + } +} \ No newline at end of file diff --git a/ethcore/evm/src/wasm/ptr.rs b/ethcore/wasm/src/ptr.rs similarity index 100% rename from ethcore/evm/src/wasm/ptr.rs rename to ethcore/wasm/src/ptr.rs diff --git a/ethcore/evm/src/wasm/result.rs b/ethcore/wasm/src/result.rs similarity index 100% rename from ethcore/evm/src/wasm/result.rs rename to ethcore/wasm/src/result.rs diff --git a/ethcore/evm/src/wasm/runtime.rs b/ethcore/wasm/src/runtime.rs similarity index 70% rename from ethcore/evm/src/wasm/runtime.rs rename to ethcore/wasm/src/runtime.rs index 7beb4c599..a983c954f 100644 --- a/ethcore/evm/src/wasm/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -20,11 +20,11 @@ use std::sync::Arc; use byteorder::{LittleEndian, ByteOrder}; -use ext; - +use vm; use parity_wasm::interpreter; use util::{Address, H256, U256}; +use vm::CallType; use super::ptr::{WasmPtr, Error as PtrError}; use super::call_args::CallArgs; @@ -57,22 +57,38 @@ impl From for Error { } } +pub struct RuntimeContext { + address: Address, + sender: Address, +} + +impl RuntimeContext { + pub fn new(address: Address, sender: Address) -> Self { + RuntimeContext { + address: address, + sender: sender, + } + } +} + /// Runtime enviroment data for wasm contract execution pub struct Runtime<'a> { gas_counter: u64, gas_limit: u64, dynamic_top: u32, - ext: &'a mut ext::Ext, + ext: &'a mut vm::Ext, memory: Arc, + context: RuntimeContext, } impl<'a> Runtime<'a> { /// New runtime for wasm contract with specified params pub fn with_params<'b>( - ext: &'b mut ext::Ext, + ext: &'b mut vm::Ext, memory: Arc, stack_space: u32, gas_limit: u64, + context: RuntimeContext, ) -> Runtime<'b> { Runtime { gas_counter: 0, @@ -80,6 +96,7 @@ impl<'a> Runtime<'a> { dynamic_top: stack_space, memory: memory, ext: ext, + context: context, } } @@ -139,13 +156,13 @@ impl<'a> Runtime<'a> { trace!(target: "wasm", "runtime: create contract"); let mut context = context; let result_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + trace!(target: "wasm", "result_ptr: {:?}", result_ptr); let code_len = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_len: {:?}", code_len); + trace!(target: "wasm", " code_len: {:?}", code_len); let code_ptr = context.value_stack.pop_as::()? as u32; - trace!(target: "wasm", " code_ptr: {:?}", code_ptr); + trace!(target: "wasm", " code_ptr: {:?}", code_ptr); let endowment = self.pop_u256(&mut context)?; - trace!(target: "wasm", " val: {:?}", endowment); + trace!(target: "wasm", " val: {:?}", endowment); let code = self.memory.get(code_ptr, code_len as usize)?; @@ -153,20 +170,141 @@ impl<'a> Runtime<'a> { .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? .into(); - match self.ext.create(&gas_left, &endowment, &code, ext::CreateContractAddress::FromSenderAndCodeHash) { - ext::ContractCreateResult::Created(address, gas_left) => { + match self.ext.create(&gas_left, &endowment, &code, vm::CreateContractAddress::FromSenderAndCodeHash) { + vm::ContractCreateResult::Created(address, gas_left) => { self.memory.set(result_ptr, &*address)?; self.gas_counter = self.gas_limit - gas_left.low_u64(); trace!(target: "wasm", "runtime: create contract success (@{:?})", address); Ok(Some(0i32.into())) }, - ext::ContractCreateResult::Failed => { + vm::ContractCreateResult::Failed => { trace!(target: "wasm", "runtime: create contract fail"); Ok(Some((-1i32).into())) } } } + pub fn call(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // + // method signature: + // fn ( + // address: *const u8, + // val_ptr: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(true, CallType::Call, context) + } + + + fn call_code(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // + // signature (same as static call): + // fn ( + // address: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(false, CallType::CallCode, context) + } + + fn do_call( + &mut self, + use_val: bool, + call_type: CallType, + context: interpreter::CallerContext, + ) + -> Result, interpreter::Error> + { + + trace!(target: "wasm", "runtime: call code"); + let mut context = context; + let result_alloc_len = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " result_len: {:?}", result_alloc_len); + + let result_ptr = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " result_ptr: {:?}", result_ptr); + + let input_len = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " input_len: {:?}", input_len); + + let input_ptr = context.value_stack.pop_as::()? as u32; + trace!(target: "wasm", " input_ptr: {:?}", input_ptr); + + let val = if use_val { Some(self.pop_u256(&mut context)?) } + else { None }; + trace!(target: "wasm", " val: {:?}", val); + + let address = self.pop_address(&mut context)?; + trace!(target: "wasm", " address: {:?}", address); + + if let Some(ref val) = val { + let address_balance = self.ext.balance(&self.context.address) + .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))?; + + if &address_balance < val { + trace!(target: "wasm", "runtime: call failed due to balance check"); + return Ok(Some((-1i32).into())); + } + } + + let mut result = Vec::with_capacity(result_alloc_len as usize); + result.resize(result_alloc_len as usize, 0); + let gas = self.gas_left() + .map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))? + .into(); + // todo: optimize to use memory views once it's in + let payload = self.memory.get(input_ptr, input_len as usize)?; + + let call_result = self.ext.call( + &gas, + &self.context.sender, + &self.context.address, + val, + &payload, + &address, + &mut result[..], + call_type, + ); + + match call_result { + vm::MessageCallResult::Success(gas_left, _) => { + self.gas_counter = self.gas_limit - gas_left.low_u64(); + self.memory.set(result_ptr, &result)?; + Ok(Some(0i32.into())) + }, + vm::MessageCallResult::Failed => { + Ok(Some((-1i32).into())) + } + } + } + + pub fn static_call(&mut self, context: interpreter::CallerContext) + -> Result, interpreter::Error> + { + // signature (same as code call): + // fn ( + // address: *const u8, + // input_ptr: *const u8, + // input_len: u32, + // result_ptr: *mut u8, + // result_len: u32, + // ) -> i32 + + self.do_call(false, CallType::StaticCall, context) + } + + /// Allocate memory using the wasm stack params pub fn malloc(&mut self, context: interpreter::CallerContext) -> Result, interpreter::Error> @@ -338,6 +476,15 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { "_create" => { self.create(context) }, + "_ccall" => { + self.call(context) + }, + "_dcall" => { + self.call_code(context) + }, + "_scall" => { + self.static_call(context) + }, "_debug" => { self.debug_log(context) }, @@ -348,7 +495,7 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> { self.mem_copy(context) }, _ => { - trace!("Unknown env func: '{}'", name); + trace!(target: "wasm", "Trapped due to unhandled function: '{}'", name); self.user_trap(context) } } diff --git a/ethcore/evm/src/wasm/tests.rs b/ethcore/wasm/src/tests.rs similarity index 61% rename from ethcore/evm/src/wasm/tests.rs rename to ethcore/wasm/src/tests.rs index 8ae13daae..401b4db09 100644 --- a/ethcore/evm/src/wasm/tests.rs +++ b/ethcore/wasm/src/tests.rs @@ -15,20 +15,20 @@ // along with Parity. If not, see . use std::sync::Arc; - -use super::super::tests::{FakeExt, FakeCall, FakeCallType}; -use super::WasmInterpreter; -use evm::{self, Evm, GasLeft}; -use action_params::{ActionParams, ActionValue}; +use byteorder::{LittleEndian, ByteOrder}; use util::{U256, H256, Address}; +use super::WasmInterpreter; +use vm::{self, Vm, GasLeft, ActionParams, ActionValue}; +use vm::tests::{FakeCall, FakeExt, FakeCallType}; + macro_rules! load_sample { ($name: expr) => { - include_bytes!(concat!("../../../res/wasm-tests/compiled/", $name)).to_vec() + include_bytes!(concat!("../../res/wasm-tests/compiled/", $name)).to_vec() } } -fn test_finalize(res: Result) -> Result { +fn test_finalize(res: Result) -> Result { match res { Ok(GasLeft::Known(gas)) => Ok(gas), Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented. @@ -85,7 +85,7 @@ fn logger() { }; println!("ext.store: {:?}", ext.store); - assert_eq!(gas_left, U256::from(99581)); + assert_eq!(gas_left, U256::from(99590)); let address_val: H256 = address.into(); assert_eq!( ext.store.get(&"0100000000000000000000000000000000000000000000000000000000000000".parse().unwrap()).expect("storage key to exist"), @@ -136,7 +136,7 @@ fn identity() { } }; - assert_eq!(gas_left, U256::from(99_689)); + assert_eq!(gas_left, U256::from(99_687)); assert_eq!( Address::from_slice(&result), @@ -170,7 +170,7 @@ fn dispersion() { } }; - assert_eq!(gas_left, U256::from(99_402)); + assert_eq!(gas_left, U256::from(99_423)); assert_eq!( result, @@ -199,7 +199,7 @@ fn suicide_not() { } }; - assert_eq!(gas_left, U256::from(99_703)); + assert_eq!(gas_left, U256::from(99_656)); assert_eq!( result, @@ -233,12 +233,14 @@ fn suicide() { } }; - assert_eq!(gas_left, U256::from(99_747)); + assert_eq!(gas_left, U256::from(99_740)); assert!(ext.suicides.contains(&refund)); } #[test] fn create() { + ::ethcore_logger::init_log(); + let mut params = ActionParams::default(); params.gas = U256::from(100_000); params.code = Some(Arc::new(load_sample!("creator.wasm"))); @@ -262,7 +264,7 @@ fn create() { assert!(ext.calls.contains( &FakeCall { call_type: FakeCallType::Create, - gas: U256::from(99_778), + gas: U256::from(99_767), sender_address: None, receive_address: None, value: Some(1_000_000_000.into()), @@ -270,5 +272,145 @@ fn create() { code_address: None, } )); - assert_eq!(gas_left, U256::from(99_768)); + assert_eq!(gas_left, U256::from(99_759)); +} + + +#[test] +fn call_code() { + ::ethcore_logger::init_log(); + + let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); + let receiver: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + + let mut params = ActionParams::default(); + params.sender = sender.clone(); + params.address = receiver.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(load_sample!("call_code.wasm"))); + params.data = Some(Vec::new()); + params.value = ActionValue::transfer(1_000_000_000); + + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Call test should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + trace!(target: "wasm", "fake_calls: {:?}", &ext.calls); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Call, + gas: U256::from(99_061), + sender_address: Some(sender), + receive_address: Some(receiver), + value: None, + data: vec![1u8, 2, 3, 5, 7, 11], + code_address: Some("0d13710000000000000000000000000000000000".parse().unwrap()), + } + )); + assert_eq!(gas_left, U256::from(94196)); + + // siphash result + let res = LittleEndian::read_u32(&result[..]); + assert_eq!(res, 4198595614); +} + +#[test] +fn call_static() { + ::ethcore_logger::init_log(); + + let sender: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + let receiver: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap(); + + let mut params = ActionParams::default(); + params.sender = sender.clone(); + params.address = receiver.clone(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(load_sample!("call_static.wasm"))); + params.data = Some(Vec::new()); + params.value = ActionValue::transfer(1_000_000_000); + + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Static call test should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + trace!(target: "wasm", "fake_calls: {:?}", &ext.calls); + assert!(ext.calls.contains( + &FakeCall { + call_type: FakeCallType::Call, + gas: U256::from(99_061), + sender_address: Some(sender), + receive_address: Some(receiver), + value: None, + data: vec![1u8, 2, 3, 5, 7, 11], + code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()), + } + )); + assert_eq!(gas_left, U256::from(94196)); + + // siphash result + let res = LittleEndian::read_u32(&result[..]); + assert_eq!(res, 317632590); +} + +// Realloc test +#[test] +fn realloc() { + let code = load_sample!("realloc.wasm"); + + let mut params = ActionParams::default(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + params.data = Some(vec![0u8]); + let mut ext = FakeExt::new(); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("Realloc should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + assert_eq!(gas_left, U256::from(98326)); + assert_eq!(result, vec![0u8; 2]); +} + +// Tests that contract's ability to read from a storage +// Test prepopulates address into storage, than executes a contract which read that address from storage and write this address into result +#[test] +fn storage_read() { + let code = load_sample!("storage_read.wasm"); + let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap(); + + let mut params = ActionParams::default(); + params.gas = U256::from(100_000); + params.code = Some(Arc::new(code)); + let mut ext = FakeExt::new(); + ext.store.insert("0100000000000000000000000000000000000000000000000000000000000000".into(), address.into()); + + let (gas_left, result) = { + let mut interpreter = wasm_interpreter(); + let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); + match result { + GasLeft::Known(_) => { panic!("storage_read should return payload"); }, + GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()), + } + }; + + assert_eq!(gas_left, U256::from(99752)); + assert_eq!(Address::from(&result[12..32]), address); } diff --git a/ethcrypto/Cargo.toml b/ethcrypto/Cargo.toml index 8e5131974..a84032f26 100644 --- a/ethcrypto/Cargo.toml +++ b/ethcrypto/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] [dependencies] rust-crypto = "0.2.36" -tiny-keccak = "1.2" +tiny-keccak = "1.3" eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" } ethkey = { path = "../ethkey" } ethcore-bigint = { path = "../util/bigint" } diff --git a/ethkey/Cargo.toml b/ethkey/Cargo.toml index 342410adc..519accadf 100644 --- a/ethkey/Cargo.toml +++ b/ethkey/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Parity Technologies "] [dependencies] rand = "0.3.14" lazy_static = "0.2" -tiny-keccak = "1.2" +tiny-keccak = "1.3" eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" } rustc-hex = "1.0" ethcore-bigint = { path = "../util/bigint" } diff --git a/ethkey/cli/Cargo.toml b/ethkey/cli/Cargo.toml index 3ea931e25..6921af745 100644 --- a/ethkey/cli/Cargo.toml +++ b/ethkey/cli/Cargo.toml @@ -9,6 +9,7 @@ serde = "1.0" serde_derive = "1.0" rustc-hex = "1.0" docopt = "0.8" +panic_hook = { path = "../../panic_hook" } [[bin]] name = "ethkey" diff --git a/ethkey/cli/src/main.rs b/ethkey/cli/src/main.rs index 0d96c2a89..e60b4583a 100644 --- a/ethkey/cli/src/main.rs +++ b/ethkey/cli/src/main.rs @@ -20,12 +20,14 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate ethkey; +extern crate panic_hook; use std::{env, fmt, process}; use std::num::ParseIntError; use docopt::Docopt; -use rustc_hex::{FromHex, FromHexError}; +use rustc_hex::{ToHex, FromHex, FromHexError}; use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, sign, verify_public, verify_address}; +use std::io; pub const USAGE: &'static str = r#" Ethereum keys generator. @@ -87,6 +89,7 @@ enum Error { FromHex(FromHexError), ParseInt(ParseIntError), Docopt(docopt::Error), + Io(io::Error), } impl From for Error { @@ -113,6 +116,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: io::Error) -> Self { + Error::Io(err) + } +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match *self { @@ -120,6 +129,7 @@ impl fmt::Display for Error { Error::FromHex(ref e) => write!(f, "{}", e), Error::ParseInt(ref e) => write!(f, "{}", e), Error::Docopt(ref e) => write!(f, "{}", e), + Error::Io(ref e) => write!(f, "{}", e), } } } @@ -146,6 +156,8 @@ impl DisplayMode { } fn main() { + panic_hook::set(); + match execute(env::args()) { Ok(ok) => println!("{}", ok), Err(err) => { @@ -158,7 +170,7 @@ fn main() { fn display(keypair: KeyPair, mode: DisplayMode) -> String { match mode { DisplayMode::KeyPair => format!("{}", keypair), - DisplayMode::Secret => format!("{:?}", keypair.secret()), + DisplayMode::Secret => format!("{}", keypair.secret().to_hex()), DisplayMode::Public => format!("{:?}", keypair.public()), DisplayMode::Address => format!("{:?}", keypair.address()), } @@ -176,17 +188,17 @@ fn execute(command: I) -> Result where I: IntoIterator>(); let expected = -"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 -public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 -address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); +"secret: aa22b54c0cb43ee30a014afe5ef3664b1cde299feabca46cd3167a85a57c39f2 +public: c4c5398da6843632c123f543d714d2d2277716c11ff612b2a2f23c6bda4d6f0327c31cd58c55a9572c3cc141dade0c32747a13b7ef34c241b26c84adbb28fcf4 +address: 006e27b6a72e1f34c626762f3c4761547aff1421".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -249,7 +261,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55".to_owned(); + let expected = "aa22b54c0cb43ee30a014afe5ef3664b1cde299feabca46cd3167a85a57c39f2".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -260,7 +272,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124".to_owned(); + let expected = "c4c5398da6843632c123f543d714d2d2277716c11ff612b2a2f23c6bda4d6f0327c31cd58c55a9572c3cc141dade0c32747a13b7ef34c241b26c84adbb28fcf4".to_owned(); assert_eq!(execute(command).unwrap(), expected); } @@ -271,7 +283,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); .map(Into::into) .collect::>(); - let expected = "26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); + let expected = "006e27b6a72e1f34c626762f3c4761547aff1421".to_owned(); assert_eq!(execute(command).unwrap(), expected); } diff --git a/ethkey/src/brain.rs b/ethkey/src/brain.rs index 9976bdb01..8bc9d2cd7 100644 --- a/ethkey/src/brain.rs +++ b/ethkey/src/brain.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use keccak::Keccak256; -use super::{KeyPair, Error, Generator, Secret}; +use super::{KeyPair, Generator, Secret}; /// Simple brainwallet. pub struct Brain(String); @@ -27,7 +27,9 @@ impl Brain { } impl Generator for Brain { - fn generate(self) -> Result { + type Error = ::Void; + + fn generate(self) -> Result { let seed = self.0; let mut secret = seed.into_bytes().keccak256(); @@ -38,11 +40,10 @@ impl Generator for Brain { match i > 16384 { false => i += 1, true => { - if let Ok(secret) = Secret::from_unsafe_slice(&secret) { - let result = KeyPair::from_secret(secret); - if result.as_ref().ok().map_or(false, |r| r.address()[0] == 0) { - return result; - } + if let Ok(pair) = Secret::from_unsafe_slice(&secret) + .and_then(KeyPair::from_secret) + { + if pair.address()[0] == 0 { return Ok(pair) } } }, } diff --git a/ethkey/src/lib.rs b/ethkey/src/lib.rs index e87e198df..271a5f166 100644 --- a/ethkey/src/lib.rs +++ b/ethkey/src/lib.rs @@ -15,8 +15,6 @@ // along with Parity. If not, see . extern crate rand; -#[macro_use] -extern crate lazy_static; extern crate tiny_keccak; extern crate secp256k1; extern crate rustc_hex; @@ -24,6 +22,9 @@ extern crate ethcore_bigint as bigint; extern crate crypto as rcrypto; extern crate byteorder; +#[macro_use] +extern crate lazy_static; + mod brain; mod error; mod keypair; @@ -34,21 +35,12 @@ mod signature; mod secret; mod extended; -lazy_static! { - pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); -} - -/// Generates new keypair. -pub trait Generator { - /// Should be called to generate new keypair. - fn generate(self) -> Result; -} - pub mod math; pub use self::brain::Brain; pub use self::error::Error; pub use self::keypair::{KeyPair, public_to_address}; +pub use self::math::public_is_valid; pub use self::prefix::Prefix; pub use self::random::Random; pub use self::signature::{sign, verify_public, verify_address, recover, Signature}; @@ -57,6 +49,22 @@ pub use self::extended::{ExtendedPublic, ExtendedSecret, ExtendedKeyPair, Deriva use bigint::hash::{H160, H256, H512}; +lazy_static! { + pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); +} + +/// Uninstantiatable error type for infallible generators. +#[derive(Debug)] +pub enum Void {} + +/// Generates new keypair. +pub trait Generator { + type Error; + + /// Should be called to generate new keypair. + fn generate(self) -> Result; +} + pub type Address = H160; pub type Message = H256; pub type Public = H512; diff --git a/ethkey/src/math.rs b/ethkey/src/math.rs index cf7012132..4c875bd8f 100644 --- a/ethkey/src/math.rs +++ b/ethkey/src/math.rs @@ -20,6 +20,12 @@ use secp256k1::constants::{GENERATOR_X, GENERATOR_Y, CURVE_ORDER}; use bigint::prelude::U256; use bigint::hash::H256; +/// Whether the public key is valid. +pub fn public_is_valid(public: &Public) -> bool { + to_secp256k1_public(public).ok() + .map_or(false, |p| p.is_valid()) +} + /// Inplace multiply public key by secret key (EC point * scalar) pub fn public_mul_secret(public: &mut Public, secret: &Secret) -> Result<(), Error> { let key_secret = secret.to_secp256k1_secret()?; diff --git a/ethkey/src/prefix.rs b/ethkey/src/prefix.rs index 174c877b0..25b1ab3f7 100644 --- a/ethkey/src/prefix.rs +++ b/ethkey/src/prefix.rs @@ -32,6 +32,8 @@ impl Prefix { } impl Generator for Prefix { + type Error = Error; + fn generate(self) -> Result { for _ in 0..self.iterations { let keypair = Random.generate()?; diff --git a/ethkey/src/random.rs b/ethkey/src/random.rs index b84402427..715dd3cb5 100644 --- a/ethkey/src/random.rs +++ b/ethkey/src/random.rs @@ -15,18 +15,30 @@ // along with Parity. If not, see . use rand::os::OsRng; -use super::{Generator, KeyPair, Error, SECP256K1}; +use super::{Generator, KeyPair, SECP256K1}; -/// Randomly generates new keypair. +/// Randomly generates new keypair, instantiating the RNG each time. pub struct Random; impl Generator for Random { - fn generate(self) -> Result { - let context = &SECP256K1; + type Error = ::std::io::Error; + + fn generate(self) -> Result { let mut rng = OsRng::new()?; - let (sec, publ) = context.generate_keypair(&mut rng)?; + match rng.generate() { + Ok(pair) => Ok(pair), + Err(void) => match void {}, // LLVM unreachable + } + } +} + +impl<'a> Generator for &'a mut OsRng { + type Error = ::Void; + + fn generate(self) -> Result { + let (sec, publ) = SECP256K1.generate_keypair(self) + .expect("context always created with full capabilities; qed"); Ok(KeyPair::from_keypair(sec, publ)) } } - diff --git a/ethkey/src/secret.rs b/ethkey/src/secret.rs index 982962684..433d8c68e 100644 --- a/ethkey/src/secret.rs +++ b/ethkey/src/secret.rs @@ -17,6 +17,7 @@ use std::fmt; use std::ops::Deref; use std::str::FromStr; +use rustc_hex::ToHex; use secp256k1::key; use bigint::hash::H256; use {Error, SECP256K1}; @@ -26,6 +27,12 @@ pub struct Secret { inner: H256, } +impl ToHex for Secret { + fn to_hex(&self) -> String { + self.inner.to_hex() + } +} + impl fmt::Debug for Secret { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "Secret: 0x{:x}{:x}..{:x}{:x}", self.inner[0], self.inner[1], self.inner[30], self.inner[31]) diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 9d8d2fce5..0f91a663c 100755 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -13,7 +13,7 @@ serde_json = "1.0" serde_derive = "1.0" rustc-hex = "1.0" rust-crypto = "0.2.36" -tiny-keccak = "1.0" +tiny-keccak = "1.3" time = "0.1.34" itertools = "0.5" parking_lot = "0.4" diff --git a/ethstore/cli/Cargo.toml b/ethstore/cli/Cargo.toml index 80d20f792..71215fefe 100644 --- a/ethstore/cli/Cargo.toml +++ b/ethstore/cli/Cargo.toml @@ -9,6 +9,7 @@ serde = "1.0" serde_derive = "1.0" docopt = "0.8" ethstore = { path = "../" } +panic_hook = { path = "../../panic_hook" } [[bin]] name = "ethstore" diff --git a/ethstore/cli/src/main.rs b/ethstore/cli/src/main.rs index 06ebfcd20..09ccc8cd4 100644 --- a/ethstore/cli/src/main.rs +++ b/ethstore/cli/src/main.rs @@ -20,6 +20,7 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate ethstore; +extern crate panic_hook; use std::{env, process, fs, fmt}; use std::io::Read; @@ -134,6 +135,8 @@ impl fmt::Display for Error { } fn main() { + panic_hook::set(); + match execute(env::args()) { Ok(result) => println!("{}", result), Err(err) => { diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index d32fa9f62..f3bb24071 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -499,26 +499,26 @@ impl SimpleSecretStore for EthMultiStore { fn sign(&self, account: &StoreAccountRef, password: &str, message: &Message) -> Result { let accounts = self.get_matching(account, password)?; - for account in accounts { - return account.sign(password, message); + match accounts.first() { + Some(ref account) => account.sign(password, message), + None => Err(Error::InvalidPassword), } - Err(Error::InvalidPassword) } fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result, Error> { let accounts = self.get_matching(account, password)?; - for account in accounts { - return account.decrypt(password, shared_mac, message); + match accounts.first() { + Some(ref account) => account.decrypt(password, shared_mac, message), + None => Err(Error::InvalidPassword), } - Err(Error::InvalidPassword) } fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result { let accounts = self.get_matching(account, password)?; - for account in accounts { - return account.agree(password, other); + match accounts.first() { + Some(ref account) => account.agree(password, other), + None => Err(Error::InvalidPassword), } - Err(Error::InvalidPassword) } fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> { diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index e3de99f2b..698646a3c 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -16,6 +16,8 @@ serde_derive = "1.0" ethcore = { path = "../ethcore" } ethcore-util = { path = "../util" } evm = { path = "../ethcore/evm" } +vm = { path = "../ethcore/vm" } +panic_hook = { path = "../panic_hook" } [features] evm-debug = ["ethcore/evm-debug-tests"] diff --git a/evmbin/benches/mod.rs b/evmbin/benches/mod.rs index d7d67a551..f4deda88e 100644 --- a/evmbin/benches/mod.rs +++ b/evmbin/benches/mod.rs @@ -31,7 +31,7 @@ extern crate rustc_hex; use self::test::{Bencher, black_box}; use evm::run_vm; -use ethcore::evm::action_params::ActionParams; +use ethcore::vm::ActionParams; use ethcore_util::U256; use rustc_hex::FromHex; diff --git a/evmbin/src/display/json.rs b/evmbin/src/display/json.rs index f12657579..f2621121e 100644 --- a/evmbin/src/display/json.rs +++ b/evmbin/src/display/json.rs @@ -21,7 +21,7 @@ use std::collections::HashMap; use util::{U256, H256, ToPretty}; use display; -use vm; +use info as vm; /// JSON formatting informant. #[derive(Default)] diff --git a/evmbin/src/display/simple.rs b/evmbin/src/display/simple.rs index 9f8f7ee14..b03f97c8d 100644 --- a/evmbin/src/display/simple.rs +++ b/evmbin/src/display/simple.rs @@ -20,7 +20,7 @@ use ethcore::trace; use util::ToPretty; use display; -use vm; +use info as vm; /// Simple formatting informant. #[derive(Default)] diff --git a/evmbin/src/vm.rs b/evmbin/src/info.rs similarity index 98% rename from evmbin/src/vm.rs rename to evmbin/src/info.rs index c4530bb9e..617ebc7b9 100644 --- a/evmbin/src/vm.rs +++ b/evmbin/src/info.rs @@ -20,7 +20,7 @@ use std::time::{Instant, Duration}; use util::U256; use ethcore::{trace, spec}; use ethcore::client::{EvmTestClient, EvmTestError}; -use evm::action_params::ActionParams; +use vm::ActionParams; /// VM execution informant pub trait Informant: trace::VMTracer { diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index df9b088d0..232642015 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -25,7 +25,9 @@ extern crate serde; extern crate serde_derive; extern crate docopt; extern crate ethcore_util as util; +extern crate vm; extern crate evm; +extern crate panic_hook; use std::sync::Arc; use std::{fmt, fs}; @@ -33,12 +35,12 @@ use docopt::Docopt; use rustc_hex::FromHex; use util::{U256, Bytes, Address}; use ethcore::spec; -use evm::action_params::ActionParams; +use vm::ActionParams; -mod vm; +mod info; mod display; -use vm::Informant; +use info::Informant; const USAGE: &'static str = r#" EVM implementation for Parity. @@ -63,6 +65,8 @@ General options: fn main() { + panic_hook::set(); + let args: Args = Docopt::new(USAGE).and_then(|d| d.deserialize()).unwrap_or_else(|e| e.exit()); if args.flag_json { @@ -87,7 +91,7 @@ fn run(args: Args, mut informant: T) { params.data = data; informant.set_gas(gas); - let result = vm::run(&mut informant, spec, params); + let result = info::run(&mut informant, spec, params); informant.finish(result); } diff --git a/evmjit/Cargo.toml b/evmjit/Cargo.toml index e4daf3dae..dbc0cd51a 100644 --- a/evmjit/Cargo.toml +++ b/evmjit/Cargo.toml @@ -7,4 +7,4 @@ authors = ["Parity Technologies "] crate-type = ["dylib"] [dependencies] -tiny-keccak = "1.2" +tiny-keccak = "1.3" diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index d52bda7d9..bd773e9b3 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -188,8 +188,9 @@ fn random_temp_path() -> PathBuf { #[cfg(test)] mod tests { + use rustc_hex::FromHex; use std::sync::{Arc, mpsc}; - use util::{Mutex, FromHex}; + use util::Mutex; use futures::future; use fetch::{self, Fetch}; use parity_reactor::Remote; diff --git a/ipc/hypervisor/src/lib.rs b/ipc/hypervisor/src/lib.rs index 1031905d4..b522122b5 100644 --- a/ipc/hypervisor/src/lib.rs +++ b/ipc/hypervisor/src/lib.rs @@ -260,7 +260,7 @@ mod tests { let client = nanoipc::fast_client::>(url).unwrap(); client.handshake().unwrap(); - client.module_ready(test_module_id); + client.module_ready(test_module_id, url.to_owned()); }); let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); diff --git a/ipfs/src/lib.rs b/ipfs/src/lib.rs index 4821ef59d..104c7db19 100644 --- a/ipfs/src/lib.rs +++ b/ipfs/src/lib.rs @@ -233,7 +233,7 @@ mod tests { let _ = write_chunk(&mut transport, &mut progress, b"foobar"); - assert_eq!(b"foobar".into_vec(), transport); + assert_eq!(b"foobar".to_vec(), transport); assert_eq!(6, progress); } @@ -244,7 +244,7 @@ mod tests { let _ = write_chunk(&mut transport, &mut progress, b"foobar"); - assert_eq!(b"bar".into_vec(), transport); + assert_eq!(b"bar".to_vec(), transport); assert_eq!(6, progress); } diff --git a/js/package-lock.json b/js/package-lock.json new file mode 100644 index 000000000..7514c3c29 --- /dev/null +++ b/js/package-lock.json @@ -0,0 +1,13048 @@ +{ + "name": "parity.js", + "version": "1.8.11", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@parity/wordlist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@parity/wordlist/-/wordlist-1.0.1.tgz", + "integrity": "sha1-wn5A4as2OKCe1TtKLoHVMbXrWjE=" + }, + "abab": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", + "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", + "dev": true + }, + "abbrev": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=" + }, + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "dev": true, + "requires": { + "mime-types": "2.1.16", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz", + "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.2.tgz", + "integrity": "sha1-R8aNaehvXZUxA7AHSpQw3GPaXjk=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + } + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" + }, + "ansi-escapes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", + "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=" + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "any-promise": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-0.1.0.tgz", + "integrity": "sha1-gwtoCqflbzNFHUsEnzvYBESY7ic=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } + }, + "aproba": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", + "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==" + }, + "archive-type": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-3.2.0.tgz", + "integrity": "sha1-nNnABpV+vpX62tW9YJiUKoE3N/Y=", + "requires": { + "file-type": "3.9.0" + } + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.3" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "1.1.0" + } + }, + "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==" + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "array.prototype.find": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", + "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.7.0" + } + }, + "arraybuffer-loader": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/arraybuffer-loader/-/arraybuffer-loader-0.2.2.tgz", + "integrity": "sha1-jnKU0VGqyO1wqC53Pq0FWQ23Dik=", + "requires": { + "loader-utils": "0.2.17" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "asn1.js": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "ast-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-each-series": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz", + "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "attr-accept": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.0.tgz", + "integrity": "sha1-tc01In8WOTWo8d4Q7T66FpQfa+Y=" + }, + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000708", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "babel-cli": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.23.0.tgz", + "integrity": "sha1-Uv+UaisPZGRcNee9XuomeqCUjA8=", + "dev": true, + "requires": { + "babel-core": "6.23.1", + "babel-polyfill": "6.23.0", + "babel-register": "6.23.0", + "babel-runtime": "6.23.0", + "chokidar": "1.7.0", + "commander": "2.8.1", + "convert-source-map": "1.5.0", + "fs-readdir-recursive": "1.0.0", + "glob": "7.1.2", + "lodash": "4.17.2", + "output-file-sync": "1.1.2", + "path-is-absolute": "1.0.1", + "slash": "1.0.0", + "source-map": "0.5.6", + "v8flags": "2.1.1" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-core": { + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.23.1.tgz", + "integrity": "sha1-wUPLYhuy9iFxDCIMXVedFbikQt8=", + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-generator": "6.25.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.2", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.6" + } + }, + "babel-eslint": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.1.1.tgz", + "integrity": "sha1-imqITwhapwYK9pz8dzQcL5k3D7I=", + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "lodash.pickby": "4.6.0" + } + }, + "babel-generator": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", + "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.2", + "source-map": "0.5.6", + "trim-right": "1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" + } + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-builder-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.24.1.tgz", + "integrity": "sha1-CteRfjPI11HmRtrKTnfMGTd9LLw=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "esutils": "2.0.2" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-define-map": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", + "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.2" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "6.24.1", + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", + "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.2" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-loader": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.3.2.tgz", + "integrity": "sha1-GN5FZjhVeMG0+P/my8Zo9eKl7wM=", + "dev": true, + "requires": { + "find-cache-dir": "0.1.1", + "loader-utils": "0.2.17", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-lodash": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.2.11.tgz", + "integrity": "sha1-Icj97J/hg176pzeHPjkCvdZtVwE=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "babel-plugin-react-intl": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-react-intl/-/babel-plugin-react-intl-2.3.1.tgz", + "integrity": "sha1-PUORLoJNoAXgjo6COdW6eEN0uwA=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "intl-messageformat-parser": "1.2.0", + "mkdirp": "0.5.1" + } + }, + "babel-plugin-recharts": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-recharts/-/babel-plugin-recharts-1.1.0.tgz", + "integrity": "sha1-gSzISxPrWN1AWyxjoo6m97JqtKc=", + "dev": true, + "requires": { + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-constructor-call": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", + "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-do-expressions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", + "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-export-extensions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", + "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", + "dev": true + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "dev": true + }, + "babel-plugin-syntax-function-bind": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", + "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", + "dev": true + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-generators": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-class-constructor-call": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", + "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", + "dev": true, + "requires": { + "babel-plugin-syntax-class-constructor-call": "6.18.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.23.0.tgz", + "integrity": "sha1-GHt0fuQEOZATVjyZPbA480dUrDs=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "requires": { + "babel-helper-explode-class": "6.24.1", + "babel-plugin-syntax-decorators": "6.13.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-decorators-legacy": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz", + "integrity": "sha1-dBtY9sW86eYCfgiC2cmU8E82aSU=", + "dev": true, + "requires": { + "babel-plugin-syntax-decorators": "6.13.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-do-expressions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", + "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=", + "dev": true, + "requires": { + "babel-plugin-syntax-do-expressions": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", + "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.2" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "requires": { + "babel-helper-define-map": "6.24.1", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", + "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "requires": { + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "requires": { + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-export-extensions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", + "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "dev": true, + "requires": { + "babel-plugin-syntax-export-extensions": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "6.18.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-function-bind": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", + "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", + "dev": true, + "requires": { + "babel-plugin-syntax-function-bind": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz", + "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "dev": true, + "requires": { + "babel-helper-builder-react-jsx": "6.24.1", + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.3.2.tgz", + "integrity": "sha1-bajYNMbXrYqwL5VlCXkM+qAf/hk=", + "dev": true + }, + "babel-plugin-transform-regenerator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", + "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", + "requires": { + "regenerator-transform": "0.9.11" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-webpack-alias": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/babel-plugin-webpack-alias/-/babel-plugin-webpack-alias-2.1.2.tgz", + "integrity": "sha1-BaG6I8KFlWYPtupXNkJPxZa0okc=", + "dev": true, + "requires": { + "babel-types": "6.25.0", + "find-up": "2.1.0", + "lodash.some": "4.6.0", + "lodash.template": "4.4.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" + } + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.templatesettings": "4.1.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0" + } + } + } + }, + "babel-polyfill": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", + "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + } + }, + "babel-preset-env": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.1.9.tgz", + "integrity": "sha1-SUQ9zW71K0i3GR6jOGniRZCp60o=", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1", + "browserslist": "1.7.7", + "electron-to-chromium": "1.3.16", + "invariant": "2.2.2" + } + }, + "babel-preset-es2015": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.22.0.tgz", + "integrity": "sha1-r1qY7LNeuK92StiloF6zbcQ4aDU=", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1" + } + }, + "babel-preset-es2016": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2016/-/babel-preset-es2016-6.22.0.tgz", + "integrity": "sha1-sGGqo5g9QMn7rPo3Q7XfN/M2FWw=", + "dev": true, + "requires": { + "babel-plugin-transform-exponentiation-operator": "6.24.1" + } + }, + "babel-preset-es2017": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2017/-/babel-preset-es2017-6.22.0.tgz", + "integrity": "sha1-3i+dpaMMUNKT+1SguhXW3cVz8PI=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1" + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "6.22.0" + } + }, + "babel-preset-react": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.23.0.tgz", + "integrity": "sha1-63zuTemKP5RQLChWUzLamBlFUZU=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-plugin-transform-react-display-name": "6.25.0", + "babel-plugin-transform-react-jsx": "6.24.1", + "babel-plugin-transform-react-jsx-self": "6.22.0", + "babel-plugin-transform-react-jsx-source": "6.22.0", + "babel-preset-flow": "6.23.0" + } + }, + "babel-preset-stage-0": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.22.0.tgz", + "integrity": "sha1-cH7rW0Fdp2nv+cQvRUf2RPkpbvk=", + "dev": true, + "requires": { + "babel-plugin-transform-do-expressions": "6.22.0", + "babel-plugin-transform-function-bind": "6.22.0", + "babel-preset-stage-1": "6.24.1" + } + }, + "babel-preset-stage-1": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", + "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "dev": true, + "requires": { + "babel-plugin-transform-class-constructor-call": "6.24.1", + "babel-plugin-transform-export-extensions": "6.22.0", + "babel-preset-stage-2": "6.24.1" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-plugin-transform-class-properties": "6.24.1", + "babel-plugin-transform-decorators": "6.24.1", + "babel-preset-stage-3": "6.24.1" + }, + "dependencies": { + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + } + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-generator-functions": "6.24.1", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-object-rest-spread": "6.23.0" + } + }, + "babel-register": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.23.0.tgz", + "integrity": "sha1-yao9TMqUtR2jSCbEoPnggUXXT/M=", + "dev": true, + "requires": { + "babel-core": "6.23.1", + "babel-runtime": "6.23.0", + "core-js": "2.4.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.2", + "mkdirp": "0.5.1", + "source-map-support": "0.4.15" + } + }, + "babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + } + }, + "babel-template": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", + "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "lodash": "4.17.2" + } + }, + "babel-traverse": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", + "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", + "requires": { + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "debug": "2.6.8", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.2" + } + }, + "babel-types": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", + "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", + "requires": { + "babel-runtime": "6.23.0", + "esutils": "2.0.2", + "lodash": "4.17.2", + "to-fast-properties": "1.0.3" + } + }, + "babelify": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "requires": { + "babel-core": "6.25.0", + "object-assign": "4.1.1" + }, + "dependencies": { + "babel-core": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", + "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", + "requires": { + "babel-code-frame": "6.22.0", + "babel-generator": "6.25.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.2", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.6" + } + }, + "babel-register": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", + "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", + "requires": { + "babel-core": "6.25.0", + "babel-runtime": "6.23.0", + "core-js": "2.4.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.2", + "mkdirp": "0.5.1", + "source-map-support": "0.4.15" + } + } + } + }, + "babylon": { + "version": "6.17.4", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", + "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base32.js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", + "integrity": "sha1-tYLexpPC8R6JPPBk7mrFthMaIgI=" + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "batch-processor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz", + "integrity": "sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + }, + "big.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", + "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=" + }, + "bignumber.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-3.0.1.tgz", + "integrity": "sha1-gHZS0Q453jfp40lyR+3HmLt0b3Y=" + }, + "bin-build": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-2.2.0.tgz", + "integrity": "sha1-EfjdYfcP/Por3KpbRvXo/t1CIcw=", + "dev": true, + "requires": { + "archive-type": "3.2.0", + "decompress": "3.0.0", + "download": "4.4.3", + "exec-series": "1.0.3", + "rimraf": "2.6.1", + "tempfile": "1.1.1", + "url-regex": "3.2.0" + }, + "dependencies": { + "tempfile": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz", + "integrity": "sha1-W8xOrsxKsscH2LwR2ZzMmiyyh/I=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2", + "uuid": "2.0.3" + } + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + } + } + }, + "bin-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-2.0.0.tgz", + "integrity": "sha1-hvjm9CU4k99g3DFpV/WvAqywWTA=", + "dev": true, + "requires": { + "executable": "1.1.0" + } + }, + "bin-version": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-1.0.4.tgz", + "integrity": "sha1-nrSY7m/Xb3q5p8FgQ2+JV5Q1144=", + "dev": true, + "requires": { + "find-versions": "1.2.1" + } + }, + "bin-version-check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-2.1.0.tgz", + "integrity": "sha1-5OXfKQuQaffRETJAMe/BP90RpbA=", + "dev": true, + "requires": { + "bin-version": "1.0.4", + "minimist": "1.2.0", + "semver": "4.3.6", + "semver-truncate": "1.1.2" + }, + "dependencies": { + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + } + } + }, + "bin-wrapper": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-3.0.2.tgz", + "integrity": "sha1-Z9MwYmLksaXy+I7iNGT2plVneus=", + "dev": true, + "requires": { + "bin-check": "2.0.0", + "bin-version-check": "2.1.0", + "download": "4.4.3", + "each-async": "1.1.1", + "lazy-req": "1.1.0", + "os-filter-obj": "1.0.3" + } + }, + "binary-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.9.0.tgz", + "integrity": "sha1-ZlBsFs5vTWkopbPNajPKQelB43s=", + "dev": true + }, + "bindings": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "bl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", + "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "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.3" + } + }, + "blockies": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/blockies/-/blockies-0.0.2.tgz", + "integrity": "sha1-Iq1Y2k9rOCvHm/Q4bFggxwBH5O0=" + }, + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", + "dev": true + }, + "bn.js": { + "version": "4.11.7", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.7.tgz", + "integrity": "sha512-LxFiV5mefv0ley0SzqkOPR1bC4EbpPx8LkOz5vMe/Yi15t5hzwgO/G+tc7wOtL4PZTYjwHu8JnEiSLumuSjSfA==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.16.3" + } + }, + "bowser": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.7.1.tgz", + "integrity": "sha1-pN6PGKGg3JUx6yqSoVIftqm6lqU=" + }, + "brace": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/brace/-/brace-0.9.0.tgz", + "integrity": "sha1-rQNLrmUiDrZ22UnLKAOD+o4S+nI=", + "requires": { + "w3c-blob": "0.0.1" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserify-aes": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", + "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.0.6", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.0" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + } + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000708", + "electron-to-chromium": "1.3.16" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8", + "isarray": "1.0.0" + } + }, + "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-to-vinyl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-to-vinyl/-/buffer-to-vinyl-1.1.0.tgz", + "integrity": "sha1-APFfruOreh3aLN5tkSG//dB7ImI=", + "requires": { + "file-type": "3.9.0", + "readable-stream": "2.3.3", + "uuid": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + } + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "2.3.1", + "upper-case": "1.1.3" + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000708", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + } + }, + "caniuse-db": { + "version": "1.0.30000708", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000708.tgz", + "integrity": "sha1-wuc2vTt/xfbBTkxt/mK5jtFeils=", + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "caw": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/caw/-/caw-1.2.0.tgz", + "integrity": "sha1-/7Im/n78VHKI3GLuPpcHPCEtEDQ=", + "requires": { + "get-proxy": "1.1.0", + "is-obj": "1.0.1", + "object-assign": "3.0.0", + "tunnel-agent": "0.4.3" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + } + } + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, + "chai-as-promised": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-6.0.0.tgz", + "integrity": "sha1-GgKkM6byTa+sY7nJb6FoTbGqjaY=", + "dev": true, + "requires": { + "check-error": "1.0.2" + } + }, + "chai-enzyme": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/chai-enzyme/-/chai-enzyme-0.6.1.tgz", + "integrity": "sha1-WFyWPG6hMxRG79Eu6DkegH11hiA=", + "dev": true, + "requires": { + "html": "1.0.0", + "react-element-to-jsx-string": "5.0.7" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "react-element-to-jsx-string": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-5.0.7.tgz", + "integrity": "sha1-xmOkgAqccSEVwNhRnLAhWkah8PI=", + "dev": true, + "requires": { + "collapse-white-space": "1.0.3", + "is-plain-object": "2.0.4", + "lodash": "4.17.4", + "sortobject": "1.1.1", + "stringify-object": "2.4.0", + "traverse": "0.6.6" + } + }, + "stringify-object": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-2.4.0.tgz", + "integrity": "sha1-xi0RAj6yH+LZsIe+A5om3zsioJ0=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0", + "is-regexp": "1.0.0" + } + } + } + }, + "chain-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz", + "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "change-emitter": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", + "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "dev": true, + "requires": { + "css-select": "1.2.0", + "dom-serializer": "0.1.0", + "entities": "1.1.1", + "htmlparser2": "3.9.2", + "lodash.assignin": "4.2.0", + "lodash.bind": "4.2.1", + "lodash.defaults": "4.2.0", + "lodash.filter": "4.6.0", + "lodash.flatten": "4.4.0", + "lodash.foreach": "4.5.0", + "lodash.map": "4.6.0", + "lodash.merge": "4.6.0", + "lodash.pick": "4.4.0", + "lodash.reduce": "4.6.0", + "lodash.reject": "4.6.0", + "lodash.some": "4.6.0" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + }, + "ci-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", + "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=" + }, + "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.3", + "safe-buffer": "5.1.1" + } + }, + "circular-dependency-plugin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-2.0.0.tgz", + "integrity": "sha1-wQeWyDOQSIqbzdQvAy1uZOmE9mA=", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "clap": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.0.tgz", + "integrity": "sha1-WckP4+E3EEdG/xlGmiemNP9oyFc=", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + }, + "classnames": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", + "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" + }, + "clean-css": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.7.tgz", + "integrity": "sha1-ua6k+FZ5iJzz6ui0A0nsTr390DI=", + "dev": true, + "requires": { + "source-map": "0.5.6" + } + }, + "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=", + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + }, + "clone-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.0.tgz", + "integrity": "sha1-6uCiQT9VwJQvgYwin+/OhF1/Oxw=", + "dev": true, + "requires": { + "is-regexp": "1.0.0", + "is-supported-regexp-flag": "1.0.0" + } + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "cmd-shim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", + "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1" + } + }, + "co": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "dev": true, + "requires": { + "q": "1.5.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=" + }, + "codemirror": { + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.28.0.tgz", + "integrity": "sha512-E/Z6050shti9v9ivl0dUClVRM4xaH204jsJmEpNYC6KDTlQwAz+5DdhLzn0tjaL/Mp1P0J1uhZokcSP2RFSwlA==" + }, + "collapse-white-space": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.3.tgz", + "integrity": "sha1-S5BvZw5aljqHt2sOFolkM0G2Ajw=" + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true, + "requires": { + "clone": "1.0.2", + "color-convert": "1.9.0", + "color-string": "0.3.0" + } + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "requires": { + "color-name": "1.1.3" + } + }, + "color-diff": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/color-diff/-/color-diff-0.1.7.tgz", + "integrity": "sha1-bbeM2UgqjkWdQIIer0tQMoPcuOI=", + "dev": true + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "colorguard": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/colorguard/-/colorguard-1.2.0.tgz", + "integrity": "sha1-8/rK9cquuk71RlPZ+yW7cxd8DYQ=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "color-diff": "0.1.7", + "log-symbols": "1.0.2", + "object-assign": "4.1.1", + "pipetteur": "2.0.3", + "plur": "2.1.2", + "postcss": "5.2.17", + "postcss-reporter": "1.4.1", + "text-table": "0.2.0", + "yargs": "1.3.3" + }, + "dependencies": { + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.2", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + }, + "yargs": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", + "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=", + "dev": true + } + } + }, + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true, + "requires": { + "color": "0.11.4", + "css-color-names": "0.0.4", + "has": "1.0.1" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "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.1" + } + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "commonmark": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.24.0.tgz", + "integrity": "sha1-uA3gGCxUY1VkOqFdsSv7KCNoJ48=", + "requires": { + "entities": "1.1.1", + "mdurl": "1.0.1", + "string.prototype.repeat": "0.2.0" + } + }, + "commonmark-react-renderer": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/commonmark-react-renderer/-/commonmark-react-renderer-4.3.3.tgz", + "integrity": "sha1-nEvKE4vIMoe655LM8TNzi+nLxvo=", + "requires": { + "in-publish": "2.0.0", + "lodash.assign": "4.2.0", + "lodash.isplainobject": "4.0.6", + "pascalcase": "0.1.1", + "xss-filters": "1.2.7" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + }, + "dependencies": { + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "console-stream": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", + "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", + "dev": true + }, + "content-type-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", + "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-to-clipboard": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz", + "integrity": "sha512-c3GdeY8qxCHGezVb1EFQfHYK/8NZRemgcTIzPq7PuxjHAf/raKibn2QdhHPb/y6q74PMgH6yizaDZlRmw6QyKw==", + "requires": { + "toggle-selection": "1.0.6" + } + }, + "copy-webpack-plugin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.0.1.tgz", + "integrity": "sha1-lyjjg7lDFgUNDHRjlY8rhcCqggA=", + "dev": true, + "requires": { + "bluebird": "2.11.0", + "fs-extra": "0.26.7", + "glob": "6.0.4", + "is-glob": "3.1.0", + "loader-utils": "0.2.17", + "lodash": "4.17.2", + "minimatch": "3.0.4", + "node-dir": "0.1.17" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" + }, + "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=" + }, + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "dev": true, + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.6.1", + "minimist": "1.2.0", + "object-assign": "4.1.1", + "os-homedir": "1.0.2", + "parse-json": "2.2.0", + "require-from-string": "1.2.1" + } + }, + "coveralls": { + "version": "2.11.16", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.11.16.tgz", + "integrity": "sha1-2pBhJlFC3e6VT2g3kSK+l76KtLE=", + "dev": true, + "requires": { + "js-yaml": "3.6.1", + "lcov-parse": "0.0.10", + "log-driver": "1.2.5", + "minimist": "1.2.0", + "request": "2.79.0" + }, + "dependencies": { + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.16.0", + "pinkie-promise": "2.0.1" + } + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.16", + "oauth-sign": "0.8.2", + "qs": "6.3.0", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.0.0" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + } + } + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "elliptic": "6.4.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "1.0.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.8" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.8" + } + }, + "create-thenable": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/create-thenable/-/create-thenable-1.0.2.tgz", + "integrity": "sha1-4gMXIMzJV12M+jH1wUbnYqgMBTQ=", + "dev": true, + "requires": { + "object.omit": "2.0.1", + "unique-concat": "0.2.2" + } + }, + "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=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.2.14" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.10.1" + } + }, + "crypto-browserify": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", + "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.12", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5" + } + }, + "crypto-js": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", + "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-loader": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.26.1.tgz", + "integrity": "sha1-K6fyATG5NZdJaz6btQB4WknNKeo=", + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "css-selector-tokenizer": "0.7.0", + "cssnano": "3.10.0", + "loader-utils": "0.2.17", + "lodash.camelcase": "4.3.0", + "object-assign": "4.1.1", + "postcss": "5.2.17", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0", + "source-list-map": "0.1.8" + } + }, + "css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "dev": true, + "requires": { + "css-tokenize": "1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "1.2.1", + "through2": "0.6.5" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "1.0.0", + "css-what": "2.1.0", + "domutils": "1.5.1", + "nth-check": "1.0.1" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "requires": { + "cssesc": "0.1.0", + "fastparse": "1.1.1", + "regexpu-core": "1.0.0" + }, + "dependencies": { + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "1.3.2", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + } + } + }, + "css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", + "dev": true + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "decamelize": "1.2.0", + "defined": "1.0.0", + "has": "1.0.1", + "object-assign": "4.1.1", + "postcss": "5.2.17", + "postcss-calc": "5.3.1", + "postcss-colormin": "2.2.2", + "postcss-convert-values": "2.6.1", + "postcss-discard-comments": "2.0.4", + "postcss-discard-duplicates": "2.1.0", + "postcss-discard-empty": "2.1.0", + "postcss-discard-overridden": "0.1.1", + "postcss-discard-unused": "2.2.3", + "postcss-filter-plugins": "2.0.2", + "postcss-merge-idents": "2.1.7", + "postcss-merge-longhand": "2.0.2", + "postcss-merge-rules": "2.1.2", + "postcss-minify-font-values": "1.0.5", + "postcss-minify-gradients": "1.0.5", + "postcss-minify-params": "1.2.2", + "postcss-minify-selectors": "2.1.1", + "postcss-normalize-charset": "1.1.1", + "postcss-normalize-url": "3.0.8", + "postcss-ordered-values": "2.2.3", + "postcss-reduce-idents": "2.4.0", + "postcss-reduce-initial": "1.0.1", + "postcss-reduce-transforms": "1.0.4", + "postcss-svgo": "2.1.6", + "postcss-unique-selectors": "2.0.2", + "postcss-value-parser": "3.3.0", + "postcss-zindex": "2.2.0" + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "requires": { + "clap": "1.2.0", + "source-map": "0.5.6" + } + }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "dev": true, + "requires": { + "cssom": "0.3.2" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "1.0.2" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.24" + } + }, + "d3-array": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.0.tgz", + "integrity": "sha1-FH0mlyDhdMQFen9CvosPPyulMQg=" + }, + "d3-collection": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", + "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" + }, + "d3-color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", + "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=" + }, + "d3-format": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.2.0.tgz", + "integrity": "sha1-a0gLqohohdRlHcJIqPSsnaFtsHo=" + }, + "d3-interpolate": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.5.tgz", + "integrity": "sha1-aeCZ/zkhRxblY8muw+qdHqS4p58=", + "requires": { + "d3-color": "1.0.3" + } + }, + "d3-path": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", + "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" + }, + "d3-scale": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.0.tgz", + "integrity": "sha1-C0F1yjHL5l4lRCfkZi3678NzRi0=", + "requires": { + "d3-array": "1.2.0", + "d3-collection": "1.0.4", + "d3-color": "1.0.3", + "d3-format": "1.2.0", + "d3-interpolate": "1.1.5", + "d3-time": "1.0.7", + "d3-time-format": "2.0.5" + } + }, + "d3-shape": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.0.0.tgz", + "integrity": "sha1-zKMySHV55Fc1TIg4oKKDvmOEWbo=", + "requires": { + "d3-path": "1.0.5" + } + }, + "d3-time": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.7.tgz", + "integrity": "sha1-lMr27bt4ebuAnQ0fdXK8SEgvcnA=" + }, + "d3-time-format": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.0.5.tgz", + "integrity": "sha1-nXeAIE98kRnJFwsaVttN6aivly4=", + "requires": { + "d3-time": "1.0.7" + } + }, + "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" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "date-difference": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/date-difference/-/date-difference-1.0.0.tgz", + "integrity": "sha1-0+bog8DK0tydv8vxLgYpe5cpiXQ=", + "requires": { + "get-stdin": "3.0.2", + "meow": "3.7.0" + } + }, + "date-now": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-1.0.1.tgz", + "integrity": "sha1-u30IZDjevkGCpIX7PfP7+5nWFTw=" + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=" + }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=" + }, + "debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.0.0.tgz", + "integrity": "sha1-CUivUT0uTOQHkW+FBqQj0/nPctg=", + "requires": { + "date-now": "1.0.1" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "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=" + }, + "decompress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-3.0.0.tgz", + "integrity": "sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0=", + "requires": { + "buffer-to-vinyl": "1.1.0", + "concat-stream": "1.6.0", + "decompress-tar": "3.1.0", + "decompress-tarbz2": "3.1.0", + "decompress-targz": "3.1.0", + "decompress-unzip": "3.4.0", + "stream-combiner2": "1.1.1", + "vinyl-assign": "1.2.1", + "vinyl-fs": "2.4.4" + } + }, + "decompress-tar": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-3.1.0.tgz", + "integrity": "sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY=", + "requires": { + "is-tar": "1.0.0", + "object-assign": "2.1.1", + "strip-dirs": "1.1.1", + "tar-stream": "1.5.4", + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "decompress-tarbz2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-3.1.0.tgz", + "integrity": "sha1-iyOTVoE1X58YnYclag+L3ZbZZm0=", + "requires": { + "is-bzip2": "1.0.0", + "object-assign": "2.1.1", + "seek-bzip": "1.0.5", + "strip-dirs": "1.1.1", + "tar-stream": "1.5.4", + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "decompress-targz": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-3.1.0.tgz", + "integrity": "sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA=", + "requires": { + "is-gzip": "1.0.0", + "object-assign": "2.1.1", + "strip-dirs": "1.1.1", + "tar-stream": "1.5.4", + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "decompress-unzip": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-3.4.0.tgz", + "integrity": "sha1-YUdbQVIGa74/7hL51inRX+ZHjus=", + "requires": { + "is-zip": "1.0.0", + "read-all-stream": "3.1.0", + "stat-mode": "0.2.2", + "strip-dirs": "1.1.1", + "through2": "2.0.3", + "vinyl": "1.2.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + } + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + } + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + }, + "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 + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "1.0.2" + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "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=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "requires": { + "repeating": "2.0.1" + } + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "miller-rabin": "4.0.0", + "randombytes": "2.0.5" + } + }, + "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" + } + }, + "doiuse": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-2.6.0.tgz", + "integrity": "sha1-GJLRC2Gpo1at2/K2FJM+gfi7ODQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000708", + "css-rule-stream": "1.1.0", + "duplexer2": "0.0.2", + "jsonfilter": "1.1.2", + "ldjson-stream": "1.2.1", + "lodash": "4.17.2", + "multimatch": "2.1.0", + "postcss": "5.2.17", + "source-map": "0.4.4", + "through2": "0.6.5", + "yargs": "3.32.0" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", + "dev": true + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "os-locale": "1.4.0", + "string-width": "1.0.2", + "window-size": "0.1.4", + "y18n": "3.2.1" + } + } + } + }, + "dom-converter": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", + "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "dev": true, + "requires": { + "utila": "0.3.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + } + } + }, + "dom-helpers": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.2.1.tgz", + "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo=" + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", + "dev": true + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "download": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/download/-/download-4.4.3.tgz", + "integrity": "sha1-qlX9rTktldS2jowr4D4MKqIbqaw=", + "requires": { + "caw": "1.2.0", + "concat-stream": "1.6.0", + "each-async": "1.1.1", + "filenamify": "1.2.1", + "got": "5.7.1", + "gulp-decompress": "1.2.0", + "gulp-rename": "1.2.2", + "is-url": "1.2.2", + "object-assign": "4.1.1", + "read-all-stream": "3.1.0", + "readable-stream": "2.3.3", + "stream-combiner2": "1.1.1", + "vinyl": "1.2.0", + "vinyl-fs": "2.4.4", + "ware": "1.3.0" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "requires": { + "browserify-aes": "1.0.6", + "create-hash": "1.1.3", + "create-hmac": "1.1.6" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "duplexify": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz", + "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=", + "requires": { + "end-of-stream": "1.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "stream-shift": "1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", + "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4=", + "requires": { + "once": "1.3.3" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1.0.2" + } + } + } + }, + "each-async": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz", + "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=", + "requires": { + "onetime": "1.1.0", + "set-immediate-shim": "1.0.1" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "editions": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.3.tgz", + "integrity": "sha1-CQcQG92iD6w8vjNMJ8vQaI3Jmls=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-1.0.0.tgz", + "integrity": "sha1-ycYKSKRu5FL7MqccMXuV5aofyz0=", + "dev": true + }, + "ejs-loader": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ejs-loader/-/ejs-loader-0.3.0.tgz", + "integrity": "sha1-aHNv3CMaSQ7fkZpkRq2dkFWlh74=", + "dev": true, + "requires": { + "loader-utils": "0.2.17", + "lodash": "3.10.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "ejsify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ejsify/-/ejsify-1.0.0.tgz", + "integrity": "sha1-NxlPWoXBKuQ4QpOVeZ7Ee0O8RT8=", + "dev": true, + "requires": { + "ejs": "1.0.0", + "through": "2.3.8" + } + }, + "electron-to-chromium": { + "version": "1.3.16", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.16.tgz", + "integrity": "sha1-0OAmc1dUdwkBrjAaIWZMukXZL30=", + "dev": true + }, + "element-resize-detector": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.1.12.tgz", + "integrity": "sha1-iz/W7t2hf5wAs2Cg6i35knroC6I=", + "requires": { + "batch-processor": "1.0.0" + } + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "requires": { + "bn.js": "4.11.7", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "empty-module": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/empty-module/-/empty-module-0.0.2.tgz", + "integrity": "sha1-E7TdjUr+3dNeUMGNzXiMUQh/FUU=", + "dev": true + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "dev": true + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.18" + } + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "requires": { + "once": "1.4.0" + } + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.7" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "enzyme": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-2.7.1.tgz", + "integrity": "sha1-djcOHZnpH3MJG7jEMUt8EozC1iE=", + "dev": true, + "requires": { + "cheerio": "0.22.0", + "function.prototype.name": "1.0.3", + "is-subset": "0.1.1", + "lodash": "4.17.2", + "object-is": "1.0.1", + "object.assign": "4.0.4", + "object.entries": "1.0.4", + "object.values": "1.0.4", + "uuid": "2.0.3" + }, + "dependencies": { + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + } + } + }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "dev": true, + "requires": { + "prr": "0.0.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "error-stack-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz", + "integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=", + "dev": true, + "requires": { + "stackframe": "0.3.1" + } + }, + "es-abstract": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.7.0.tgz", + "integrity": "sha1-363ndOAb/Nl/lhgCmMRJyGI/uUw=", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.0", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es5-ext": { + "version": "0.10.24", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz", + "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=", + "dev": true, + "requires": { + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "es6-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.0.0.tgz", + "integrity": "sha1-8JTHBB9mJZm7EnINoFnWucf/D0A=" + }, + "es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-iterator": "2.0.1", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-promise": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", + "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=" + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.24" + } + }, + "es6-templates": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", + "integrity": "sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=", + "dev": true, + "requires": { + "recast": "0.11.23", + "through": "2.3.8" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "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=" + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + }, + "dependencies": { + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.16.1.tgz", + "integrity": "sha1-m8MfxzQWks93LoBgdQj2fXEcVgk=", + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.8", + "doctrine": "1.5.0", + "escope": "3.6.0", + "espree": "3.4.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.3", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.6.1", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.2", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.1.0", + "figures": "1.7.0", + "lodash": "4.17.2", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + } + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + } + } + }, + "eslint-config-semistandard": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-7.0.0.tgz", + "integrity": "sha1-+ANJP1alFy9/WcNa5kg2C0Hy/3E=", + "dev": true + }, + "eslint-config-standard": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-6.2.1.tgz", + "integrity": "sha1-06aKr8cZFjnn7kQec0hzkCY1QpI=", + "dev": true + }, + "eslint-config-standard-jsx": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.3.0.tgz", + "integrity": "sha1-yrCAGhWjYL9j+suXqyL73YjYpeA=", + "dev": true + }, + "eslint-config-standard-react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-react/-/eslint-config-standard-react-4.2.0.tgz", + "integrity": "sha1-0V/SXoN+IK/w2zL2T7VdEYgOuNA=", + "dev": true, + "requires": { + "eslint-config-standard-jsx": "3.3.0" + } + }, + "eslint-plugin-promise": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz", + "integrity": "sha1-G+J5Pq/i0YtbEjuBNsJp+AT+cSI=", + "dev": true + }, + "eslint-plugin-react": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.0.tgz", + "integrity": "sha1-nEi0jRAVVLU1VBPnxkI4q95u8e8=", + "dev": true, + "requires": { + "array.prototype.find": "2.0.4", + "doctrine": "1.5.0", + "has": "1.0.1", + "jsx-ast-utils": "1.4.1", + "object.assign": "4.0.4" + } + }, + "eslint-plugin-standard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-2.0.1.tgz", + "integrity": "sha1-NYlpn/nJF/LCX3apFmh/ZBw2n/M=", + "dev": true + }, + "espree": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", + "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", + "dev": true, + "requires": { + "acorn": "5.1.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "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=" + }, + "etag": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", + "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=", + "dev": true + }, + "ethereum-common": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", + "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" + }, + "ethereumjs-tx": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.2.5.tgz", + "integrity": "sha1-7TbX/+uXvIicYe7xq3b0emE9goY=", + "requires": { + "ethereum-common": "0.0.18", + "ethereumjs-util": "5.1.2" + } + }, + "ethereumjs-util": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz", + "integrity": "sha1-JboCFcu0wvCxCKb5avKi5i5Fkh8=", + "requires": { + "babel-preset-es2015": "6.24.1", + "babelify": "7.3.0", + "bn.js": "4.11.7", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.3.0", + "rlp": "2.0.0", + "secp256k1": "3.3.0" + }, + "dependencies": { + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1" + } + } + } + }, + "ethjs-util": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.4.tgz", + "integrity": "sha1-HItoeSV0RO9NPz+7rC3tEs2ZfZM=", + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.24" + } + }, + "eventemitter3": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.2.tgz", + "integrity": "sha1-IM5IkZCc6fNbCIyU+rQOLJb0c6w=" + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", + "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "requires": { + "create-hash": "1.1.3" + } + }, + "exec-buffer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", + "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "p-finally": "1.0.0", + "pify": "3.0.0", + "rimraf": "2.6.1", + "tempfile": "2.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "exec-series": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/exec-series/-/exec-series-1.0.3.tgz", + "integrity": "sha1-bSV6m+rEgqhyx3g7yGFYOfx3FDo=", + "dev": true, + "requires": { + "async-each-series": "1.1.0", + "object-assign": "4.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "execall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", + "integrity": "sha1-c9CQTjlbPKsGWLCNCewlMH8pu3M=", + "dev": true, + "requires": { + "clone-regexp": "1.0.0" + } + }, + "executable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/executable/-/executable-1.1.0.tgz", + "integrity": "sha1-h3mA6REvM5EGbaNyZd562ENKtNk=", + "dev": true, + "requires": { + "meow": "3.7.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "2.2.3" + } + }, + "expand-template": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.0.3.tgz", + "integrity": "sha1-bDAzIxd6YrGyLAcCefeGEoe2mxo=" + }, + "express": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.14.1.tgz", + "integrity": "sha1-ZGwjf3ZvFIwhIK/wc4F7nk1+DTM=", + "dev": true, + "requires": { + "accepts": "1.3.3", + "array-flatten": "1.1.1", + "content-disposition": "0.5.2", + "content-type": "1.0.2", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.2.0", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.7.0", + "finalhandler": "0.5.1", + "fresh": "0.3.0", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.1", + "path-to-regexp": "0.1.7", + "proxy-addr": "1.1.5", + "qs": "6.2.0", + "range-parser": "1.2.0", + "send": "0.14.2", + "serve-static": "1.11.2", + "type-is": "1.6.15", + "utils-merge": "1.0.0", + "vary": "1.1.1" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "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=", + "dev": true + }, + "qs": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz", + "integrity": "sha1-O3hIwDwt7OaalSKw+ujEEm10Xzs=", + "dev": true + } + } + }, + "extend": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz", + "integrity": "sha1-oPX9bPyDpf5J72mNYOyKYk3UV2w=" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + }, + "external-editor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", + "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", + "requires": { + "iconv-lite": "0.4.18", + "jschardet": "1.5.0", + "tmp": "0.0.31" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + } + } + }, + "extract-loader": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/extract-loader/-/extract-loader-0.1.0.tgz", + "integrity": "sha1-ocFGkVJBzEhtUpImPHVV1aoZdm4=", + "dev": true, + "requires": { + "loader-utils": "0.2.17" + } + }, + "extract-text-webpack-plugin": { + "version": "2.0.0-beta.4", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.0.0-beta.4.tgz", + "integrity": "sha1-0yOTBp59kMgxjUg5IwJhi1a8G6k=", + "dev": true, + "requires": { + "async": "1.5.2", + "loader-utils": "0.2.17", + "webpack-sources": "0.1.5" + } + }, + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.1.0" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "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 + }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true + }, + "fbjs": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.14.tgz", + "integrity": "sha1-0dviviVMNakeCfMfnNUKQLKg7Rw=", + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.14" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + } + } + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "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=", + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.2.2", + "object-assign": "4.1.1" + } + }, + "file-loader": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.10.0.tgz", + "integrity": "sha1-u+bbdHSsksf1T9wZfPVH6YtrjhI=", + "dev": true, + "requires": { + "loader-utils": "0.2.17" + } + }, + "file-saver": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz", + "integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI=" + }, + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "filename-reserved-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", + "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=" + }, + "filenamify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", + "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", + "requires": { + "filename-reserved-regex": "1.0.0", + "strip-outer": "1.0.0", + "trim-repeated": "1.0.0" + } + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "7.1.2", + "minimatch": "3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "filesize": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.10.tgz", + "integrity": "sha1-/I+iPdtO+eXgq24eZPZ5okpWdh8=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "finalhandler": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz", + "integrity": "sha1-LEANjUUwk1vCMlScX6OF7Afeb80=", + "dev": true, + "requires": { + "debug": "2.2.0", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } + }, + "find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "find-versions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-1.2.1.tgz", + "integrity": "sha1-y96fEuOFdaCvG+G5osXV/Y8Ya2I=", + "dev": true, + "requires": { + "array-uniq": "1.0.3", + "get-stdin": "4.0.1", + "meow": "3.7.0", + "semver-regex": "1.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + } + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "flat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-2.0.1.tgz", + "integrity": "sha1-cOKRiKdL4MPIlAnu0fqVd5B64y8=", + "requires": { + "is-buffer": "1.1.5" + } + }, + "flat-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "1.0.2" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "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.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.16" + } + }, + "format-json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/format-json/-/format-json-1.0.3.tgz", + "integrity": "sha1-Jo49PhaXkv9Ju1sDDyLIfKHCzZ8=" + }, + "format-number": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/format-number/-/format-number-2.0.1.tgz", + "integrity": "sha1-6SMah0PKZLR9CVVdzkApY0O+Zus=" + }, + "formatio": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz", + "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", + "dev": true, + "requires": { + "samsam": "1.1.2" + } + }, + "forwarded": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", + "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=", + "dev": true + }, + "fresh": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", + "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=", + "dev": true + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.1" + } + }, + "fs-readdir-recursive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz", + "integrity": "sha1-jNF0XItPiinIyuw5JHaSG6GV9WA=", + "dev": true + }, + "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.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", + "dev": true + }, + "function.prototype.name": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.0.3.tgz", + "integrity": "sha512-5EblxZUdioXi2JiMZ9FUbwYj40eQ9MFHyzFLBSPdlRl3SO8l7SLWuAnQ/at/1Wi4hjJwME/C5WpF2ZfAc8nGNw==", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "function-bind": "1.1.0", + "is-callable": "1.1.3" + } + }, + "gather-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz", + "integrity": "sha1-szmUr0V6gRVwDUEPMXczy+egkEs=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "1.1.2", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "geopattern": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/geopattern/-/geopattern-1.2.3.tgz", + "integrity": "sha1-3pZgLkbbqQlcpXdL+zs2MI9+Y/4=", + "requires": { + "extend": "1.2.1" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "get-own-enumerable-property-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-1.0.1.tgz", + "integrity": "sha1-8dTjrRQC4DmJjlbR6bmqkkwm5IQ=" + }, + "get-proxy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-1.1.0.tgz", + "integrity": "sha1-iUhUSRvFkbDxR9euVw9cZ4tyVus=", + "requires": { + "rc": "1.2.1" + } + }, + "get-stdin": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz", + "integrity": "sha1-wc7SS5A5s43thb3xYeV3E7bdSr4=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "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" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "gifsicle": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-3.0.4.tgz", + "integrity": "sha1-9Fy17RAWW2ZdySng6TKLbIId+js=", + "dev": true, + "requires": { + "bin-build": "2.2.0", + "bin-wrapper": "3.0.2", + "logalot": "2.1.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + } + } + }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "dev": true, + "requires": { + "min-document": "2.19.0", + "process": "0.5.2" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "requires": { + "sparkles": "1.0.0" + } + }, + "got": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", + "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", + "requires": { + "create-error-class": "3.0.2", + "duplexer2": "0.1.4", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "node-status-codes": "1.0.0", + "object-assign": "4.1.1", + "parse-json": "2.2.0", + "pinkie-promise": "2.0.1", + "read-all-stream": "3.1.0", + "readable-stream": "2.3.3", + "timed-out": "3.1.3", + "unzip-response": "1.0.2", + "url-parse-lax": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "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.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "gulp-decompress": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gulp-decompress/-/gulp-decompress-1.2.0.tgz", + "integrity": "sha1-jutlpeAV+O2FMsr+KEVJYGJvDcc=", + "requires": { + "archive-type": "3.2.0", + "decompress": "3.0.0", + "gulp-util": "3.0.8", + "readable-stream": "2.3.3" + } + }, + "gulp-rename": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", + "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=" + }, + "gulp-sourcemaps": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", + "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", + "requires": { + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "strip-bom": "2.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + } + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "requires": { + "glogg": "1.0.0" + } + }, + "handlebars": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", + "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.16" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "happypack": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/happypack/-/happypack-3.0.3.tgz", + "integrity": "sha1-IveMh6MlzbeYyVjPTsOD/NTW/cc=", + "dev": true, + "requires": { + "async": "1.5.0", + "json-stringify-safe": "5.0.1", + "loader-utils": "0.2.16", + "mkdirp": "0.5.1" + }, + "dependencies": { + "async": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.0.tgz", + "integrity": "sha1-J5ZkJyNXOFlWVjP8YnRES+4vjOM=", + "dev": true + }, + "loader-utils": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.16.tgz", + "integrity": "sha1-8IYyBm7YKCg13/iN+1JwR2Wt7m0=", + "dev": true, + "requires": { + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" + } + } + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + } + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "requires": { + "sparkles": "1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "requires": { + "inherits": "2.0.3" + } + }, + "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" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "history": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", + "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=", + "requires": { + "invariant": "2.2.2", + "loose-envify": "1.3.1", + "query-string": "4.3.4", + "warning": "3.0.0" + } + }, + "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.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "hoist-non-react-statics": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", + "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + }, + "html": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz", + "integrity": "sha1-pUT6nqVJK/s6LMqCEKEL57WvH2E=", + "dev": true, + "requires": { + "concat-stream": "1.6.0" + } + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", + "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", + "dev": true, + "requires": { + "whatwg-encoding": "1.0.1" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, + "html-loader": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.4.4.tgz", + "integrity": "sha1-8rW5rNXgNf86tf02nBPJenuwFNo=", + "dev": true, + "requires": { + "es6-templates": "0.2.3", + "fastparse": "1.1.1", + "html-minifier": "3.5.3", + "loader-utils": "0.2.17", + "object-assign": "4.1.1" + } + }, + "html-minifier": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.3.tgz", + "integrity": "sha512-iKRzQQDuTCsq0Ultbi/mfJJnR0D3AdZKTq966Gsp92xkmAPCV4Xi08qhJ0Dl3ZAWemSgJ7qZK+UsZc0gFqK6wg==", + "dev": true, + "requires": { + "camel-case": "3.0.0", + "clean-css": "4.1.7", + "commander": "2.11.0", + "he": "1.1.1", + "ncname": "1.0.0", + "param-case": "2.1.1", + "relateurl": "0.2.7", + "uglify-js": "3.0.27" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "uglify-js": { + "version": "3.0.27", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.0.27.tgz", + "integrity": "sha512-HD8CmxPXUI62v5tweiulMcP/apAtx1DXGcNZkhKQZyC+MTrTsoCBb8yPAwVrbvpgw3EpRU76bRe6axjIiCYcQg==", + "dev": true, + "requires": { + "commander": "2.11.0", + "source-map": "0.5.6" + } + } + } + }, + "html-tags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-1.2.0.tgz", + "integrity": "sha1-x43mW1Zjqll5id0rerSSANfk25g=", + "dev": true + }, + "html-webpack-plugin": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.28.0.tgz", + "integrity": "sha1-LnhjtX5f1I/iYzA+L/yTTDBk0Ak=", + "dev": true, + "requires": { + "bluebird": "3.5.0", + "html-minifier": "3.5.3", + "loader-utils": "0.2.17", + "lodash": "4.17.4", + "pretty-error": "2.1.1", + "toposort": "1.0.3" + }, + "dependencies": { + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.4.1", + "domutils": "1.5.1", + "entities": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "http-errors": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz", + "integrity": "sha1-eIwNLB3iyBuebowBhDtrl+uSB1A=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "setprototypeof": "1.0.2", + "statuses": "1.3.1" + } + }, + "http-proxy": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "dev": true, + "requires": { + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" + }, + "dependencies": { + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + } + } + }, + "http-proxy-middleware": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.3.tgz", + "integrity": "sha1-lAOCFHFJuFYIT1U0dS1bWoFozR0=", + "dev": true, + "requires": { + "http-proxy": "1.16.2", + "is-glob": "3.1.0", + "lodash": "4.17.2", + "micromatch": "2.3.11" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.1" + } + }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "dev": true + }, + "humanize": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/humanize/-/humanize-0.0.9.tgz", + "integrity": "sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ=", + "dev": true + }, + "husky": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.13.1.tgz", + "integrity": "sha1-Ee/G/BDg7E54l3b2WCvjfXG6TM8=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "find-parent-dir": "0.3.0", + "is-ci": "1.0.10", + "normalize-path": "1.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + } + } + }, + "hyphenate-style-name": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz", + "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=" + }, + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "ignore": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", + "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", + "dev": true + }, + "ignore-styles": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ignore-styles/-/ignore-styles-5.0.1.tgz", + "integrity": "sha1-tJ7yJ0va/NikiAqWa/440aC/RnE=", + "dev": true + }, + "image-webpack-loader": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/image-webpack-loader/-/image-webpack-loader-3.2.0.tgz", + "integrity": "sha1-8mMG1gSNOi9ajYROyu3StxSPCk4=", + "dev": true, + "requires": { + "file-loader": "0.9.0", + "imagemin": "5.3.1", + "imagemin-gifsicle": "5.2.0", + "imagemin-mozjpeg": "6.0.0", + "imagemin-optipng": "5.2.1", + "imagemin-pngquant": "5.0.1", + "imagemin-svgo": "5.2.2", + "loader-utils": "0.2.17" + }, + "dependencies": { + "file-loader": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.9.0.tgz", + "integrity": "sha1-HS2t3UJM5tGwfP4/eXMb7TYXq0I=", + "dev": true, + "requires": { + "loader-utils": "0.2.17" + } + } + } + }, + "imagemin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-5.3.1.tgz", + "integrity": "sha1-8Zwu7h5xumxlWMUV+fyWaAGJptQ=", + "dev": true, + "requires": { + "file-type": "4.4.0", + "globby": "6.1.0", + "make-dir": "1.0.0", + "p-pipe": "1.2.0", + "pify": "2.3.0", + "replace-ext": "1.0.0" + }, + "dependencies": { + "file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + } + } + }, + "imagemin-gifsicle": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-5.2.0.tgz", + "integrity": "sha512-K01m5QuPK+0en8oVhiOOAicF7KjrHlCZxS++mfLI2mV/Ksfq/Y9nCXCWDz6jRv13wwlqe5T7hXT+ji2DnLc2yQ==", + "dev": true, + "requires": { + "exec-buffer": "3.2.0", + "gifsicle": "3.0.4", + "is-gif": "1.0.0" + } + }, + "imagemin-mozjpeg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-6.0.0.tgz", + "integrity": "sha1-caMqRXqhsmEXpo7u8tmxkMLlCR4=", + "dev": true, + "requires": { + "exec-buffer": "3.2.0", + "is-jpg": "1.0.0", + "mozjpeg": "4.1.1" + } + }, + "imagemin-optipng": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-5.2.1.tgz", + "integrity": "sha1-0i2kEsCfX/AKQzmWC5ioix2+hpU=", + "dev": true, + "requires": { + "exec-buffer": "3.2.0", + "is-png": "1.1.0", + "optipng-bin": "3.1.4" + } + }, + "imagemin-pngquant": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-5.0.1.tgz", + "integrity": "sha1-2KMp2lU6+iJrEc5i3r4Lfje0OeY=", + "dev": true, + "requires": { + "exec-buffer": "3.2.0", + "is-png": "1.1.0", + "pngquant-bin": "3.1.1" + } + }, + "imagemin-svgo": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-5.2.2.tgz", + "integrity": "sha1-UBaZ9XiXMKV5IrhzbqFcU/e1WDg=", + "dev": true, + "requires": { + "is-svg": "2.1.0", + "svgo": "0.7.2" + } + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=" + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "2.0.1" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + }, + "inline-style-prefixer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz", + "integrity": "sha1-wVPH6I/YT+9cYC6VqBaLJ3BnH+c=", + "requires": { + "bowser": "1.7.1", + "hyphenate-style-name": "1.0.2" + } + }, + "inquirer": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.1.tgz", + "integrity": "sha512-QgW3eiPN8gpj/K5vVpHADJJgrrF0ho/dZGylikGX7iqAdRgC9FVKYKWFLx6hZDBFcOLEoSqINYrVPeFAeG/PdA==", + "requires": { + "ansi-escapes": "2.0.0", + "chalk": "2.0.1", + "cli-cursor": "2.1.0", + "cli-width": "2.1.0", + "external-editor": "2.0.4", + "figures": "2.0.0", + "lodash": "4.17.2", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "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.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", + "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + }, + "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=" + }, + "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" + } + }, + "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" + } + }, + "supports-color": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", + "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "interpret": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "dev": true + }, + "intl-format-cache": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-2.0.5.tgz", + "integrity": "sha1-tITO/Lk1PzdPJd44mjzuoa8Y18k=" + }, + "intl-messageformat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-1.3.0.tgz", + "integrity": "sha1-99kmre16OrGbLcYB79VOmaS9Tq4=", + "requires": { + "intl-messageformat-parser": "1.2.0" + } + }, + "intl-messageformat-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.2.0.tgz", + "integrity": "sha1-WQa3+VOrdHDg3IVJCXtki5kYkv8=" + }, + "intl-relativeformat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/intl-relativeformat/-/intl-relativeformat-1.3.0.tgz", + "integrity": "sha1-iT3HB2/M04DPCRojAMOA+les5Fs=", + "requires": { + "intl-messageformat": "1.3.0" + } + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "requires": { + "loose-envify": "1.3.1" + } + }, + "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=" + }, + "ip-regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz", + "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=", + "dev": true + }, + "ipaddr.js": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", + "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=", + "dev": true + }, + "irregular-plurals": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.3.0.tgz", + "integrity": "sha512-njf5A+Mxb3kojuHd1DzISjjIl+XhyzovXEOyPPSzdQozq/Lf2tN27mOrAAsxEPZxpn6I4MGzs1oo9TxXxPFpaA==", + "dev": true + }, + "is-absolute": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", + "integrity": "sha1-hHSREZ/MtftDYhfMc39/qtUPYD8=", + "requires": { + "is-relative": "0.1.3" + } + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.9.0" + } + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-bzip2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-bzip2/-/is-bzip2-1.0.0.tgz", + "integrity": "sha1-XuWOqlounIDiFAe+3yOuWsCRs/w=" + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "requires": { + "ci-info": "1.0.0" + } + }, + "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=", + "dev": true + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-dom": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/is-dom/-/is-dom-1.0.9.tgz", + "integrity": "sha1-SDgy1SlyBz3hK5/j9gMghw2oNw0=" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "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.1" + } + }, + "is-gif": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-1.0.0.tgz", + "integrity": "sha1-ptKumIkwB7/6l6HYwB1jIFgyCX4=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-gzip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", + "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=" + }, + "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-jpg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-1.0.0.tgz", + "integrity": "sha1-KVnBfnNDDbOCZNp1uQ3VTy2G2hw=", + "dev": true + }, + "is-my-json-valid": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-natural-number": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-2.1.1.tgz", + "integrity": "sha1-fUxXKDd+84bD4ZSpkRv1fG3DNec=" + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "3.2.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "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==", + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "is-png": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz", + "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84=", + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, + "is-relative": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz", + "integrity": "sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI=" + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } + }, + "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-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "is-supported-regexp-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz", + "integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g=", + "dev": true + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true, + "requires": { + "html-comment-regex": "1.1.1" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-tar": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-tar/-/is-tar-1.0.0.tgz", + "integrity": "sha1-L2suF5LB9bs2UZrKqdZcDSb+hT0=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-url": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", + "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=" + }, + "is-zip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-zip/-/is-zip-1.0.0.tgz", + "integrity": "sha1-R7Co/004p2QxzP2ZqOFaTIa6IyU=" + }, + "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": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.7.1", + "whatwg-fetch": "2.0.1" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul": { + "version": "1.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-1.0.0-alpha.2.tgz", + "integrity": "sha1-BglrwI6Yuq10Sq5Gli2N+frGPQg=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "istanbul-api": "1.1.11", + "js-yaml": "3.6.1", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "which": "1.2.14", + "wordwrap": "1.0.0" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "istanbul-api": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.11.tgz", + "integrity": "sha1-/MC0YeKzvaceMFFVE4I4doJX2d4=", + "dev": true, + "requires": { + "async": "2.5.0", + "fileset": "2.0.3", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-hook": "1.0.7", + "istanbul-lib-instrument": "1.7.4", + "istanbul-lib-report": "1.1.1", + "istanbul-lib-source-maps": "1.2.1", + "istanbul-reports": "1.1.1", + "js-yaml": "3.9.1", + "mkdirp": "0.5.1", + "once": "1.4.0" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.2" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "js-yaml": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", + "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + } + } + }, + "istanbul-lib-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", + "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", + "dev": true, + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz", + "integrity": "sha1-6f2SDkdn89Ge3HZeLWs/XMvQ7qg=", + "dev": true, + "requires": { + "babel-generator": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "istanbul-lib-coverage": "1.1.1", + "semver": "5.4.1" + } + }, + "istanbul-lib-report": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", + "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", + "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==", + "dev": true, + "requires": { + "debug": "2.6.8", + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "rimraf": "2.6.1", + "source-map": "0.5.6" + } + }, + "istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-P8G873A0kW24XRlxHVGhMJBhQ8gWAec+dae7ZxOBzxT4w+a9ATSPvRVK3LB1RAJ9S8bg2tOyWHAGW40Zd2dKfw==", + "dev": true, + "requires": { + "handlebars": "4.0.10" + } + }, + "js-base64": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", + "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=", + "dev": true + }, + "js-sha3": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", + "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jschardet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.0.tgz", + "integrity": "sha512-+Q8JsoEQbrdE+a/gg1F9XO92gcKXgpE5UACqr0sIubjDmBEkd+OOWPGzQeMrWSLxd73r4dHxBeRW7edHu5LmJQ==" + }, + "jsdom": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.11.0.tgz", + "integrity": "sha1-qVsDBOUhospaY8bqR793CKeoRZE=", + "dev": true, + "requires": { + "abab": "1.0.3", + "acorn": "4.0.13", + "acorn-globals": "3.1.0", + "array-equal": "1.0.0", + "content-type-parser": "1.0.1", + "cssom": "0.3.2", + "cssstyle": "0.2.37", + "escodegen": "1.8.1", + "html-encoding-sniffer": "1.0.1", + "nwmatcher": "1.4.1", + "parse5": "1.5.1", + "request": "2.81.0", + "sax": "1.2.4", + "symbol-tree": "3.2.2", + "tough-cookie": "2.3.2", + "webidl-conversions": "4.0.1", + "whatwg-encoding": "1.0.1", + "whatwg-url": "4.8.0", + "xml-name-validator": "2.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + }, + "json-loader": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.4.tgz", + "integrity": "sha1-i6oTZaYy9Yo8RtIBdfxgAsluN94=", + "dev": true + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + } + }, + "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=" + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonfilter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/jsonfilter/-/jsonfilter-1.1.2.tgz", + "integrity": "sha1-Ie987cdRk4E8dZMulqmL4gW6WhE=", + "dev": true, + "requires": { + "JSONStream": "0.8.4", + "minimist": "1.2.0", + "stream-combiner": "0.2.2", + "through2": "0.6.5" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonparse": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", + "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "JSONStream": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz", + "integrity": "sha1-kWV9/m/4V0gwZhMrRhi2Lo9Ih70=", + "dev": true, + "requires": { + "jsonparse": "0.0.5", + "through": "2.3.8" + } + }, + "jsprim": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "jsqr": { + "version": "git+https://github.com/JodusNodus/jsQR.git#5ba1acefa1cbb9b2bc92b49f503f2674e2ec212b" + }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", + "dev": true + }, + "keccak": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.3.0.tgz", + "integrity": "sha512-JgsKPxYhcJxKrV+TrCyg/GwZbOjhpRPrz2kG8xbAsUaIDelUlKjm08YcwBO9Fm8sqf/Kg8ZWkk6nWujhLykfvw==", + "requires": { + "bindings": "1.3.0", + "inherits": "2.0.3", + "nan": "2.6.2", + "prebuild-install": "2.2.1", + "safe-buffer": "5.1.1" + } + }, + "keycode": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.1.9.tgz", + "integrity": "sha1-lkojxU5IiUBbSGGlyfBIDUUUHfo=" + }, + "keythereum": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/keythereum/-/keythereum-0.4.6.tgz", + "integrity": "sha1-D97Hz5OK455eMGGy9uFmd7dmxdo=", + "requires": { + "elliptic": "6.4.0", + "ethereumjs-util": "5.1.1", + "sjcl": "1.0.6", + "uuid": "3.0.0", + "validator": "4.0.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.1.tgz", + "integrity": "sha1-Ei+zjep0fcYrOuv8Nl0b1Ivktz4=", + "requires": { + "bn.js": "4.11.7", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.3.0", + "rlp": "2.0.0", + "secp256k1": "3.3.0" + } + }, + "validator": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/validator/-/validator-4.0.2.tgz", + "integrity": "sha1-cKHCUl7EdE5AmXHBspiqaadTQlE=" + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.5" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "known-css-properties": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.0.6.tgz", + "integrity": "sha1-caC4/eG240McRx77w9lzP667z78=", + "dev": true + }, + "laggard": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/laggard/-/laggard-0.1.0.tgz", + "integrity": "sha1-Lv1kX38tjz0nrICAOcqGqO40EHU=", + "dev": true, + "requires": { + "minimist": "1.2.0", + "pixrem": "3.0.2", + "postcss": "5.2.17", + "postcss-color-rgba-fallback": "2.2.0", + "postcss-opacity": "3.0.0", + "postcss-pseudoelements": "3.0.0", + "postcss-reporter": "1.4.1", + "postcss-vmin": "2.0.0", + "postcss-will-change": "1.1.0", + "read-file-stdin": "0.2.1", + "write-file-stdout": "0.0.2" + }, + "dependencies": { + "postcss-opacity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity/-/postcss-opacity-3.0.0.tgz", + "integrity": "sha1-eHm8xzRAW/dKpsgcORdiBS/FWyk=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.2", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + } + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lazy-req": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", + "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "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" + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "dev": true + }, + "ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "dev": true, + "requires": { + "split2": "0.2.1", + "through2": "0.6.5" + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, + "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" + } + }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "requires": { + "immediate": "3.0.6" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "requires": { + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" + } + }, + "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" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz", + "integrity": "sha1-NKMFW6vgTOQkZ7YH1wAHLH/2v0I=" + }, + "lodash-es": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz", + "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc=" + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash.keys": "3.1.2" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", + "dev": true + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "3.2.0", + "lodash._basecreate": "3.0.3", + "lodash._isiterateecall": "3.0.9" + } + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "requires": { + "lodash._root": "3.0.1" + } + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", + "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=" + }, + "lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=" + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=" + }, + "lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", + "dev": true + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", + "dev": true + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", + "dev": true + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-driver": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", + "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + }, + "logalot": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", + "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=", + "dev": true, + "requires": { + "figures": "1.7.0", + "squeak": "1.3.0" + }, + "dependencies": { + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + } + } + }, + "loglevel": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.4.1.tgz", + "integrity": "sha1-lbOD+Ro8J1b9SrCTZn5DCRYfK80=" + }, + "lolex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", + "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + }, + "lpad-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", + "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "indent-string": "2.1.0", + "longest": "1.0.1", + "meow": "3.7.0" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + } + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "macaddress": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", + "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", + "dev": true + }, + "make-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", + "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "markdown-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-loader/-/markdown-loader-2.0.0.tgz", + "integrity": "sha1-Qhhi04xCJP02FetkgBfqOFtWLXg=", + "dev": true, + "requires": { + "loader-utils": "0.2.17", + "marked": "0.3.6" + } + }, + "marked": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz", + "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=" + }, + "material-ui": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/material-ui/-/material-ui-0.16.5.tgz", + "integrity": "sha1-u4ZhqsfKyMsiOj529PV+4YpK78E=", + "requires": { + "babel-runtime": "6.23.0", + "inline-style-prefixer": "2.0.5", + "keycode": "2.1.9", + "lodash.merge": "4.6.0", + "lodash.throttle": "4.1.1", + "react-addons-create-fragment": "15.6.0", + "react-addons-transition-group": "15.6.0", + "react-event-listener": "0.4.1", + "recompose": "0.20.2", + "simple-assign": "0.1.0", + "warning": "3.0.0" + } + }, + "material-ui-chip-input": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/material-ui-chip-input/-/material-ui-chip-input-0.11.1.tgz", + "integrity": "sha1-6Sssxcl0HNddaxgi8cd3GtTObBA=" + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "miller-rabin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", + "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "brorand": "1.1.0" + } + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "dev": true + }, + "mime-db": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", + "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=" + }, + "mime-types": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", + "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", + "requires": { + "mime-db": "1.29.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "requires": { + "dom-walk": "0.1.1" + } + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" + }, + "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.8" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "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" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "mobx": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-2.6.4.tgz", + "integrity": "sha1-4FqRpbLJfaw/2rNAJOa3Sn9DEas=" + }, + "mobx-react": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-4.0.3.tgz", + "integrity": "sha1-QOsx0l4LjWMEjtojdsxWv6vRT3U=", + "requires": { + "hoist-non-react-statics": "1.2.0" + } + }, + "mobx-react-devtools": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/mobx-react-devtools/-/mobx-react-devtools-4.2.10.tgz", + "integrity": "sha1-eSdL2NRLoE2VByhzihRFQfoqYBI=" + }, + "mocha": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.2.0.tgz", + "integrity": "sha1-fcT0XlCIB1FxpoiWgU5q6et6heM=", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.5", + "glob": "7.0.5", + "growl": "1.9.2", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "glob": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", + "integrity": "sha1-tCAqaQmbu00pKnwblbZoK2fr3JU=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "mock-local-storage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mock-local-storage/-/mock-local-storage-1.0.2.tgz", + "integrity": "sha1-plplzdq0cHQz1Suk6fa2MIS4wpg=", + "dev": true, + "requires": { + "core-js": "0.8.4" + }, + "dependencies": { + "core-js": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-0.8.4.tgz", + "integrity": "sha1-wiZl8eDRucPF4bCNq9HxCGleT88=", + "dev": true + } + } + }, + "mock-socket": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-6.0.4.tgz", + "integrity": "sha1-hfWKCqg7wdtMp9FLQtj53WY+dWk=", + "dev": true + }, + "moment": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.17.0.tgz", + "integrity": "sha1-pMKS4CqsXd77Kabu0k9Rk43Tt08=" + }, + "mozjpeg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-4.1.1.tgz", + "integrity": "sha1-hZAwsk9omlPbm0DwFg2JGVuI/VA=", + "dev": true, + "requires": { + "bin-build": "2.2.0", + "bin-wrapper": "3.0.2", + "logalot": "2.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + } + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "1.1.14" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "nan": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" + }, + "napa": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/napa/-/napa-2.3.0.tgz", + "integrity": "sha1-QZZUbRoLa7lPNwQgU8xd3XlzHlM=", + "requires": { + "download": "4.4.3", + "extend": "3.0.1", + "load-json-file": "1.1.0", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "npm-cache-filename": "1.0.2", + "npmlog": "2.0.4", + "rimraf": "2.6.1", + "tar-pack": "3.4.0", + "write-json-file": "1.2.0" + }, + "dependencies": { + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", + "requires": { + "ansi": "0.3.1", + "has-unicode": "2.0.1", + "lodash.pad": "4.5.1", + "lodash.padend": "4.6.1", + "lodash.padstart": "4.6.1" + } + }, + "npmlog": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", + "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "requires": { + "ansi": "0.3.1", + "are-we-there-yet": "1.1.4", + "gauge": "1.2.7" + } + } + } + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "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 + }, + "ncname": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", + "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", + "dev": true, + "requires": { + "xml-char-classes": "1.0.0" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "no-case": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.1.tgz", + "integrity": "sha1-euuhxzpSGEJlVUt9wDuvcg34AIE=", + "dev": true, + "requires": { + "lower-case": "1.1.4" + } + }, + "nock": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.0.7.tgz", + "integrity": "sha1-zJNIG7FfOL7Co5xEQr4HglI1saE=", + "dev": true, + "requires": { + "chai": "3.5.0", + "debug": "2.6.8", + "deep-equal": "1.0.1", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.2", + "mkdirp": "0.5.1", + "propagate": "0.4.0", + "qs": "6.3.0" + } + }, + "node-abi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.0.tgz", + "integrity": "sha512-AbW35CPRE4vdieOse46V+16dKispLNv3PQwgqlcfg7GQeQHcLu3gvp3fbU2gTh7d8NfGjp5CJh+j4Hpyb0XzaA==" + }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "dev": true, + "requires": { + "minimatch": "3.0.4" + } + }, + "node-emoji": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz", + "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==", + "requires": { + "lodash.toarray": "4.4.0" + } + }, + "node-fetch": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz", + "integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "node-gyp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", + "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "requires": { + "fstream": "1.0.11", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.1.2", + "osenv": "0.1.4", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.2.14" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "node-libs-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", + "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.1.4", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.11.1", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "0.0.1", + "os-browserify": "0.2.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.3", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "0.10.31", + "timers-browserify": "2.0.3", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "node-status-codes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=" + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.0" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.0.2" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "prepend-http": "1.0.4", + "query-string": "4.3.4", + "sort-keys": "1.1.2" + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz", + "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=" + }, + "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=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "dev": true, + "requires": { + "boolbase": "1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "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=" + }, + "nwmatcher": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.1.tgz", + "integrity": "sha1-eumwew6oBNt+JfBctf5Al9TklJ8=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + }, + "object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "function-bind": "1.1.0", + "object-keys": "1.0.11" + } + }, + "object.entries": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz", + "integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.7.0", + "function-bind": "1.1.0", + "has": "1.0.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "object.values": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.0.4.tgz", + "integrity": "sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.7.0", + "function-bind": "1.1.0", + "has": "1.0.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onecolor": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.4.tgz", + "integrity": "sha1-daRvgNpseqpbTarhekcZi9llJJQ=", + "dev": true + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "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.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "optipng-bin": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-3.1.4.tgz", + "integrity": "sha1-ldNPLEiHBPb9cGBr/qDGWfHZXYQ=", + "dev": true, + "requires": { + "bin-build": "2.2.0", + "bin-wrapper": "3.0.2", + "logalot": "2.1.0" + } + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "dev": true + }, + "os-filter-obj": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-1.0.3.tgz", + "integrity": "sha1-WRUzDZDs7VV9LZOKMcbdIU2cY60=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "1.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=" + }, + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "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-pipe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz", + "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "2.3.1" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.1", + "browserify-aes": "1.0.6", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.0", + "pbkdf2": "3.0.12" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "dev": true + }, + "parseurl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "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=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pbkdf2": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz", + "integrity": "sha1-vjZ4XFBn6kjYBv+SMojF91C2uKI=", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.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=" + }, + "phoneformat.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/phoneformat.js/-/phoneformat.js-1.0.3.tgz", + "integrity": "sha1-Eb40dOdkdFQP43NMwz8aZYQdX4c=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "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.4" + } + }, + "pipetteur": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pipetteur/-/pipetteur-2.0.3.tgz", + "integrity": "sha1-GVV2CVno0aEcsqUOyD7sRwYz5J8=", + "dev": true, + "requires": { + "onecolor": "3.0.4", + "synesthesia": "1.0.1" + } + }, + "pixrem": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pixrem/-/pixrem-3.0.2.tgz", + "integrity": "sha1-MNG6+0w73Ojpu0vVahOYVhkyDDQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "postcss": "5.2.17", + "reduce-css-calc": "1.3.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true, + "requires": { + "irregular-plurals": "1.3.0" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "pngquant-bin": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-3.1.1.tgz", + "integrity": "sha1-0STZinWpSH9AwWQLTb/Lsr1aH9E=", + "dev": true, + "requires": { + "bin-build": "2.2.0", + "bin-wrapper": "3.0.2", + "logalot": "2.1.0" + } + }, + "postcss": { + "version": "5.2.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", + "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "js-base64": "2.1.9", + "source-map": "0.5.6", + "supports-color": "3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-alias": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-alias/-/postcss-alias-1.0.0.tgz", + "integrity": "sha1-Bwxh7hGXr27l63XSat9IiZudL3s=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-message-helpers": "2.0.0", + "reduce-css-calc": "1.3.0" + } + }, + "postcss-clearfix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-clearfix/-/postcss-clearfix-1.0.0.tgz", + "integrity": "sha1-r+xqDgHSXaw2pUrbif/Uv+HSGa8=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-color-rgba-fallback": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgba-fallback/-/postcss-color-rgba-fallback-2.2.0.tgz", + "integrity": "sha1-bSlJG+WZCpMXPUfnx29YELCUAro=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0", + "rgb-hex": "1.0.0" + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true, + "requires": { + "colormin": "1.1.2", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "uniqs": "2.0.0" + } + }, + "postcss-easings": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/postcss-easings/-/postcss-easings-0.3.0.tgz", + "integrity": "sha1-I9zL+XWH4o1doZw7rktQaYxarV4=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-filter-plugins": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", + "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "uniqid": "4.1.1" + } + }, + "postcss-fontpath": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/postcss-fontpath/-/postcss-fontpath-0.3.0.tgz", + "integrity": "sha1-KBQqed0Y8snwv1yH96PreUxTkp4=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.17" + } + }, + "postcss-hexrgba": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/postcss-hexrgba/-/postcss-hexrgba-0.2.1.tgz", + "integrity": "sha1-XGGrukOcCjjknn+8CzzZNhGewiU=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-import": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-9.1.0.tgz", + "integrity": "sha1-lf6YdqHnmvSfvcNYnwH+WqfMHoA=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0", + "promise-each": "2.2.0", + "read-cache": "1.0.0", + "resolve": "1.4.0" + } + }, + "postcss-input-style": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/postcss-input-style/-/postcss-input-style-0.3.0.tgz", + "integrity": "sha1-47T9sKpEG+0ZMMu0TYrVY0zzhUA=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-less": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz", + "integrity": "sha1-xjGwicbM5CK5oQ86lY0r7dOBkyQ=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1", + "postcss-load-options": "1.2.0", + "postcss-load-plugins": "2.3.0" + } + }, + "postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-loader": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-1.3.2.tgz", + "integrity": "sha1-xWi2HC5I4nThwiSiWH+1ZvTsJvU=", + "dev": true, + "requires": { + "loader-utils": "1.1.0", + "object-assign": "4.1.1", + "postcss": "5.2.17", + "postcss-load-config": "1.2.0" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + } + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-api": "1.6.1", + "postcss": "5.2.17", + "postcss-selector-parser": "2.2.3", + "vendors": "1.0.1" + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0", + "uniqs": "2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "has": "1.0.1", + "postcss": "5.2.17", + "postcss-selector-parser": "2.2.3" + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "dev": true, + "requires": { + "postcss": "6.0.8" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", + "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + }, + "postcss": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.8.tgz", + "integrity": "sha512-G6WnRmdTt2jvJvY+aY+M0AO4YlbxE+slKPZb+jG2P2U9Tyxi3h1fYZ/DgiFU6DC6bv3XIEJoZt+f/kNh8BrWFw==", + "dev": true, + "requires": { + "chalk": "2.0.1", + "source-map": "0.5.6", + "supports-color": "4.2.1" + } + }, + "supports-color": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", + "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.8" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", + "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + }, + "postcss": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.8.tgz", + "integrity": "sha512-G6WnRmdTt2jvJvY+aY+M0AO4YlbxE+slKPZb+jG2P2U9Tyxi3h1fYZ/DgiFU6DC6bv3XIEJoZt+f/kNh8BrWFw==", + "dev": true, + "requires": { + "chalk": "2.0.1", + "source-map": "0.5.6", + "supports-color": "4.2.1" + } + }, + "supports-color": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", + "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.8" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", + "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + }, + "postcss": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.8.tgz", + "integrity": "sha512-G6WnRmdTt2jvJvY+aY+M0AO4YlbxE+slKPZb+jG2P2U9Tyxi3h1fYZ/DgiFU6DC6bv3XIEJoZt+f/kNh8BrWFw==", + "dev": true, + "requires": { + "chalk": "2.0.1", + "source-map": "0.5.6", + "supports-color": "4.2.1" + } + }, + "supports-color": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", + "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.8" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", + "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + }, + "postcss": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.8.tgz", + "integrity": "sha512-G6WnRmdTt2jvJvY+aY+M0AO4YlbxE+slKPZb+jG2P2U9Tyxi3h1fYZ/DgiFU6DC6bv3XIEJoZt+f/kNh8BrWFw==", + "dev": true, + "requires": { + "chalk": "2.0.1", + "source-map": "0.5.6", + "supports-color": "4.2.1" + } + }, + "supports-color": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", + "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-nested": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-1.0.0.tgz", + "integrity": "sha1-0Ta9S1dr1WMt8ULBKyGYqcz3lN8=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true, + "requires": { + "is-absolute-url": "2.1.0", + "normalize-url": "1.9.1", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-opacity": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity/-/postcss-opacity-4.0.0.tgz", + "integrity": "sha1-qlYgQ9ozlMlKOs7c9D8MMj0JhqE=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-position": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/postcss-position/-/postcss-position-0.5.0.tgz", + "integrity": "sha1-hlPU8LhP+wflRPt/fq4IxlUbc6A=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-pseudoelements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudoelements/-/postcss-pseudoelements-3.0.0.tgz", + "integrity": "sha1-bGghd8eQC6BTtt8X+MWQKEx7i7w=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-quantity-queries": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/postcss-quantity-queries/-/postcss-quantity-queries-0.4.0.tgz", + "integrity": "sha1-vhNwp76TEqFzY5wIaapCECRPhs4=", + "dev": true, + "requires": { + "balanced-match": "0.2.1", + "postcss": "5.2.17" + }, + "dependencies": { + "balanced-match": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.1.tgz", + "integrity": "sha1-e8ZYtL7WHu5CStdPdfXD4sTfPMc=", + "dev": true + } + } + }, + "postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true, + "requires": { + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reporter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-2.0.0.tgz", + "integrity": "sha1-0l50un/OkR4qpy7BrlkvrebsNnE=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.2", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "postcss-responsive-type": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/postcss-responsive-type/-/postcss-responsive-type-0.5.1.tgz", + "integrity": "sha1-J0EzvARjWeVCpYu8YhhH0ED9EOY=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-scss": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-0.4.1.tgz", + "integrity": "sha1-rXcbgfD3L19IRdCKpg+TVXZT1Uw=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + } + }, + "postcss-simple-vars": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-simple-vars/-/postcss-simple-vars-3.0.0.tgz", + "integrity": "sha1-H6TMtLcVHZ8NUvuOoZoVwTGVmdY=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, + "requires": { + "is-svg": "2.1.0", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0", + "svgo": "0.7.2" + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.17", + "uniqs": "2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "postcss-vmin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-vmin/-/postcss-vmin-2.0.0.tgz", + "integrity": "sha1-UyfCEZE3ElaGj9enOZF/FHTVf+4=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-will-change": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-will-change/-/postcss-will-change-1.1.0.tgz", + "integrity": "sha1-plHdWoHoLEEtOabPkKkrsyaa8Yw=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.17", + "uniqs": "2.0.0" + } + }, + "prebuild-install": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.1.tgz", + "integrity": "sha512-y/sgNJ49vjXQ3qYdSI/jTRZq6D7g5Q2euK6x0/L8dvwK1EGvNLidtg2t4PZzTgkR6LahkzpYVshOmHKYtp0AlQ==", + "requires": { + "expand-template": "1.0.3", + "github-from-package": "0.0.0", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "node-abi": "2.1.0", + "noop-logger": "0.1.1", + "npmlog": "4.1.2", + "os-homedir": "1.0.2", + "pump": "1.0.2", + "rc": "1.2.1", + "simple-get": "1.4.3", + "tar-fs": "1.15.3", + "tunnel-agent": "0.6.0", + "xtend": "4.0.1" + } + }, + "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=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "dev": true, + "requires": { + "renderkid": "2.0.1", + "utila": "0.4.0" + } + }, + "private": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=" + }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", + "dev": true + }, + "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": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "progress-bar-webpack-plugin": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/progress-bar-webpack-plugin/-/progress-bar-webpack-plugin-1.9.3.tgz", + "integrity": "sha1-gfuL2OONpu2vmiC+7Xm9l43WPCo=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "object.assign": "4.0.4", + "progress": "1.1.8" + } + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "promise-each": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promise-each/-/promise-each-2.2.0.tgz", + "integrity": "sha1-M1MXTv8mlEgQN+BOAfd6oPttG2A=", + "dev": true, + "requires": { + "any-promise": "0.1.0" + } + }, + "promise-worker": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-worker/-/promise-worker-1.1.1.tgz", + "integrity": "sha1-wrddBF0kliXAImTi3/mtIuAxxps=", + "requires": { + "is-promise": "2.1.0", + "lie": "3.1.1" + } + }, + "prop-types": { + "version": "15.5.10", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.5.10.tgz", + "integrity": "sha1-J5ffwxJhguOpXj37suiT3ddFYVQ=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1" + } + }, + "propagate": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", + "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", + "dev": true + }, + "proper-lockfile": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-2.0.1.tgz", + "integrity": "sha1-FZ+wYZPTIAP0s2kd0uwaY0qoDR0=", + "requires": { + "graceful-fs": "4.1.11", + "retry": "0.10.1" + } + }, + "proxy-addr": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", + "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", + "dev": true, + "requires": { + "forwarded": "0.1.0", + "ipaddr.js": "1.4.0" + } + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.7", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, + "pump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", + "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "requires": { + "end-of-stream": "1.4.0", + "once": "1.4.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "push.js": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/push.js/-/push.js-0.0.11.tgz", + "integrity": "sha1-T606n5CEQhLiqmfQc6I9Rw4yqJE=" + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "dev": true + }, + "qs": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.0.tgz", + "integrity": "sha1-9AOyZPI7wBIox0ExtAfxjV6l1EI=" + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "raf": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.3.2.tgz", + "integrity": "sha1-DBO+C1tJtG921maSSNUnzysC/ic=", + "requires": { + "performance-now": "2.1.0" + } + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", + "dev": true + }, + "rc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + } + }, + "react": { + "version": "15.4.2", + "resolved": "https://registry.npmjs.org/react/-/react-15.4.2.tgz", + "integrity": "sha1-QfeZGyYYU5K6m66WyIiefgGDl+8=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "react-ace": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-4.1.0.tgz", + "integrity": "sha1-ZZ+qAQ0XP2DWqJQPCzJcXkIsq1Q=", + "requires": { + "brace": "0.8.0", + "lodash.isequal": "4.5.0" + }, + "dependencies": { + "brace": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/brace/-/brace-0.8.0.tgz", + "integrity": "sha1-6CbG1QVMrl9getexyBI23SzwGXg=", + "requires": { + "w3c-blob": "0.0.1" + } + } + } + }, + "react-addons-create-fragment": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-addons-create-fragment/-/react-addons-create-fragment-15.6.0.tgz", + "integrity": "sha1-r5GiKx+wld0B8a+6Q7/Q71idiyA=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "react-addons-css-transition-group": { + "version": "15.4.2", + "resolved": "https://registry.npmjs.org/react-addons-css-transition-group/-/react-addons-css-transition-group-15.4.2.tgz", + "integrity": "sha1-t4KINN+hQin+B3UOMx6KjLb7d0U=", + "requires": { + "fbjs": "0.8.14", + "object-assign": "4.1.1" + } + }, + "react-addons-perf": { + "version": "15.4.2", + "resolved": "https://registry.npmjs.org/react-addons-perf/-/react-addons-perf-15.4.2.tgz", + "integrity": "sha1-EQvc9cRZxPd8uF7WNLzTOXU2ODs=", + "dev": true, + "requires": { + "fbjs": "0.8.14", + "object-assign": "4.1.1" + } + }, + "react-addons-shallow-compare": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-addons-shallow-compare/-/react-addons-shallow-compare-15.6.0.tgz", + "integrity": "sha1-t6Tl/58nBMIM9obdigXdCLJt4lI=", + "requires": { + "fbjs": "0.8.14", + "object-assign": "4.1.1" + } + }, + "react-addons-test-utils": { + "version": "15.4.2", + "resolved": "https://registry.npmjs.org/react-addons-test-utils/-/react-addons-test-utils-15.4.2.tgz", + "integrity": "sha1-k7yqcY/K5zYNQuj7HAl1bMNjAqI=", + "dev": true, + "requires": { + "fbjs": "0.8.14", + "object-assign": "4.1.1" + } + }, + "react-addons-transition-group": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-addons-transition-group/-/react-addons-transition-group-15.6.0.tgz", + "integrity": "sha1-DyILn5WX2zqAqI29b+gF/GRM4hw=", + "requires": { + "react-transition-group": "1.2.0" + } + }, + "react-codemirror": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/react-codemirror/-/react-codemirror-0.3.0.tgz", + "integrity": "sha1-zWvW70WOweA1z9iz/nswyMeIPGw=", + "requires": { + "classnames": "2.2.5", + "codemirror": "5.28.0", + "lodash.debounce": "4.0.8" + } + }, + "react-container-dimensions": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/react-container-dimensions/-/react-container-dimensions-1.2.0.tgz", + "integrity": "sha1-v7XnDhCqgtLsukkUfRS7TCLK/ao=", + "requires": { + "element-resize-detector": "1.1.12", + "invariant": "2.2.2" + } + }, + "react-copy-to-clipboard": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-4.2.3.tgz", + "integrity": "sha1-JoxaD73pqV2WFFAU5/hRELDn+44=", + "requires": { + "copy-to-clipboard": "3.0.8" + } + }, + "react-deep-force-update": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-deep-force-update/-/react-deep-force-update-2.0.1.tgz", + "integrity": "sha1-T39sEsPn3kLzRZkqPFGCNvoeytM=", + "dev": true + }, + "react-dom": { + "version": "15.4.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.4.2.tgz", + "integrity": "sha1-AVNj8FsKH9Uq6e/dOgBg2QaVII8=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "react-dropzone": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-3.7.3.tgz", + "integrity": "sha1-eFK2ZSpDr8f6ByAh8zaRI+pKYeA=", + "requires": { + "attr-accept": "1.1.0" + } + }, + "react-element-to-jsx-string": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-6.0.0.tgz", + "integrity": "sha1-8sFRR27o3YF4ke01K+Ss6fs2McI=", + "requires": { + "collapse-white-space": "1.0.3", + "is-plain-object": "2.0.4", + "lodash": "4.17.4", + "sortobject": "1.1.1", + "stringify-object": "3.2.0", + "traverse": "0.6.6" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + } + } + }, + "react-event-listener": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.4.1.tgz", + "integrity": "sha1-hrU5dMPfZRhXdmt7F3aC7Xx8gxg=", + "requires": { + "babel-runtime": "6.23.0", + "react-addons-shallow-compare": "15.6.0", + "warning": "3.0.0" + } + }, + "react-hot-loader": { + "version": "3.0.0-beta.6", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-3.0.0-beta.6.tgz", + "integrity": "sha1-Rj+sC/yLY6g4UlivIMkWNqvOdfQ=", + "dev": true, + "requires": { + "babel-template": "6.25.0", + "global": "4.3.2", + "react-deep-force-update": "2.0.1", + "react-proxy": "3.0.0-alpha.1", + "redbox-react": "1.4.3", + "source-map": "0.4.4" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "react-inspector": { + "version": "github:paritytech/react-inspector#73b5214261a5131821eb9088f58d7e5f31210c23", + "requires": { + "babel-runtime": "6.23.0", + "is-dom": "1.0.9" + } + }, + "react-intl": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.1.5.tgz", + "integrity": "sha1-+Xleo0t5DctdDY73Bg3dvoW/h2M=", + "requires": { + "intl-format-cache": "2.0.5", + "intl-messageformat": "1.3.0", + "intl-relativeformat": "1.3.0", + "invariant": "2.2.2" + } + }, + "react-intl-aggregate-webpack-plugin": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/react-intl-aggregate-webpack-plugin/-/react-intl-aggregate-webpack-plugin-0.0.1.tgz", + "integrity": "sha1-wplYhg17zfpvRg3sefVa4CIEiMY=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "react-markdown": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-2.4.4.tgz", + "integrity": "sha1-JtglQ40pLnym4pL+diAeHb8s/u4=", + "requires": { + "commonmark": "0.24.0", + "commonmark-react-renderer": "4.3.3", + "in-publish": "2.0.0" + } + }, + "react-portal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-3.0.0.tgz", + "integrity": "sha1-kwT86DbooyFrIliPjckbRHco8K4=" + }, + "react-proxy": { + "version": "3.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz", + "integrity": "sha1-RABCa8+oDKpnJMd1VpUxUgn6Swc=", + "dev": true, + "requires": { + "lodash": "4.17.2" + } + }, + "react-qr-reader": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/react-qr-reader/-/react-qr-reader-1.1.3.tgz", + "integrity": "sha512-ruBF8KaSwUW9nbzjO4rA7/HOCGYZuNUz9od7uBRy8SRBi24nwxWWmwa2z8R6vPGDRglA0y2Qk1aVBuC1olTnHw==", + "requires": { + "jsqr": "git+https://github.com/JodusNodus/jsQR.git#5ba1acefa1cbb9b2bc92b49f503f2674e2ec212b", + "prop-types": "15.5.10", + "webrtc-adapter": "2.1.0" + } + }, + "react-redux": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-4.4.6.tgz", + "integrity": "sha1-S50ymFMHoRCWot1hVhmABE/MYgk=", + "requires": { + "hoist-non-react-statics": "1.2.0", + "invariant": "2.2.2", + "lodash": "4.17.2", + "loose-envify": "1.3.1" + } + }, + "react-router": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.0.tgz", + "integrity": "sha1-PzE+Tbr1cEjEjdCow8rCTZNmff8=", + "requires": { + "history": "3.3.0", + "hoist-non-react-statics": "1.2.0", + "invariant": "2.2.2", + "loose-envify": "1.3.1", + "warning": "3.0.0" + } + }, + "react-router-redux": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.7.tgz", + "integrity": "sha1-mx/eTnAQbFD0chThK92IjPuW4qY=" + }, + "react-smooth": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-0.1.11.tgz", + "integrity": "sha1-84n45Yy7VGq7SSHKDL57B5vFGg0=", + "requires": { + "lodash": "4.13.1", + "raf": "3.3.2", + "react-addons-transition-group": "15.6.0" + }, + "dependencies": { + "lodash": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz", + "integrity": "sha1-g+SxCRP0hJbU0W/sSlYK8u50S2g=" + } + } + }, + "react-tap-event-plugin": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-tap-event-plugin/-/react-tap-event-plugin-2.0.1.tgz", + "integrity": "sha1-MWvrO8ZVbinshppyk+icgmqQdNI=", + "requires": { + "fbjs": "0.8.14" + } + }, + "react-tooltip": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-3.2.2.tgz", + "integrity": "sha1-OlmcDqu9nrlZeqLXKyF/17o1h2c=", + "requires": { + "classnames": "2.2.5" + } + }, + "react-transition-group": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.0.tgz", + "integrity": "sha1-tR/JIbDDg1p+98Vxx5/ILHPpIE8=", + "requires": { + "chain-function": "1.0.0", + "dom-helpers": "3.2.1", + "loose-envify": "1.3.1", + "prop-types": "15.5.10", + "warning": "3.0.0" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "0.0.7" + } + }, + "read-all-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", + "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", + "requires": { + "pinkie-promise": "2.0.1", + "readable-stream": "2.3.3" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-file-stdin": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/read-file-stdin/-/read-file-stdin-0.2.1.tgz", + "integrity": "sha1-JezP86FTtoCa+ssj7hU4fbng7mE=", + "dev": true, + "requires": { + "gather-stream": "1.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + } + } + }, + "recast": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", + "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "dev": true, + "requires": { + "ast-types": "0.9.6", + "esprima": "3.1.3", + "private": "0.1.7", + "source-map": "0.5.6" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + } + } + }, + "recharts": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-0.15.2.tgz", + "integrity": "sha1-Y28ho0HwCzHJJXOe1K73CttV2A8=", + "requires": { + "classnames": "2.2.5", + "core-js": "2.4.0", + "d3-scale": "1.0.0", + "d3-shape": "1.0.0", + "lodash": "4.13.1", + "react-container-dimensions": "1.2.0", + "react-smooth": "0.1.11", + "recharts-scale": "0.2.1", + "reduce-css-calc": "1.3.0" + }, + "dependencies": { + "core-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.0.tgz", + "integrity": "sha1-30CKtG0Br/kcAcPnlxk11CLFT4E=" + }, + "lodash": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz", + "integrity": "sha1-g+SxCRP0hJbU0W/sSlYK8u50S2g=" + } + } + }, + "recharts-scale": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.2.1.tgz", + "integrity": "sha1-N49UPtF8MkXk2a+xCq9imCQNL8s=" + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.4.0" + } + }, + "recompose": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.20.2.tgz", + "integrity": "sha1-ET1qx+KcpmTP/+wWtoHd3fFSULw=", + "requires": { + "change-emitter": "0.1.6", + "fbjs": "0.8.14", + "hoist-non-react-statics": "1.2.0", + "symbol-observable": "0.2.4" + } + }, + "redbox-react": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/redbox-react/-/redbox-react-1.4.3.tgz", + "integrity": "sha512-P/N+y57/FVUQWbgpfTf/2wjgxEhxQuA6FRLv0ipZKLFv5v8mp6qs5inFyBwJQYAgaMrntZRCvKdz1vGwkCNs7A==", + "dev": true, + "requires": { + "error-stack-parser": "1.3.6", + "object-assign": "4.1.1", + "prop-types": "15.5.10", + "sourcemapped-stacktrace": "1.1.7" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "requires": { + "balanced-match": "0.4.2", + "math-expression-evaluator": "1.2.17", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "requires": { + "balanced-match": "0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + } + } + }, + "reduce-reducers": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reduce-reducers/-/reduce-reducers-0.1.2.tgz", + "integrity": "sha1-+htHGLxSkqcd3R5dg5yb6pdw8Us=" + }, + "redux": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.6.0.tgz", + "integrity": "sha1-iHwrPQub2G7KK+cFccJ2VMGeGI0=", + "requires": { + "lodash": "4.17.2", + "lodash-es": "4.17.4", + "loose-envify": "1.3.1", + "symbol-observable": "1.0.4" + }, + "dependencies": { + "symbol-observable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", + "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" + } + } + }, + "redux-actions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/redux-actions/-/redux-actions-1.1.0.tgz", + "integrity": "sha1-347HkdniZ1ROWKi6K3L8XDCvujs=", + "requires": { + "invariant": "2.2.2", + "lodash": "4.17.2", + "reduce-reducers": "0.1.2" + } + }, + "redux-thunk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.1.0.tgz", + "integrity": "sha1-xyS/7nXb41LaLjupvBQwK63Ympg=" + }, + "regenerate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", + "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=" + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "regenerator-transform": { + "version": "0.9.11", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", + "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "private": "0.1.7" + } + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "requires": { + "regenerate": "1.3.2", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "0.5.0" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=" + }, + "renderkid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", + "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "dev": true, + "requires": { + "css-select": "1.2.0", + "dom-converter": "0.1.4", + "htmlparser2": "3.3.0", + "strip-ansi": "3.0.1", + "utila": "0.3.3" + }, + "dependencies": { + "domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.1.0", + "domutils": "1.1.6", + "readable-stream": "1.0.34" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + } + } + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "1.0.2" + } + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.16", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.0" + }, + "dependencies": { + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + } + } + }, + "request-capture-har": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/request-capture-har/-/request-capture-har-1.2.2.tgz", + "integrity": "sha1-zWks+yzHRP2EozWKrG7lFSjPcg0=" + }, + "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": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" + }, + "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-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "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=", + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + }, + "dependencies": { + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "1.1.0" + } + } + } + }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" + }, + "rgb-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgb-hex/-/rgb-hex-1.0.0.tgz", + "integrity": "sha1-v6+M2c2RZLWibXHrTxWgllMks8E=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "requires": { + "glob": "7.1.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "rlp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", + "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=" + }, + "roadrunner": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/roadrunner/-/roadrunner-1.1.0.tgz", + "integrity": "sha1-EYCjDWThlw2PVd2MsNqP/M7K1x4=" + }, + "rucksack-css": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/rucksack-css/-/rucksack-css-0.9.1.tgz", + "integrity": "sha1-2n66TGe9BbAMv0yDQwXF/lU3XeE=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "laggard": "0.1.0", + "minimist": "1.2.0", + "postcss": "5.2.17", + "postcss-alias": "1.0.0", + "postcss-clearfix": "1.0.0", + "postcss-color-rgba-fallback": "2.2.0", + "postcss-easings": "0.3.0", + "postcss-fontpath": "0.3.0", + "postcss-hexrgba": "0.2.1", + "postcss-input-style": "0.3.0", + "postcss-opacity": "4.0.0", + "postcss-position": "0.5.0", + "postcss-pseudoelements": "3.0.0", + "postcss-quantity-queries": "0.4.0", + "postcss-reporter": "2.0.0", + "postcss-responsive-type": "0.5.1", + "postcss-vmin": "2.0.0", + "read-file-stdin": "0.2.1", + "write-file-stdout": "0.0.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "samsam": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", + "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "requires": { + "ajv": "5.2.2" + } + }, + "script-ext-html-webpack-plugin": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/script-ext-html-webpack-plugin/-/script-ext-html-webpack-plugin-1.7.1.tgz", + "integrity": "sha1-rpwOJtd2fUqnk8duNVA0TsCLbRA=", + "dev": true, + "requires": { + "debug": "2.6.8" + } + }, + "scryptsy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.0.0.tgz", + "integrity": "sha1-Jiw28CMc+nZU4jY/o5TNLexm83g=" + }, + "sdp": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-1.5.4.tgz", + "integrity": "sha1-jgOPbdsUvXZa4fS1IW4SCUUR4NA=" + }, + "secp256k1": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.3.0.tgz", + "integrity": "sha512-CbrQoeGG5V0kQ1ohEMGI+J7oKerapLTpivLICBaXR0R4HyQcN3kM9itLsV5fdpV1UR1bD14tOkJ1xughmlDIiQ==", + "requires": { + "bindings": "1.3.0", + "bip66": "1.1.5", + "bn.js": "4.11.7", + "create-hash": "1.1.3", + "drbg.js": "1.0.1", + "elliptic": "6.4.0", + "nan": "2.6.2", + "prebuild-install": "2.2.1", + "safe-buffer": "5.1.1" + } + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "semver-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", + "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", + "dev": true + }, + "semver-truncate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", + "dev": true, + "requires": { + "semver": "5.4.1" + } + }, + "send": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.14.2.tgz", + "integrity": "sha1-ObBDiz9RC+Xcb2Z6EfcWiTaM3u8=", + "dev": true, + "requires": { + "debug": "2.2.0", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.7.0", + "fresh": "0.3.0", + "http-errors": "1.5.1", + "mime": "1.3.4", + "ms": "0.7.2", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + }, + "dependencies": { + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "serve-static": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.11.2.tgz", + "integrity": "sha1-LPmIm9RDWjIMw2iVyapXvWYuasc=", + "dev": true, + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.1", + "send": "0.14.2" + } + }, + "serviceworker-cache-polyfill": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serviceworker-cache-polyfill/-/serviceworker-cache-polyfill-4.0.0.tgz", + "integrity": "sha1-3hnuc77yGrPAdAo3sz22JGS6ves=" + }, + "serviceworker-webpack-plugin": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-0.2.0.tgz", + "integrity": "sha1-beneyC7RRMdUxvFbND57h2SsWyg=", + "dev": true, + "requires": { + "minimatch": "3.0.4" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz", + "integrity": "sha1-gaVSFB7BBLiOic44MQOtXGZWTQg=", + "dev": true + }, + "sha.js": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", + "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "requires": { + "inherits": "2.0.3" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "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=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.0.3", + "rechoir": "0.6.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-assign": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz", + "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o=" + }, + "simple-get": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz", + "integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=", + "requires": { + "once": "1.4.0", + "unzip-response": "1.0.2", + "xtend": "4.0.1" + } + }, + "sinon": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", + "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", + "dev": true, + "requires": { + "formatio": "1.1.1", + "lolex": "1.3.2", + "samsam": "1.1.2", + "util": "0.10.3" + } + }, + "sinon-as-promised": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/sinon-as-promised/-/sinon-as-promised-4.0.2.tgz", + "integrity": "sha1-Eg6c4DPao5ZI3EKQYv5mC+G1tBI=", + "dev": true, + "requires": { + "create-thenable": "1.0.2", + "native-promise-only": "0.8.1" + } + }, + "sinon-chai": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.8.0.tgz", + "integrity": "sha1-Qyqbv9Uab8AHmPTSUmqCnAYGh6w=", + "dev": true + }, + "sjcl": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.6.tgz", + "integrity": "sha1-ZBVGKmPMDUIVxJuuydP6DBtTUg8=" + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.16.3" + } + }, + "solc": { + "version": "github:ngotchac/solc-js#04eb38cc3003fba8cb3656653a7941ed36408818", + "requires": { + "memorystream": "0.3.1", + "require-from-string": "1.2.1", + "yargs": "4.8.1" + }, + "dependencies": { + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "requires": { + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "lodash.assign": "4.2.0", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "2.4.1" + } + } + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "sortobject": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sortobject/-/sortobject-1.1.1.tgz", + "integrity": "sha1-T2ldTUTtCkwGSCw0wlgqLc3CqzQ=", + "requires": { + "editions": "1.3.3" + } + }, + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "dev": true + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + }, + "source-map-support": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", + "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", + "requires": { + "source-map": "0.5.6" + } + }, + "sourcemapped-stacktrace": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/sourcemapped-stacktrace/-/sourcemapped-stacktrace-1.1.7.tgz", + "integrity": "sha512-pgHNUACbafkQ+M5zR00NSOtSKBc/i40prgN+SY07J/pghClwVNWNTTMa0JuXj4lriR2TvMKcPAHw5KN9tVFRhA==", + "dev": true, + "requires": { + "source-map": "0.5.6" + } + }, + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=" + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, + "specificity": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.3.1.tgz", + "integrity": "sha1-8bBoQkzjF64HR42V3jwhz4Xo1Wc=", + "dev": true + }, + "split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "requires": { + "through2": "0.6.5" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "squeak": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", + "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "console-stream": "0.1.1", + "lpad-align": "1.1.2" + } + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "stackframe": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", + "integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=", + "dev": true + }, + "stat-mode": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", + "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "store": { + "version": "1.3.20", + "resolved": "https://registry.npmjs.org/store/-/store-1.3.20.tgz", + "integrity": "sha1-E+p+P7LWwjmGgmXWhrHYTpnFvj4=" + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "dev": true, + "requires": { + "duplexer": "0.1.1", + "through": "2.3.8" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "requires": { + "duplexer2": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "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_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.1" + } + }, + "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.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string.prototype.repeat": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", + "integrity": "sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8=" + }, + "stringify-object": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.0.tgz", + "integrity": "sha1-lDcKE15BvASDWIE7+ZSB8TFcaqY=", + "requires": { + "get-own-enumerable-property-symbols": "1.0.1", + "is-obj": "1.0.1", + "is-regexp": "1.0.0" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "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.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + } + }, + "strip-dirs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz", + "integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=", + "requires": { + "chalk": "1.1.3", + "get-stdin": "4.0.1", + "is-absolute": "0.1.7", + "is-natural-number": "2.1.1", + "minimist": "1.2.0", + "sum-up": "1.0.3" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + } + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "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-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + } + } + }, + "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=" + }, + "strip-outer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.0.tgz", + "integrity": "sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g=", + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "style-loader": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.13.1.tgz", + "integrity": "sha1-RoKA77wEcwI806bNVuM7Wh1/w6k=", + "dev": true, + "requires": { + "loader-utils": "0.2.17" + } + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "stylehacks": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-2.3.2.tgz", + "integrity": "sha1-ZMg+BDimjJ7fRJ6MVSp9mrYAmws=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "chalk": "1.1.3", + "log-symbols": "1.0.2", + "minimist": "1.2.0", + "plur": "2.1.2", + "postcss": "5.2.17", + "postcss-reporter": "1.4.1", + "postcss-selector-parser": "2.2.3", + "read-file-stdin": "0.2.1", + "text-table": "0.2.0", + "write-file-stdout": "0.0.2" + }, + "dependencies": { + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.2", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + } + } + }, + "stylelint": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-7.9.0.tgz", + "integrity": "sha1-uNnqIPiHqzUQdcat7ZUo3iRQkyc=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "balanced-match": "0.4.2", + "chalk": "1.1.3", + "colorguard": "1.2.0", + "cosmiconfig": "2.2.2", + "doiuse": "2.6.0", + "execall": "1.0.0", + "get-stdin": "5.0.1", + "globby": "6.1.0", + "globjoin": "0.1.4", + "html-tags": "1.2.0", + "ignore": "3.3.3", + "known-css-properties": "0.0.6", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "meow": "3.7.0", + "micromatch": "2.3.11", + "normalize-selector": "0.2.0", + "postcss": "5.2.17", + "postcss-less": "0.14.0", + "postcss-media-query-parser": "0.2.3", + "postcss-reporter": "3.0.0", + "postcss-resolve-nested-selector": "0.1.1", + "postcss-scss": "0.4.1", + "postcss-selector-parser": "2.2.3", + "postcss-value-parser": "3.3.0", + "resolve-from": "2.0.0", + "specificity": "0.3.1", + "string-width": "2.1.1", + "style-search": "0.1.0", + "stylehacks": "2.3.2", + "sugarss": "0.2.0", + "svg-tags": "1.0.0", + "table": "4.0.1" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "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=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "postcss-reporter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz", + "integrity": "sha1-CeoPN6RExWk4eGBuCbAY6+/3z48=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "table": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz", + "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + } + } + } + }, + "stylelint-config-standard": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-16.0.0.tgz", + "integrity": "sha1-u3OHv/HX3XGGpSs+v4hbJAXWkb8=", + "dev": true + }, + "sugarss": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-0.2.0.tgz", + "integrity": "sha1-rDQjdWMyfG/4l7ZHQr9q7BkK054=", + "dev": true, + "requires": { + "postcss": "5.2.17" + } + }, + "sum-up": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz", + "integrity": "sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4=", + "requires": { + "chalk": "1.1.3" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true, + "requires": { + "coa": "1.0.4", + "colors": "1.1.2", + "csso": "2.3.2", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "sax": "1.2.4", + "whet.extend": "0.9.9" + }, + "dependencies": { + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + } + } + }, + "sw-toolbox": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/sw-toolbox/-/sw-toolbox-3.6.0.tgz", + "integrity": "sha1-Jt8dHHA0hljk3qKIQxkUm3sxg7U=", + "requires": { + "path-to-regexp": "1.7.0", + "serviceworker-cache-polyfill": "4.0.0" + } + }, + "symbol-observable": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=" + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "synesthesia": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/synesthesia/-/synesthesia-1.0.1.tgz", + "integrity": "sha1-XvlepUjA1cbm+btLDQcx3/hkp3c=", + "dev": true, + "requires": { + "css-color-names": "0.0.3" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", + "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=", + "dev": true + } + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.2", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "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=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "tapable": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.7.tgz", + "integrity": "sha1-5GwNqsuyuKmLmwzqD0BSEFgX7Vw=", + "dev": true + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-fs": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz", + "integrity": "sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA=", + "requires": { + "chownr": "1.0.1", + "mkdirp": "0.5.1", + "pump": "1.0.2", + "tar-stream": "1.5.4" + } + }, + "tar-pack": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz", + "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=", + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.3.3", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tar-stream": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", + "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", + "requires": { + "bl": "1.2.1", + "end-of-stream": "1.4.0", + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true + }, + "tempfile": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", + "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=", + "dev": true, + "requires": { + "temp-dir": "1.0.0", + "uuid": "3.1.0" + }, + "dependencies": { + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + } + } + }, + "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 + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "requires": { + "through2": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + } + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, + "timed-out": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", + "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=" + }, + "timers-browserify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.3.tgz", + "integrity": "sha512-+JAqyNgg+M8+gXIrq2EeUr4kZqRz47Ysco7X5QKRGScRE9HIHckyHD1asozSFGeqx2nmPCgA8T5tIGVO0ML7/w==", + "dev": true, + "requires": { + "global": "4.3.2", + "setimmediate": "1.0.5" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "requires": { + "extend-shallow": "2.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + }, + "to-source": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/to-source/-/to-source-2.0.3.tgz", + "integrity": "sha1-U4f4JZzzV2Kz4+m1wtzY49uaLRU=", + "dev": true + }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, + "toposort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.3.tgz", + "integrity": "sha1-8CzYp0vYvi/A6YYRw7rLlaFxhpw=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "requires": { + "punycode": "1.4.1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "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.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "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": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "dev": true + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.16" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typedarray-to-buffer": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.2.tgz", + "integrity": "sha1-EBezLZhP9VbroQD1AViauhrOLgQ=", + "dev": true, + "requires": { + "is-typedarray": "1.0.0" + } + }, + "u2f-api": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.0.9.tgz", + "integrity": "sha1-ve1Fe6Wpqe6bWLPeKR+MH4/qy3o=" + }, + "u2f-api-polyfill": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/u2f-api-polyfill/-/u2f-api-polyfill-0.4.3.tgz", + "integrity": "sha1-t60WWm+WJVhReoZ8XEv5OZ/Pfpg=" + }, + "ua-parser-js": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", + "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=" + }, + "uglify-js": { + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.16.tgz", + "integrity": "sha1-0oYZC27vxv1l6w7KxlUeCw6IOaQ=", + "requires": { + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqid": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", + "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", + "dev": true, + "requires": { + "macaddress": "0.2.8" + } + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-concat": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/unique-concat/-/unique-concat-0.2.2.tgz", + "integrity": "sha1-khD5vcqsxeHjkpSQ18AZ35bxhxI=", + "dev": true + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unzip-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=" + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.7.tgz", + "integrity": "sha1-Z+h3l1n4AA2nSZSQZoDJQ6mwkl0=", + "dev": true, + "requires": { + "loader-utils": "0.2.17", + "mime": "1.2.11" + }, + "dependencies": { + "mime": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", + "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.4" + } + }, + "url-regex": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz", + "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=", + "dev": true, + "requires": { + "ip-regex": "1.0.3" + } + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "useragent.js": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/useragent.js/-/useragent.js-0.5.6.tgz", + "integrity": "sha1-p2rvEB4kg3AlI/9vtYpACvd+Iqk=" + }, + "utf8": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", + "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "dev": true + }, + "uuid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", + "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "1.1.1" + } + }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=" + }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "validator": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-6.2.0.tgz", + "integrity": "sha1-sszNxJ/w9LjuTmHbot3T3eE/I+c=" + }, + "vary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", + "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc=", + "dev": true + }, + "vendors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", + "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", + "dev": true + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "requires": { + "extsprintf": "1.0.2" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-assign": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/vinyl-assign/-/vinyl-assign-1.2.1.tgz", + "integrity": "sha1-TRmIkbVRWRHXcajNnFSApGoHSkU=", + "requires": { + "object-assign": "4.1.1", + "readable-stream": "2.3.3" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "requires": { + "duplexify": "3.5.0", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + }, + "dependencies": { + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + } + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "w3c-blob": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/w3c-blob/-/w3c-blob-0.0.1.tgz", + "integrity": "sha1-sM01KhpQ9RVWNCD/1YYflQ8dhbg=" + }, + "ware": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", + "integrity": "sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q=", + "requires": { + "wrap-fn": "0.1.5" + } + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "1.3.1" + } + }, + "watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "dev": true, + "requires": { + "async": "2.5.0", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.2" + } + } + } + }, + "web3": { + "version": "0.17.0-beta", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.17.0-beta.tgz", + "integrity": "sha1-V684JFv/ejIJn3zleA+tW7wA2ls=", + "requires": { + "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "crypto-js": "3.1.8", + "utf8": "2.1.2", + "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" + } + } + }, + "webidl-conversions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", + "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", + "dev": true + }, + "webpack": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.2.1.tgz", + "integrity": "sha1-e7HXKuIIfdGkr1Jq/sFe7RfdpHU=", + "dev": true, + "requires": { + "acorn": "4.0.13", + "acorn-dynamic-import": "2.0.2", + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "async": "2.5.0", + "enhanced-resolve": "3.4.1", + "interpret": "1.0.3", + "json-loader": "0.5.4", + "loader-runner": "2.3.0", + "loader-utils": "0.2.17", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.0.0", + "source-map": "0.5.6", + "supports-color": "3.2.3", + "tapable": "0.2.7", + "uglify-js": "2.8.16", + "watchpack": "1.4.0", + "webpack-sources": "0.1.5", + "yargs": "6.6.0" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.2" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "webpack-bundle-size-analyzer": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-size-analyzer/-/webpack-bundle-size-analyzer-2.5.0.tgz", + "integrity": "sha1-k56kZeRVk1Op/OQK9RGCDyFqnIA=", + "dev": true, + "requires": { + "commander": "2.8.1", + "filesize": "3.5.10", + "humanize": "0.0.9" + } + }, + "webpack-dev-middleware": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.10.1.tgz", + "integrity": "sha1-xrTPQoE5zxrvvgagwA/bT42i+JM=", + "dev": true, + "requires": { + "memory-fs": "0.4.1", + "mime": "1.3.4", + "path-is-absolute": "1.0.1", + "range-parser": "1.2.0" + } + }, + "webpack-error-notification": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/webpack-error-notification/-/webpack-error-notification-0.1.6.tgz", + "integrity": "sha1-6/y9TvRrg0ZrWcEv3oeQFo9Holc=", + "dev": true + }, + "webpack-hot-middleware": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.17.1.tgz", + "integrity": "sha1-DI+/b5P/KcCV1oSwerbWwPL5Udc=", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "html-entities": "1.2.1", + "querystring": "0.2.0", + "strip-ansi": "3.0.1" + } + }, + "webpack-sources": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.1.5.tgz", + "integrity": "sha1-qh86vw8NdNtxEcQOUAuE+WZkB1A=", + "dev": true, + "requires": { + "source-list-map": "0.1.8", + "source-map": "0.5.6" + } + }, + "webrtc-adapter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-2.1.0.tgz", + "integrity": "sha1-YStbxs6Oc8nQZgA4oh+SVahnvz4=", + "requires": { + "sdp": "1.5.4" + } + }, + "websocket": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.24.tgz", + "integrity": "sha1-dJA+dfJUW2suHeFCW8HJBZF6GJA=", + "dev": true, + "requires": { + "debug": "2.6.8", + "nan": "2.6.2", + "typedarray-to-buffer": "3.1.2", + "yaeti": "0.0.6" + } + }, + "whatwg-encoding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", + "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", + "dev": true, + "requires": { + "iconv-lite": "0.4.13" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + } + } + }, + "whatwg-fetch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.1.tgz", + "integrity": "sha1-B4uUYbvpHOpzy86LsSKgX56St3I=" + }, + "whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "dev": true, + "requires": { + "tr46": "0.0.3", + "webidl-conversions": "3.0.1" + }, + "dependencies": { + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + } + } + }, + "whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "requires": { + "string-width": "1.0.2" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "worker-loader": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-0.8.1.tgz", + "integrity": "sha1-6OmVMx6jTfW/aCloJL+38K1XjUM=", + "requires": { + "loader-utils": "1.1.0", + "schema-utils": "0.3.0" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "requires": { + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + } + } + }, + "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.2", + "strip-ansi": "3.0.1" + } + }, + "wrap-fn": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", + "integrity": "sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU=", + "requires": { + "co": "3.1.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "write-file-stdout": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/write-file-stdout/-/write-file-stdout-0.0.2.tgz", + "integrity": "sha1-wlLXx8WxtAKJdjDjRTx7/mkNnKE=", + "dev": true + }, + "write-json-file": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-1.2.0.tgz", + "integrity": "sha1-LV3+lqvDyIkFfJOXGqQAXvtUgTQ=", + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "sort-keys": "1.1.2", + "write-file-atomic": "1.3.4" + } + }, + "xml-char-classes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", + "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=", + "dev": true + }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "dev": true + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, + "xss-filters": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/xss-filters/-/xss-filters-1.2.7.tgz", + "integrity": "sha1-Wfod4gHzby80cNysX1jMwoMLCpo=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "4.2.1" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "requires": { + "camelcase": "3.0.0", + "lodash.assign": "4.2.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + } + } + }, + "yarn": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-0.21.3.tgz", + "integrity": "sha1-jdo6Y8eYs4PPpXdFLCs8s+Sqh+A=", + "requires": { + "babel-runtime": "6.23.0", + "bytes": "2.4.0", + "camelcase": "3.0.0", + "chalk": "1.1.3", + "cmd-shim": "2.0.2", + "commander": "2.11.0", + "death": "1.1.0", + "debug": "2.6.8", + "defaults": "1.0.3", + "detect-indent": "5.0.0", + "ini": "1.3.4", + "inquirer": "3.2.1", + "invariant": "2.2.2", + "is-builtin-module": "1.0.0", + "is-ci": "1.0.10", + "leven": "2.1.0", + "loud-rejection": "1.6.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "node-emoji": "1.8.1", + "node-gyp": "3.6.2", + "object-path": "0.11.4", + "proper-lockfile": "2.0.1", + "read": "1.0.7", + "request": "2.81.0", + "request-capture-har": "1.2.2", + "rimraf": "2.6.1", + "roadrunner": "1.1.0", + "semver": "5.4.1", + "strip-bom": "3.0.0", + "tar": "2.2.1", + "tar-stream": "1.5.4", + "validate-npm-package-license": "3.0.1" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=" + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "requires": { + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" + } + }, + "zxcvbn": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.1.tgz", + "integrity": "sha1-I4Gq3X8HiiWoayFTJ1YmR7gKqKw=" + } + } +} diff --git a/js/package.json b/js/package.json index fb69b12d2..3c399db87 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "1.7.100", + "version": "1.8.11", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", @@ -209,7 +209,7 @@ "react-intl": "2.1.5", "react-markdown": "2.4.4", "react-portal": "3.0.0", - "react-qr-reader": "1.0.3", + "react-qr-reader": "1.1.3", "react-redux": "4.4.6", "react-router": "3.0.0", "react-router-redux": "4.0.7", diff --git a/js/src/api/local/accounts/account.js b/js/src/api/local/accounts/account.js index 0bb069c8b..224a05cd9 100644 --- a/js/src/api/local/accounts/account.js +++ b/js/src/api/local/accounts/account.js @@ -31,6 +31,10 @@ export default class Account { } isValidPassword (password) { + if (!this._keyObject) { + return false; + } + return decryptPrivateKey(this._keyObject, password) .then((privateKey) => { if (!privateKey) { diff --git a/js/src/api/local/accounts/accounts.js b/js/src/api/local/accounts/accounts.js index 823ab3624..d11ea2bad 100644 --- a/js/src/api/local/accounts/accounts.js +++ b/js/src/api/local/accounts/accounts.js @@ -168,6 +168,12 @@ export default class Accounts { return false; } + if (!account.uuid) { + this.removeUnsafe(address); + + return true; + } + return account .isValidPassword(password) .then((isValid) => { diff --git a/js/src/api/local/localAccountsMiddleware.js b/js/src/api/local/localAccountsMiddleware.js index c8e767f89..c452f541a 100644 --- a/js/src/api/local/localAccountsMiddleware.js +++ b/js/src/api/local/localAccountsMiddleware.js @@ -206,6 +206,10 @@ export default class LocalAccountsMiddleware extends Middleware { return accounts.remove(address, password); }); + register('parity_removeAddress', ([address]) => { + return accounts.remove(address, null); + }); + register('parity_testPassword', ([address, password]) => { const account = accounts.get(address); diff --git a/js/src/api/rpc/shh/shh.js b/js/src/api/rpc/shh/shh.js index 9312df6c1..c58754abf 100644 --- a/js/src/api/rpc/shh/shh.js +++ b/js/src/api/rpc/shh/shh.js @@ -14,58 +14,78 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default class Personal { +export default class Shh { constructor (transport) { this._transport = transport; } - addToGroup (identity) { + info () { return this._transport - .execute('shh_addToGroup', identity); + .execute('shh_info'); } - getFilterChanges (filterId) { + newKeyPair () { return this._transport - .execute('shh_getFilterChanges', filterId); + .execute('shh_newKeyPair'); } - getMessages (filterId) { + addPrivateKey (privKey) { return this._transport - .execute('shh_getMessages', filterId); + .execute('shh_addPrivateKey', privKey); } - hasIdentity (identity) { + newSymKey () { return this._transport - .execute('shh_hasIdentity', identity); + .execute('shh_newSymKey'); } - newFilter (options) { + getPublicKey (identity) { return this._transport - .execute('shh_newFilter', options); + .execute('shh_getPublicKey', identity); } - newGroup () { + getPrivateKey (identity) { return this._transport - .execute('shh_newGroup'); + .execute('shh_getPrivateKey', identity); } - newIdentity () { + getSymKey (identity) { return this._transport - .execute('shh_newIdentity'); + .execute('shh_getSymKey', identity); } - post (options) { + deleteKey (identity) { return this._transport - .execute('shh_post', options); + .execute('shh_deleteKey', identity); } - uninstallFilter (filterId) { + post (messageObj) { return this._transport - .execute('shh_uninstallFilter', filterId); + .execute('shh_post', messageObj); } - version () { + newMessageFilter (filterObj) { return this._transport - .execute('shh_version'); + .execute('shh_newMessageFilter', filterObj); + } + + getFilterMessages (filterId) { + return this._transport + .execute('shh_getFilterMessages', filterId); + } + + deleteMessageFilter (filterId) { + return this._transport + .execute('shh_deleteMessageFilter', filterId); + } + + subscribe (filterObj, callback) { + return this._transport + .subscribe('shh', callback, filterObj); + } + + unsubscribe (subscriptionId) { + return this._transport + .unsubscribe(subscriptionId); } } diff --git a/js/src/api/transport/ws/ws.js b/js/src/api/transport/ws/ws.js index 3c642d5f8..9c276772d 100644 --- a/js/src/api/transport/ws/ws.js +++ b/js/src/api/transport/ws/ws.js @@ -29,7 +29,7 @@ export default class Ws extends JsonRpcBase { this._url = url; this._token = token; this._messages = {}; - this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [] }; + this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [], 'shh_subscription': [] }; this._sessionHash = null; this._connecting = false; diff --git a/js/src/contracts/code/wallet.js b/js/src/contracts/code/wallet.js index 06142308a..ab60bfc98 100644 --- a/js/src/contracts/code/wallet.js +++ b/js/src/contracts/code/wallet.js @@ -15,16 +15,16 @@ // along with Parity. If not, see . /** - * @version Solidity v0.4.9 - Optimized - * @from https://github.com/paritytech/parity/blob/c4196a5de31e0b97ec42d5263d9db404cea4a776/js/src/contracts/snippets/enhanced-wallet.sol - * @date 07-Mar-2017 @ 16h00 UTC + * @version Solidity v0.4.10 - Optimized + * @from https://github.com/paritytech/parity/blob/6b0e4f9098be6b841353e7c4f116aa86b7c2e3d6/js/src/contracts/snippets/enhanced-wallet.sol + * @date 20-Jul-2017 @ 16h00 UTC */ -export const walletCompiler = 'v0.4.9+commit.364da425'; +export const walletCompiler = 'v0.4.10+commit.f0d539ae'; export const walletSource = 'https://github.com/paritytech/parity/blob/c4196a5de31e0b97ec42d5263d9db404cea4a776/js/src/contracts/snippets/enhanced-wallet.sol'; -export const wallet = '0x6060604052341561000c57fe5b60405161048538038061048583398101604090815281516020830151918301519201915b604080517f696e697457616c6c657428616464726573735b5d2c75696e743235362c75696e81527f7432353629000000000000000000000000000000000000000000000000000000602080830191909152915190819003602501902084516000829052909173_____________WalletLibrary______________91600281019160049182010290819038829003903960006000600483016000866127105a03f45b505050505050505b61039d806100e86000396000f300606060405236156100725763ffffffff60e060020a6000350416632f54bf6e811461012d5780634123cb6b1461015d578063523750931461017f578063659010e7146101a1578063746c9171146101c3578063c2cf7326146101e5578063c41a360a14610218578063f1736d8614610247575b61012b5b60003411156100c75760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a1610127565b60003611156101275773_____________WalletLibrary______________600160a060020a0316600036600060405160200152604051808383808284378201915050925050506020604051808303818560325a03f4151561012457fe5b50505b5b5b565b005b341561013557fe5b610149600160a060020a0360043516610269565b604080519115158252519081900360200190f35b341561016557fe5b61016d6102cd565b60408051918252519081900360200190f35b341561018757fe5b61016d6102d3565b60408051918252519081900360200190f35b34156101a957fe5b61016d6102d9565b60408051918252519081900360200190f35b34156101cb57fe5b61016d6102df565b60408051918252519081900360200190f35b34156101ed57fe5b610149600435600160a060020a03602435166102e5565b604080519115158252519081900360200190f35b341561022057fe5b61022b60043561034a565b60408051600160a060020a039092168252519081900360200190f35b341561024f57fe5b61016d61036b565b60408051918252519081900360200190f35b600073_____________WalletLibrary______________600160a060020a0316600036600060405160200152604051808383808284378201915050925050506020604051808303818560325a03f415156102bf57fe5b50506040515190505b919050565b60015481565b60045481565b60035481565b60005481565b600073_____________WalletLibrary______________600160a060020a0316600036600060405160200152604051808383808284378201915050925050506020604051808303818560325a03f4151561033b57fe5b50506040515190505b92915050565b6000600560018301610100811061035d57fe5b0160005b505490505b919050565b600254815600a165627a7a723058204a75c2f5c8009054bd9e9998e8bb6f4bca0b201484709f357b482793957c47130029'; -export const walletLibrary = '0x6060604052341561000c57fe5b5b6116d88061001c6000396000f300606060405236156101015763ffffffff60e060020a600035041663173825d981146101575780632f54bf6e146101755780634123cb6b146101a557806352375093146101c75780635c52c2f5146101e9578063659010e7146101fb5780637065cb481461021d578063746c91711461023b578063797af6271461025d5780639da5e0eb14610284578063b20d30a914610299578063b61d27f6146102ae578063b75c7dc6146102ec578063ba51a6df14610301578063c2cf732614610316578063c41a360a14610349578063c57c5f6014610378578063cbf0b0c0146103cf578063e46dcfeb146103ed578063f00d4b5d14610449578063f1736d861461046d575b6101555b60003411156101525760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b5b565b005b341561015f57fe5b610155600160a060020a036004351661048f565b005b341561017d57fe5b610191600160a060020a036004351661057d565b604080519115158252519081900360200190f35b34156101ad57fe5b6101b561059e565b60408051918252519081900360200190f35b34156101cf57fe5b6101b56105a4565b60408051918252519081900360200190f35b34156101f157fe5b6101556105aa565b005b341561020357fe5b6101b56105e1565b60408051918252519081900360200190f35b341561022557fe5b610155600160a060020a03600435166105e7565b005b341561024357fe5b6101b56106d7565b60408051918252519081900360200190f35b341561026557fe5b6101916004356106dd565b604080519115158252519081900360200190f35b341561028c57fe5b610155600435610a2f565b005b34156102a157fe5b610155600435610a43565b005b34156102b657fe5b6101b560048035600160a060020a0316906024803591604435918201910135610a7b565b60408051918252519081900360200190f35b34156102f457fe5b610155600435610d5d565b005b341561030957fe5b610155600435610e08565b005b341561031e57fe5b610191600435600160a060020a0360243516610e8a565b604080519115158252519081900360200190f35b341561035157fe5b61035c600435610edf565b60408051600160a060020a039092168252519081900360200190f35b341561038057fe5b6101556004808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496505093359350610f0092505050565b005b34156103d757fe5b610155600160a060020a0360043516610fd4565b005b34156103f557fe5b6101556004808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496505084359460200135935061101292505050565b005b341561045157fe5b610155600160a060020a036004358116906024351661102b565b005b341561047557fe5b6101b5611125565b60408051918252519081900360200190f35b60006000366040518083838082843782019150509250505060405180910390206104b88161112b565b1561057657600160a060020a0383166000908152610105602052604090205491508115156104e557610576565b60016001540360005411156104f957610576565b6000600583610100811061050957fe5b0160005b5055600160a060020a03831660009081526101056020526040812055610531611296565b610539611386565b60408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a15b5b5b505050565b600160a060020a03811660009081526101056020526040812054115b919050565b60015481565b60045481565b6000366040518083838082843782019150509250505060405180910390206105d18161112b565b156105dc5760006003555b5b5b50565b60035481565b60003660405180838380828437820191505092505050604051809103902061060e8161112b565b156106d15761061c8261057d565b15610626576106d1565b61062e611296565b60015460fa901061064157610641611386565b5b60015460fa9010610652576106d1565b60018054810190819055600160a060020a03831690600590610100811061067557fe5b0160005b5055600154600160a060020a03831660008181526101056020908152604091829020939093558051918252517f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3929181900390910190a15b5b5b5050565b60005481565b60006000826106eb8161112b565b15610a255760008481526101086020526040902054600160a060020a031615158061072757506000848152610108602052604090206001015415155b80610754575060008481526101086020526040902060029081015461010060018216150260001901160415155b15610a255760008481526101086020526040902054600160a060020a0316151561082c57600084815261010860209081526040918290206001808201546002928301805486516000199482161561010002949094011693909304601f810185900485028301850190955284825261082594909391929183018282801561081b5780601f106107f05761010080835404028352916020019161081b565b820191906000526020600020905b8154815290600101906020018083116107fe57829003601f168201915b50505050506114c2565b91506108e3565b60008481526101086020526040908190208054600180830154935160029384018054600160a060020a0390941695949093919283928592918116156101000260001901160480156108be5780601f10610893576101008083540402835291602001916108be565b820191906000526020600020905b8154815290600101906020018083116108a157829003601f168201915b505091505060006040518083038185876185025a03f19250505015156108e357610000565b5b6000848152610108602090815260409182902060018082015482548551600160a060020a033381811683529682018c90529681018390529086166060820181905295881660a082015260c06080820181815260029586018054958616156101000260001901909516959095049082018190527fe3a3a4111a84df27d76b68dc721e65c7711605ea5eee4afd3a9c58195217365c968b959394909390928a9290919060e0830190859080156109d95780601f106109ae576101008083540402835291602001916109d9565b820191906000526020600020905b8154815290600101906020018083116109bc57829003601f168201915b505097505050505050505060405180910390a16000848152610108602052604081208054600160a060020a03191681556001810182905590610a1e6002830182611557565b5050600192505b5b5b5b5050919050565b6002819055610a3c6114dc565b6004555b50565b600036604051808383808284378201915050925050506040518091039020610a6a8161112b565b156106d15760028290555b5b5b5050565b60006000610a883361057d565b15610d505782158015610a9f5750610a9f856114eb565b5b80610aad57506000546001145b15610bef57600160a060020a0386161515610b0357610afc8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437506114c2945050505050565b9050610b43565b85600160a060020a03168585856040518083838082843782019150509250505060006040518083038185876185025a03f1925050501515610b4357610000565b5b7f9738cd1a8777c86b011f7b01d87d484217dc6ab5154a9d41eda5d14af8caf2923386888787866040518087600160a060020a0316600160a060020a0316815260200186815260200185600160a060020a0316600160a060020a031681526020018060200183600160a060020a0316600160a060020a0316815260200182810382528585828181526020019250808284376040519201829003995090975050505050505050a1610d50565b600036436040518084848082843791909101928352505060408051602092819003830190206000818152610108909352912054909450600160a060020a0316159150508015610c4e575060008281526101086020526040902060010154155b8015610c7b5750600082815261010860205260409020600290810154610100600182161502600019011604155b15610cbf576000828152610108602052604090208054600160a060020a031916600160a060020a03881617815560018101869055610cbd90600201858561159f565b505b610cc8826106dd565b1515610d505760408051838152600160a060020a033381811660208401529282018890528816606082015260a0608082018181529082018690527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32928592909189918b918a918a9160c082018484808284376040519201829003995090975050505050505050a15b5b5b5b5b50949350505050565b600160a060020a033316600090815261010560205260408120549080821515610d8557610e01565b50506000828152610106602052604081206001810154600284900a929083161115610e015780546001908101825581018054839003905560408051600160a060020a03331681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5b50505050565b600036604051808383808284378201915050925050506040518091039020610e2f8161112b565b156106d157600154821115610e43576106d1565b6000829055610e50611296565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15b5b5b5050565b600082815261010660209081526040808320600160a060020a038516845261010590925282205482811515610ec25760009350610ed6565b8160020a9050808360010154166000141593505b50505092915050565b60006005600183016101008110610ef257fe5b0160005b505490505b919050565b815160019081018155600090600160a060020a033316906005905b0160005b505550600160a060020a033316600090815261010560205260408120600190555b8251811015610fc9578281815181101515610f5757fe5b60209081029091010151600160a060020a03166005600283016101008110610f7b57fe5b0160005b50819055508060020161010560008584815181101515610f9b57fe5b90602001906020020151600160a060020a03168152602001908152602001600020819055505b600101610f40565b60008290555b505050565b600036604051808383808284378201915050925050506040518091039020610ffb8161112b565b156106d15781600160a060020a0316ff5b5b5b5050565b61101b81610a2f565b6105768383610f00565b5b505050565b60006000366040518083838082843782019150509250505060405180910390206110548161112b565b15610e01576110628361057d565b1561106c57610e01565b600160a060020a03841660009081526101056020526040902054915081151561109457610e01565b61109c611296565b600160a060020a03831660058361010081106110b457fe5b0160005b5055600160a060020a0380851660008181526101056020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b5b5b50505050565b60025481565b600160a060020a0333166000908152610105602052604081205481808215156111535761128c565b600085815261010660205260409020805490925015156111b65760008054835560018084019190915561010780549161118e9190830161161e565b60028301819055610107805487929081106111a557fe5b906000526020600020900160005b50555b8260020a9050808260010154166000141561128c5760408051600160a060020a03331681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a181546001901161127957600085815261010660205260409020600201546101078054909190811061123c57fe5b906000526020600020900160005b50600090819055858152610106602052604081208181556001808201839055600290910191909155935061128c565b8154600019018255600182018054821790555b5b5b505050919050565b6101075460005b81811015611374576101086000610107838154811015156112ba57fe5b906000526020600020900160005b50548152602081019190915260400160009081208054600160a060020a031916815560018101829055906112ff6002830182611557565b505061010780548290811061131057fe5b906000526020600020900160005b50541561136b5761010660006101078381548110151561133a57fe5b906000526020600020900160005b505481526020810191909152604001600090812081815560018101829055600201555b5b60010161129d565b6106d16101076000611648565b5b5050565b60015b6001548110156105dc575b600154811080156113b7575060058161010081106113ae57fe5b0160005b505415155b156113c457600101611394565b5b60016001541180156113eb575060015460059061010081106113e357fe5b0160005b5054155b156113ff57600180546000190190556113c4565b600154811080156114255750600154600590610100811061141c57fe5b0160005b505415155b80156114425750600581610100811061143a57fe5b0160005b5054155b156114b957600154600590610100811061145857fe5b0160005b5054600582610100811061146c57fe5b0160005b5055806101056000600583610100811061148657fe5b0160005b505481526020019081526020016000208190555060006005600154610100811015156114b257fe5b0160005b50555b611389565b5b50565b600081516020830184f09050803b15610000575b92915050565b600062015180425b0490505b90565b60006114f63361057d565b15610599576004546115066114dc565b111561151d5760006003556115196114dc565b6004555b600354828101108015906115375750600254826003540111155b1561154c575060038054820190556001610599565b5060005b5b5b919050565b50805460018160011615610100020316600290046000825580601f1061157d57506105dc565b601f0160209004906000526020600020908101906105dc919061166a565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115e05782800160ff1982351617855561160d565b8280016001018555821561160d579182015b8281111561160d5782358255916020019190600101906115f2565b5b5061161a92915061166a565b5090565b8154818355818115116105765760008381526020902061057691810190830161166a565b5b505050565b50805460008255906000526020600020908101906105dc919061166a565b5b50565b6114e891905b8082111561161a5760008155600101611670565b5090565b90565b6114e891905b8082111561161a5760008155600101611670565b5090565b905600a165627a7a723058206560ca68304798da7e3be68397368a30b63db1453ff138ff8f765e80080025af0029'; +export const wallet = '0x6060604052341561000c57fe5b60405161048538038061048583398101604090815281516020830151918301519201915b604080517f696e697457616c6c657428616464726573735b5d2c75696e743235362c75696e81527f7432353629000000000000000000000000000000000000000000000000000000602080830191909152915190819003602501902084516000829052909173_____________WalletLibrary______________91600281019160049182010290819038829003903960006000600483016000866127105a03f45b505050505050505b61039d806100e86000396000f300606060405236156100725763ffffffff60e060020a6000350416632f54bf6e811461012d5780634123cb6b1461015d578063523750931461017f578063659010e7146101a1578063746c9171146101c3578063c2cf7326146101e5578063c41a360a14610218578063f1736d8614610247575b61012b5b60003411156100c75760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a1610127565b60003611156101275773_____________WalletLibrary______________600160a060020a0316600036600060405160200152604051808383808284378201915050925050506020604051808303818560325a03f4151561012457fe5b50505b5b5b565b005b341561013557fe5b610149600160a060020a0360043516610269565b604080519115158252519081900360200190f35b341561016557fe5b61016d6102cd565b60408051918252519081900360200190f35b341561018757fe5b61016d6102d3565b60408051918252519081900360200190f35b34156101a957fe5b61016d6102d9565b60408051918252519081900360200190f35b34156101cb57fe5b61016d6102df565b60408051918252519081900360200190f35b34156101ed57fe5b610149600435600160a060020a03602435166102e5565b604080519115158252519081900360200190f35b341561022057fe5b61022b60043561034a565b60408051600160a060020a039092168252519081900360200190f35b341561024f57fe5b61016d61036b565b60408051918252519081900360200190f35b600073_____________WalletLibrary______________600160a060020a0316600036600060405160200152604051808383808284378201915050925050506020604051808303818560325a03f415156102bf57fe5b50506040515190505b919050565b60015481565b60045481565b60035481565b60005481565b600073_____________WalletLibrary______________600160a060020a0316600036600060405160200152604051808383808284378201915050925050506020604051808303818560325a03f4151561033b57fe5b50506040515190505b92915050565b6000600560018301610100811061035d57fe5b0160005b505490505b919050565b600254815600a165627a7a72305820c20a8475c42598c198f6629bada37e1b234da85ac2c0cbac3d96089030b180400029'; +export const walletLibrary = '0x6060604052341561000c57fe5b5b61170f8061001c6000396000f300606060405236156101015763ffffffff60e060020a600035041663173825d981146101575780632f54bf6e146101755780634123cb6b146101a557806352375093146101c75780635c52c2f5146101e9578063659010e7146101fb5780637065cb481461021d578063746c91711461023b578063797af6271461025d5780639da5e0eb14610284578063b20d30a914610299578063b61d27f6146102ae578063b75c7dc6146102ec578063ba51a6df14610301578063c2cf732614610316578063c41a360a14610349578063c57c5f6014610378578063cbf0b0c0146103cf578063e46dcfeb146103ed578063f00d4b5d14610449578063f1736d861461046d575b6101555b60003411156101525760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b5b565b005b341561015f57fe5b610155600160a060020a036004351661048f565b005b341561017d57fe5b610191600160a060020a036004351661057d565b604080519115158252519081900360200190f35b34156101ad57fe5b6101b561059e565b60408051918252519081900360200190f35b34156101cf57fe5b6101b56105a4565b60408051918252519081900360200190f35b34156101f157fe5b6101556105aa565b005b341561020357fe5b6101b56105e1565b60408051918252519081900360200190f35b341561022557fe5b610155600160a060020a03600435166105e7565b005b341561024357fe5b6101b56106d7565b60408051918252519081900360200190f35b341561026557fe5b6101916004356106dd565b604080519115158252519081900360200190f35b341561028c57fe5b610155600435610a30565b005b34156102a157fe5b610155600435610a56565b005b34156102b657fe5b6101b560048035600160a060020a0316906024803591604435918201910135610a8e565b60408051918252519081900360200190f35b34156102f457fe5b610155600435610d71565b005b341561030957fe5b610155600435610e1c565b005b341561031e57fe5b610191600435600160a060020a0360243516610e9e565b604080519115158252519081900360200190f35b341561035157fe5b61035c600435610ef3565b60408051600160a060020a039092168252519081900360200190f35b341561038057fe5b6101556004808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496505093359350610f1492505050565b005b34156103d757fe5b610155600160a060020a0360043516610ff9565b005b34156103f557fe5b6101556004808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496505084359460200135935061103792505050565b005b341561045157fe5b610155600160a060020a0360043581169060243516611062565b005b341561047557fe5b6101b561115c565b60408051918252519081900360200190f35b60006000366040518083838082843782019150509250505060405180910390206104b881611162565b1561057657600160a060020a0383166000908152610105602052604090205491508115156104e557610576565b60016001540360005411156104f957610576565b6000600583610100811061050957fe5b0160005b5055600160a060020a038316600090815261010560205260408120556105316112cd565b6105396113bd565b60408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a15b5b5b505050565b600160a060020a03811660009081526101056020526040812054115b919050565b60015481565b60045481565b6000366040518083838082843782019150509250505060405180910390206105d181611162565b156105dc5760006003555b5b5b50565b60035481565b60003660405180838380828437820191505092505050604051809103902061060e81611162565b156106d15761061c8261057d565b15610626576106d1565b61062e6112cd565b60015460fa9010610641576106416113bd565b5b60015460fa9010610652576106d1565b60018054810190819055600160a060020a03831690600590610100811061067557fe5b0160005b5055600154600160a060020a03831660008181526101056020908152604091829020939093558051918252517f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3929181900390910190a15b5b5b5050565b60005481565b60006000826106eb81611162565b15610a265760008481526101086020526040902054600160a060020a031615158061072757506000848152610108602052604090206001015415155b80610754575060008481526101086020526040902060029081015461010060018216150260001901160415155b15610a265760008481526101086020526040902054600160a060020a0316151561082c57600084815261010860209081526040918290206001808201546002928301805486516000199482161561010002949094011693909304601f810185900485028301850190955284825261082594909391929183018282801561081b5780601f106107f05761010080835404028352916020019161081b565b820191906000526020600020905b8154815290600101906020018083116107fe57829003601f168201915b50505050506114f9565b91506108e4565b60008481526101086020526040908190208054600180830154935160029384018054600160a060020a0390941695949093919283928592918116156101000260001901160480156108be5780601f10610893576101008083540402835291602001916108be565b820191906000526020600020905b8154815290600101906020018083116108a157829003601f168201915b505091505060006040518083038185876185025a03f19250505015156108e45760006000fd5b5b6000848152610108602090815260409182902060018082015482548551600160a060020a033381811683529682018c90529681018390529086166060820181905295881660a082015260c06080820181815260029586018054958616156101000260001901909516959095049082018190527fe3a3a4111a84df27d76b68dc721e65c7711605ea5eee4afd3a9c58195217365c968b959394909390928a9290919060e0830190859080156109da5780601f106109af576101008083540402835291602001916109da565b820191906000526020600020905b8154815290600101906020018083116109bd57829003601f168201915b505097505050505050505060405180910390a16000848152610108602052604081208054600160a060020a03191681556001810182905590610a1f600283018261158e565b5050600192505b5b5b5b5050919050565b60006001541115610a415760006000fd5b6002819055610a4e611513565b6004555b5b50565b600036604051808383808284378201915050925050506040518091039020610a7d81611162565b156106d15760028290555b5b5b5050565b60006000610a9b3361057d565b15610d645782158015610ab25750610ab285611522565b5b80610ac057506000546001145b15610c0357600160a060020a0386161515610b1657610b0f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437506114f9945050505050565b9050610b57565b85600160a060020a03168585856040518083838082843782019150509250505060006040518083038185876185025a03f1925050501515610b575760006000fd5b5b7f9738cd1a8777c86b011f7b01d87d484217dc6ab5154a9d41eda5d14af8caf2923386888787866040518087600160a060020a0316600160a060020a0316815260200186815260200185600160a060020a0316600160a060020a031681526020018060200183600160a060020a0316600160a060020a0316815260200182810382528585828181526020019250808284376040519201829003995090975050505050505050a1610d64565b600036436040518084848082843791909101928352505060408051602092819003830190206000818152610108909352912054909450600160a060020a0316159150508015610c62575060008281526101086020526040902060010154155b8015610c8f5750600082815261010860205260409020600290810154610100600182161502600019011604155b15610cd3576000828152610108602052604090208054600160a060020a031916600160a060020a03881617815560018101869055610cd19060020185856115d6565b505b610cdc826106dd565b1515610d645760408051838152600160a060020a033381811660208401529282018890528816606082015260a0608082018181529082018690527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32928592909189918b918a918a9160c082018484808284376040519201829003995090975050505050505050a15b5b5b5b5b50949350505050565b600160a060020a033316600090815261010560205260408120549080821515610d9957610e15565b50506000828152610106602052604081206001810154600284900a929083161115610e155780546001908101825581018054839003905560408051600160a060020a03331681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5b50505050565b600036604051808383808284378201915050925050506040518091039020610e4381611162565b156106d157600154821115610e57576106d1565b6000829055610e646112cd565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15b5b5b5050565b600082815261010660209081526040808320600160a060020a038516845261010590925282205482811515610ed65760009350610eea565b8160020a9050808360010154166000141593505b50505092915050565b60006005600183016101008110610f0657fe5b0160005b505490505b919050565b600060006001541115610f275760006000fd5b825160019081018155600160a060020a033316906005905b0160005b505550600160a060020a033316600090815261010560205260408120600190555b8251811015610fed578281815181101515610f7b57fe5b60209081029091010151600160a060020a03166005600283016101008110610f9f57fe5b0160005b50819055508060020161010560008584815181101515610fbf57fe5b90602001906020020151600160a060020a03168152602001908152602001600020819055505b600101610f64565b60008290555b5b505050565b60003660405180838380828437820191505092505050604051809103902061102081611162565b156106d15781600160a060020a0316ff5b5b5b5050565b600060015411156110485760006000fd5b61105181610a30565b6105768383610f14565b5b5b505050565b600060003660405180838380828437820191505092505050604051809103902061108b81611162565b15610e15576110998361057d565b156110a357610e15565b600160a060020a0384166000908152610105602052604090205491508115156110cb57610e15565b6110d36112cd565b600160a060020a03831660058361010081106110eb57fe5b0160005b5055600160a060020a0380851660008181526101056020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b5b5b50505050565b60025481565b600160a060020a03331660009081526101056020526040812054818082151561118a576112c3565b600085815261010660205260409020805490925015156111ed576000805483556001808401919091556101078054916111c591908301611655565b60028301819055610107805487929081106111dc57fe5b906000526020600020900160005b50555b8260020a905080826001015416600014156112c35760408051600160a060020a03331681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18154600190116112b057600085815261010660205260409020600201546101078054909190811061127357fe5b906000526020600020900160005b5060009081905585815261010660205260408120818155600180820183905560029091019190915593506112c3565b8154600019018255600182018054821790555b5b5b505050919050565b6101075460005b818110156113ab576101086000610107838154811015156112f157fe5b906000526020600020900160005b50548152602081019190915260400160009081208054600160a060020a03191681556001810182905590611336600283018261158e565b505061010780548290811061134757fe5b906000526020600020900160005b5054156113a25761010660006101078381548110151561137157fe5b906000526020600020900160005b505481526020810191909152604001600090812081815560018101829055600201555b5b6001016112d4565b6106d1610107600061167f565b5b5050565b60015b6001548110156105dc575b600154811080156113ee575060058161010081106113e557fe5b0160005b505415155b156113fb576001016113cb565b5b60016001541180156114225750600154600590610100811061141a57fe5b0160005b5054155b1561143657600180546000190190556113fb565b6001548110801561145c5750600154600590610100811061145357fe5b0160005b505415155b80156114795750600581610100811061147157fe5b0160005b5054155b156114f057600154600590610100811061148f57fe5b0160005b505460058261010081106114a357fe5b0160005b505580610105600060058361010081106114bd57fe5b0160005b505481526020019081526020016000208190555060006005600154610100811015156114e957fe5b0160005b50555b6113c0565b5b50565b600081516020830184f09050803b15610000575b92915050565b600062015180425b0490505b90565b600061152d3361057d565b156105995760045461153d611513565b1115611554576000600355611550611513565b6004555b6003548281011080159061156e5750600254826003540111155b15611583575060038054820190556001610599565b5060005b5b5b919050565b50805460018160011615610100020316600290046000825580601f106115b457506105dc565b601f0160209004906000526020600020908101906105dc91906116a1565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106116175782800160ff19823516178555611644565b82800160010185558215611644579182015b82811115611644578235825591602001919060010190611629565b5b506116519291506116a1565b5090565b815481835581811511610576576000838152602090206105769181019083016116a1565b5b505050565b50805460008255906000526020600020908101906105dc91906116a1565b5b50565b61151f91905b8082111561165157600081556001016116a7565b5090565b90565b61151f91905b8082111561165157600081556001016116a7565b5090565b905600a165627a7a723058209a3af51063f944081cd5ee8601e4e655f25cf7bc219a7983cda60f163f1709a70029'; export const walletLibraryABI = '[{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"removeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_numOwners","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_lastDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"resetSpentToday","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_spentToday","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"addOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_required","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_h","type":"bytes32"}],"name":"confirm","outputs":[{"name":"o_success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_limit","type":"uint256"}],"name":"initDaylimit","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newLimit","type":"uint256"}],"name":"setDailyLimit","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"o_hash","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_operation","type":"bytes32"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newRequired","type":"uint256"}],"name":"changeRequirement","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_operation","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"hasConfirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"ownerIndex","type":"uint256"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owners","type":"address[]"},{"name":"_required","type":"uint256"}],"name":"initMultiowned","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"}],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owners","type":"address[]"},{"name":"_required","type":"uint256"},{"name":"_daylimit","type":"uint256"}],"name":"initWallet","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_dailyLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Confirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"},{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"}],"name":"OwnerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newRequirement","type":"uint256"}],"name":"RequirementChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"},{"indexed":false,"name":"created","type":"address"}],"name":"SingleTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"},{"indexed":false,"name":"created","type":"address"}],"name":"MultiTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"initiator","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"ConfirmationNeeded","type":"event"}]'; -export const walletSourceURL = 'https://github.com/paritytech/parity/blob/c4196a5de31e0b97ec42d5263d9db404cea4a776/js/src/contracts/snippets/enhanced-wallet.sol'; +export const walletSourceURL = 'https://github.com/paritytech/parity/blob/6b0e4f9098be6b841353e7c4f116aa86b7c2e3d6/js/src/contracts/snippets/enhanced-wallet.sol'; export const walletLibraryRegKey = 'walletLibrary.v.2'; // Used if no Wallet Library found in registry... diff --git a/js/src/contracts/snippets/enhanced-wallet.sol b/js/src/contracts/snippets/enhanced-wallet.sol index 1f89b1f6f..90a15c070 100644 --- a/js/src/contracts/snippets/enhanced-wallet.sol +++ b/js/src/contracts/snippets/enhanced-wallet.sol @@ -104,7 +104,7 @@ contract WalletLibrary is WalletEvents { // constructor is given number of sigs required to do protected "onlymanyowners" transactions // as well as the selection of addresses capable of confirming them. - function initMultiowned(address[] _owners, uint _required) { + function initMultiowned(address[] _owners, uint _required) only_uninitialized { m_numOwners = _owners.length + 1; m_owners[1] = uint(msg.sender); m_ownerIndex[uint(msg.sender)] = 1; @@ -198,7 +198,7 @@ contract WalletLibrary is WalletEvents { } // constructor - stores initial daily limit and records the present day's index. - function initDaylimit(uint _limit) { + function initDaylimit(uint _limit) only_uninitialized { m_dailyLimit = _limit; m_lastDay = today(); } @@ -211,9 +211,12 @@ contract WalletLibrary is WalletEvents { m_spentToday = 0; } + // throw unless the contract is not yet initialized. + modifier only_uninitialized { if (m_numOwners > 0) throw; _; } + // constructor - just pass on the owner array to the multiowned and // the limit to daylimit - function initWallet(address[] _owners, uint _required, uint _daylimit) { + function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized { initDaylimit(_daylimit); initMultiowned(_owners, _required); } diff --git a/js/src/dapps/localtx/Application/application.js b/js/src/dapps/localtx/Application/application.js index 8efadcf1a..27dc41b3e 100644 --- a/js/src/dapps/localtx/Application/application.js +++ b/js/src/dapps/localtx/Application/application.js @@ -151,7 +151,7 @@ export default class Application extends Component { if (!transactions.length) { return ( -

The queue seems is empty.

+

The queue seems empty.

); } diff --git a/js/src/jsonrpc/interfaces/shh.js b/js/src/jsonrpc/interfaces/shh.js index 801c965d0..7084aa3bf 100644 --- a/js/src/jsonrpc/interfaces/shh.js +++ b/js/src/jsonrpc/interfaces/shh.js @@ -14,21 +14,37 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { Data, Quantity } from '../types'; +import { Data, Quantity, Float } from '../types'; export default { - version: { - nodoc: 'Not present in Rust code', + info: { desc: 'Returns the current whisper protocol version.', params: [], returns: { - type: String, - desc: 'The current whisper protocol version' + type: Object, + desc: 'The current whisper protocol version', + details: { + minPow: { + type: Float, + desc: 'required PoW threshold for a message to be accepted into the local pool, or null if there is empty space in the pool.' + }, + messages: { + type: Quantity, + desc: 'Number of messages in the pool.' + }, + memory: { + type: Quantity, + desc: 'Amount of memory used by messages in the pool.' + }, + targetMemory: { + type: Quantity, + desc: 'Target amount of memory for the pool.' + } + } } }, post: { - nodoc: 'Not present in Rust code', desc: 'Sends a whisper message.', params: [ { @@ -63,79 +79,122 @@ export default { } }, - newIdentity: { - nodoc: 'Not present in Rust code', - desc: 'Creates new whisper identity in the client.', + newKeyPair: { + desc: 'Generate a new key pair (identity) for asymmetric encryption.', params: [], returns: { type: Data, - desc: '60 Bytes - the address of the new identiy' + desc: '32 Bytes - the address of the new identiy' } }, - hasIdentity: { - nodoc: 'Not present in Rust code', - desc: 'Checks if the client hold the private keys for a given identity.', + addPrivateKey: { + desc: 'Import a private key to use for asymmetric decryption.', params: [ { type: Data, - desc: '60 Bytes - The identity address to check' + desc: '32 Bytes - The private key to import' } ], returns: { - type: Boolean, - desc: '`true` if the client holds the privatekey for that identity, otherwise `false`' + type: Data, + desc: '`32 Bytes` A unique identity to refer to this keypair by.' } }, - newGroup: { - nodoc: 'Not present in Rust code', - desc: '(?)', + newSymKey: { + desc: 'Generate a key pair(identity) for symmetric encryption.', params: [], returns: { - type: Data, desc: '60 Bytes - the address of the new group. (?)' + type: Data, + desc: '32 Bytes - the address of the new identiy' } }, - addToGroup: { - nodoc: 'Not present in Rust code', - desc: '(?)', + getPublicKey: { + desc: 'Get the public key associated with an asymmetric identity.', params: [ { type: Data, - desc: '60 Bytes - The identity address to add to a group (?)' + desc: '32 Bytes - The identity to fetch the public key for.' } ], returns: { - type: Boolean, - desc: '`true` if the identity was successfully added to the group, otherwise `false` (?)' + type: Data, + desc: '`64 Bytes` - The public key of the asymmetric identity.' } }, - newFilter: { - nodoc: 'Not present in Rust code', - desc: 'Creates filter to notify, when client receives whisper message matching the filter options.', + getPrivateKey: { + desc: 'Get the private key associated with an asymmetric identity.', + params: [ + { + type: Data, + desc: '32 Bytes - The identity to fetch the private key for.' + } + ], + returns: { + type: Data, + desc: '`32 Bytes` - The private key of the asymmetric identity.' + } + }, + + getSymKey: { + desc: 'Get the key associated with a symmetric identity.', + params: [ + { + type: Data, + desc: '`32 Bytes` - The identity to fetch the key for.' + } + ], + returns: { + type: Data, + desc: '`64 Bytes` - The key of the asymmetric identity.' + } + }, + + deleteKey: { + desc: 'Delete the key or key pair denoted by the given identity.', + params: [ + { + type: Data, + desc: '`32 Bytes` - The identity to remove.' + } + ], + returns: { + type: Data, + desc: '`true` on successful removal, `false` on unkown identity' + } + }, + + newMessageFilter: { + desc: 'Create a new polled filter for messages.', params: [ { type: Object, desc: 'The filter options:', details: { - to: { - type: Data, desc: '60 Bytes - Identity of the receiver. *When present it will try to decrypt any incoming message if the client holds the private key to this identity.*', + decryptWith: { + type: Data, + desc: '`32 bytes` - Identity of key used for description. null if listening for broadcasts.' + }, + from: { + type: Data, desc: '`32 Bytes` - if present, only accept messages signed by this key.', optional: true }, topics: { - type: Array, desc: 'Array of `Data` topics which the incoming message\'s topics should match. You can use the following combinations' + type: Array, + desc: 'Array of `Data`. Only accept messages matching these topics. Should be non-empty.' } } } ], returns: { - type: Quantity, - desc: 'The newly created filter' + type: Data, + desc: '`32 bytes` - Unique identity for this filter.' } }, - uninstallFilter: { + getFilterMesssages: { nodoc: 'Not present in Rust code', desc: 'Uninstalls a filter with given id. Should always be called when watch is no longer needed.\nAdditonally Filters timeout when they aren\'t requested with [shh_getFilterChanges](#shh_getfilterchanges) for a period of time.', params: [ @@ -150,30 +209,83 @@ export default { } }, - getFilterChanges: { - nodoc: 'Not present in Rust code', + getFilterMessages: { desc: 'Polling method for whisper filters. Returns new messages since the last call of this method.\n**Note** calling the [shh_getMessages](#shh_getmessages) method, will reset the buffer for this method, so that you won\'t receive duplicate messages.', params: [ { - type: Quantity, - desc: 'The filter id' + type: Data, + desc: '`32 bytes` - Unique identity to fetch changes for.' } ], returns: { type: Array, - desc: 'Array of messages received since last poll' + desc: 'Array of `messages` received since last poll', + details: { + from: { + type: Data, + desc: '`64 bytes` - Public key that signed this message or null' + }, + recipient: { + type: Data, + desc: '`32 bytes` - local identity which decrypted this message, or null if broadcast.' + }, + ttl: { + type: Quantity, + desc: 'time to live of the message in seconds.' + }, + topics: { + type: Array, + desc: 'Array of `Data` - Topics which matched the filter' + }, + timestamp: { + type: Quantity, + desc: 'Unix timestamp of the message' + }, + payload: { + type: Data, + desc: 'The message body' + }, + padding: { + type: Data, + desc: 'Optional padding which was decoded.' + } + } } }, - getMessages: { - nodoc: 'Not present in Rust code', - desc: 'Get all messages matching a filter. Unlike `shh_getFilterChanges` this returns all messages.', + deleteMessageFilter: { + desc: 'Delete a message filter by identifier', params: [ { - type: Quantity, - desc: 'The filter id' + type: Data, + desc: '`32 bytes` - The identity of the filter to delete.' } ], - returns: 'See [shh_getFilterChanges](#shh_getfilterchanges)' + returns: { + type: Boolean, + desc: '`true` on deletion, `false` on unrecognized ID.' + } + }, + subscribe: { + desc: 'Open a subscription to a filter.', + params: [{ + type: Data, + desc: 'See [shh_newMessageFilter](#shh_newmessagefilter)' + }], + returns: { + type: Quantity, + desc: 'Unique subscription identifier' + } + }, + unsubscribe: { + desc: 'Close a subscribed filter', + params: [{ + type: Quantity, + desc: 'Unique subscription identifier' + }], + returns: { + type: Boolean, + desc: '`true` on success, `false` on unkown subscription ID.' + } } }; diff --git a/js/src/jsonrpc/types.js b/js/src/jsonrpc/types.js index 52e79019e..c750932c9 100644 --- a/js/src/jsonrpc/types.js +++ b/js/src/jsonrpc/types.js @@ -22,6 +22,8 @@ export class Hash {} export class Integer {} +export class Float {} + export class Quantity {} export class BlockNumber { diff --git a/js/src/lib.rs.in b/js/src/lib.rs.in index 220811656..b811c1066 100644 --- a/js/src/lib.rs.in +++ b/js/src/lib.rs.in @@ -51,5 +51,5 @@ impl WebApp for App { #[test] fn test_js() { - parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR")); + parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR"), "build"); } diff --git a/js/src/modals/CreateAccount/store.js b/js/src/modals/CreateAccount/store.js index ab9879b8d..cc2160ab9 100644 --- a/js/src/modals/CreateAccount/store.js +++ b/js/src/modals/CreateAccount/store.js @@ -120,7 +120,6 @@ export default class Store { } @computed get qrAddressValid () { - console.log('qrValid', this.qrAddress, this._api.util.isAddressValid(this.qrAddress)); return this._api.util.isAddressValid(this.qrAddress); } @@ -191,7 +190,7 @@ export default class Store { } // FIXME: Current native signer encoding is not 100% for EIP-55, lowercase for now - this.qrAddress = this._api.util + this.qrAddress = qrAddress && this._api.util ? this._api.util.toChecksumAddress(qrAddress.toLowerCase()) : qrAddress; } diff --git a/js/src/modals/CreateWallet/createWalletStore.js b/js/src/modals/CreateWallet/createWalletStore.js index dd243f179..d614e8041 100644 --- a/js/src/modals/CreateWallet/createWalletStore.js +++ b/js/src/modals/CreateWallet/createWalletStore.js @@ -191,6 +191,8 @@ export default class CreateWalletStore { return null; // exception when registry is not available }) .then((address) => { + console.warn('WalletLibrary address in registry', address); + if (!address || /^(0x)?0*$/.test(address)) { return null; } diff --git a/js/src/redux/providers/balancesActions.js b/js/src/redux/providers/balancesActions.js index 73726e825..edfa7d2d3 100644 --- a/js/src/redux/providers/balancesActions.js +++ b/js/src/redux/providers/balancesActions.js @@ -144,34 +144,37 @@ export function updateTokensFilter (_addresses, _tokens, options = {}) { promises.push(api.eth.uninstallFilter(tokensFilter.filterToId)); } - const promise = Promise.all(promises); + Promise + .all([ + api.eth.blockNumber() + ].concat(promises)) + .then(([ block ]) => { + const topicsFrom = [ TRANSFER_SIGNATURE, addresses, null ]; + const topicsTo = [ TRANSFER_SIGNATURE, null, addresses ]; - const topicsFrom = [ TRANSFER_SIGNATURE, addresses, null ]; - const topicsTo = [ TRANSFER_SIGNATURE, null, addresses ]; + const filterOptions = { + fromBlock: block, + toBlock: 'pending', + address: tokenAddresses + }; - const filterOptions = { - fromBlock: 0, - toBlock: 'pending', - address: tokenAddresses - }; + const optionsFrom = { + ...filterOptions, + topics: topicsFrom + }; - const optionsFrom = { - ...filterOptions, - topics: topicsFrom - }; + const optionsTo = { + ...filterOptions, + topics: topicsTo + }; - const optionsTo = { - ...filterOptions, - topics: topicsTo - }; + const newFilters = Promise.all([ + api.eth.newFilter(optionsFrom), + api.eth.newFilter(optionsTo) + ]); - const newFilters = Promise.all([ - api.eth.newFilter(optionsFrom), - api.eth.newFilter(optionsTo) - ]); - - promise - .then(() => newFilters) + return newFilters; + }) .then(([ filterFromId, filterToId ]) => { const nextTokensFilter = { filterFromId, filterToId, diff --git a/js/src/redux/providers/status.js b/js/src/redux/providers/status.js index c8be9d55f..fc5dc38ba 100644 --- a/js/src/redux/providers/status.js +++ b/js/src/redux/providers/status.js @@ -228,9 +228,10 @@ export default class Status { _overallStatus = (health) => { const all = [health.peers, health.sync, health.time].filter(x => x); + const allNoTime = [health.peers, health.sync].filter(x => x); const statuses = all.map(x => x.status); const bad = statuses.find(x => x === STATUS_BAD); - const needsAttention = statuses.find(x => x === STATUS_WARN); + const needsAttention = allNoTime.map(x => x.status).find(x => x === STATUS_WARN); const message = all.map(x => x.message).filter(x => x); if (all.length) { diff --git a/js/src/redux/providers/statusReducer.js b/js/src/redux/providers/statusReducer.js index 23da8616f..23635cc8a 100644 --- a/js/src/redux/providers/statusReducer.js +++ b/js/src/redux/providers/statusReducer.js @@ -35,7 +35,7 @@ const initialState = { status: DEFAULT_STATUS }, overall: { - isReady: false, + isNotReady: true, status: DEFAULT_STATUS, message: [] } diff --git a/js/src/secureApi.js b/js/src/secureApi.js index b539f3ece..c34f71dd9 100644 --- a/js/src/secureApi.js +++ b/js/src/secureApi.js @@ -101,13 +101,7 @@ export default class SecureApi extends Api { return 'dapps.parity'; } - const { host } = this._dappsAddress; - - if (!host || host === '0.0.0.0') { - return window.location.hostname; - } - - return host; + return this._dappsAddress.host; } get isConnecting () { @@ -173,6 +167,25 @@ export default class SecureApi extends Api { }); } + /** + * Resolves a wildcard address to `window.location.hostname`; + */ + _resolveHost (url) { + const parts = url ? url.split(':') : []; + const port = parts[1]; + let host = parts[0]; + + if (!host) { + return host; + } + + if (host === '0.0.0.0') { + host = window.location.hostname; + } + + return port ? `${host}:${port}` : host; + } + /** * Returns a Promise that gets resolved with * a boolean: `true` if the node is up, `false` @@ -316,8 +329,8 @@ export default class SecureApi extends Api { this._uiApi.parity.wsUrl() ]) .then(([dappsUrl, wsUrl]) => { - this._dappsUrl = dappsUrl; - this._wsUrl = wsUrl; + this._dappsUrl = this._resolveHost(dappsUrl); + this._wsUrl = this._resolveHost(wsUrl); }); } diff --git a/js/src/ui/ConfirmDialog/confirmDialog.js b/js/src/ui/ConfirmDialog/confirmDialog.js index 02f400e93..86f668a28 100644 --- a/js/src/ui/ConfirmDialog/confirmDialog.js +++ b/js/src/ui/ConfirmDialog/confirmDialog.js @@ -69,14 +69,14 @@ export default class ConfirmDialog extends Component { } key='deny' label={ labelDeny || DEFAULT_NO } onClick={ onDeny } />,