From a7782260ddbcf0d3acec93387182d36826fa7cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 12 Jun 2018 22:26:15 +0200 Subject: [PATCH 01/22] First version of contracts and tests --- .gitignore | 14 + .solcover.js | 6 + .soliumignore | 1 + .soliumrc.json | 22 + contracts/Curation.sol | 393 + contracts/interfaces/IRegistry.sol | 13 + contracts/interfaces/IStaking.sol | 13 + contracts/interfaces/IVoting.sol | 16 + migrations/1_initial_migration.js | 5 + package-lock.json | 10473 +++++++++++++++++++++++++++ package.json | 40 + test/TestCuration.sol | 19 + test/curation.js | 537 ++ test/mocks/CurationMock.sol | 28 + test/mocks/StakingMock.sol | 35 + test/mocks/VotingMock.sol | 53 + truffle.js | 1 + 17 files changed, 11669 insertions(+) create mode 100644 .gitignore create mode 100644 .solcover.js create mode 100644 .soliumignore create mode 100644 .soliumrc.json create mode 100644 contracts/Curation.sol create mode 100644 contracts/interfaces/IRegistry.sol create mode 100644 contracts/interfaces/IStaking.sol create mode 100644 contracts/interfaces/IVoting.sol create mode 100644 migrations/1_initial_migration.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 test/TestCuration.sol create mode 100644 test/curation.js create mode 100644 test/mocks/CurationMock.sol create mode 100644 test/mocks/StakingMock.sol create mode 100644 test/mocks/VotingMock.sol create mode 100644 truffle.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b67b77b --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Dependencies +node_modules + +# coverage +coverage +coverageEnv +coverage.json +scTopics +allFiredEvents + +artifact.json + +# truffle build artifacts +build diff --git a/.solcover.js b/.solcover.js new file mode 100644 index 0000000..2169f75 --- /dev/null +++ b/.solcover.js @@ -0,0 +1,6 @@ +module.exports = { + norpc: true, + // rsync is needed so symlinks are resolved on copy of lerna packages + testCommand: 'rsync --copy-links -r ../node_modules/@aragon node_modules && node --max-old-space-size=4096 ../node_modules/.bin/truffle test --network coverage', + copyNodeModules: true, +} diff --git a/.soliumignore b/.soliumignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.soliumignore @@ -0,0 +1 @@ + diff --git a/.soliumrc.json b/.soliumrc.json new file mode 100644 index 0000000..f69c670 --- /dev/null +++ b/.soliumrc.json @@ -0,0 +1,22 @@ +{ + "extends": "solium:all", + "rules": { + "imports-on-top": ["error"], + "variable-declarations": ["error"], + "array-declarations": ["error"], + "operator-whitespace": ["error"], + "lbrace": ["error"], + "mixedcase": 0, + "camelcase": ["error"], + "uppercase": 0, + "no-empty-blocks": ["error"], + "no-unused-vars": ["error"], + "quotes": ["error"], + "indentation": 0, + "whitespace": ["error"], + "deprecated-suicide": ["error"], + "arg-overflow": ["error", 8], + "pragma-on-top": ["error"], + "security/enforce-explicit-visibility": ["error"] + } +} diff --git a/contracts/Curation.sol b/contracts/Curation.sol new file mode 100644 index 0000000..2c45d55 --- /dev/null +++ b/contracts/Curation.sol @@ -0,0 +1,393 @@ +pragma solidity 0.4.18; + +import "@aragon/os/contracts/apps/AragonApp.sol"; +import "@aragon/os/contracts/common/IsContract.sol"; +import "@aragon/os/contracts/lib/misc/Migrations.sol"; +import "@aragon/os/contracts/lib/zeppelin/math/SafeMath.sol"; +import "@aragon/os/contracts/lib/zeppelin/math/SafeMath64.sol"; + +import "./interfaces/IRegistry.sol"; +import "./interfaces/IStaking.sol"; +import "./interfaces/IVoting.sol"; + + +contract Curation is AragonApp { + using SafeMath for uint256; + using SafeMath64 for uint64; + + uint64 constant public MAX_UINT64 = uint64(-1); + uint256 constant public PCT_BASE = 10 ** 18; // 0% = 0; 1% = 10^16; 100% = 10^18 + bytes32 constant public MIN_DEPOSIT_PARAM = keccak256("MIN_DEPOSIT_PARAM"); + bytes32 constant public APPLY_STAGE_LEN_PARAM = keccak256("APPLY_STAGE_LEN_PARAM"); + bytes32 constant public DISPENSATION_PCT_PARAM = keccak256("DISPENSATION_PCT_PARAM"); + + IRegistry public registry; + IStaking public staking; + IVoting public voting; + uint256 public minDeposit; + uint64 public applyStageLen; + uint256 public dispensationPct; + + bytes32 constant public CHANGE_PARAMS_ROLE = keccak256("CHANGE_PARAMS_ROLE"); + bytes32 constant public CHANGE_VOTING_APP_ROLE = keccak256("CHANGE_VOTING_APP_ROLE"); + + // TODO!!! + enum TimeUnit { Blocks, Seconds } + + struct Application { + address applicant; + uint64 date; + bool registered; + bytes data; + uint256 amount; + uint256 lockId; + } + + struct Challenge { + address challenger; + uint64 date; + bool resolved; + uint256 amount; + uint256 lockId; + uint256 voteId; + uint256 dispensationPct; + mapping(address => bool) claims; // participants who already claimed their reward + } + + mapping(bytes32 => Application) applications; + mapping(bytes32 => Challenge) challenges; + mapping(uint256 => bool) usedLocks; + + event NewApplication(bytes32 applicationId, address applicant); + event NewChallenge(bytes32 applicationId, bytes32 challengeId, address challenger); + event ResolvedChallenge(bytes32 applicationId, bytes32 challengeId, bool result); + + /** + * @notice Initializes Curation app with + * @param _registry TODO + */ + function initialize( + IRegistry _registry, + IStaking _staking, + IVoting _voting, + uint256 _minDeposit, + uint64 _applyStageLen, + uint256 _dispensationPct + ) + onlyInit + external + { + initialized(); + + require(isContract(_registry)); + require(isContract(_staking)); + + registry = _registry; + staking = _staking; + _setVotingApp(_voting); + + _setMinDeposit(_minDeposit); + _setApplyStageLen(_applyStageLen); + _setDispensationPct(_dispensationPct); + } + + function newApplication(bytes data, uint256 lockId) isInitialized public returns (bytes32 applicationId) { + applicationId = keccak256(data); + + require(data.length != 0); + // check data doesn't have an ongoing application + require(!applicationExists(applicationId)); + // check data doesn't exist in Registry + require(!registry.exists(applicationId)); + + // check locked tokens + uint256 amount = _checkLock(lockId, MAX_UINT64); + + applications[applicationId] = Application({ + applicant: msg.sender, + date: uint64(getTimestamp()), + registered: false, + data: data, + amount: amount, + lockId: lockId + }); + + // register used lock + NewApplication(applicationId, msg.sender); + } + + function challengeApplication(bytes32 applicationId, uint256 lockId) isInitialized public returns(bytes32) { + // check application doesn't have an ongoing challenge + require(!challengeExists(applicationId)); + // check locked tokens + uint256 amount = _checkLock(lockId, uint64(getTimestamp()).add(applyStageLen)); + + // touch-and-remove case + Application memory application = applications[applicationId]; + if (application.amount < minDeposit) { + registry.remove(applicationId); + staking.unlock(application.applicant, application.lockId); + staking.unlock(msg.sender, lockId); + return 0; + } + + // create vote + // TODO: script + // TODO: metadata + uint256 voteId = voting.newVote("", ""); + + challenges[applicationId] = Challenge({ + challenger: msg.sender, + date: uint64(getTimestamp()), + resolved: false, + amount: amount, + lockId: lockId, + voteId: voteId, + dispensationPct: dispensationPct + }); + + // TODO: ids? + NewChallenge(applicationId, applicationId, msg.sender); + + return applicationId; + } + + function resolveChallenge(bytes32 challengeId) isInitialized public { + Challenge storage challenge = challenges[challengeId]; + Application storage application = applications[challengeId]; + + require(!challenge.resolved); + // TODO: canExecute?? + require(voting.isClosed(challenge.voteId)); + + bool voteResult; + (voteResult,,) = voting.getVoteResult(challenge.voteId); + + if (voteResult == false) { // challenge not accepted (application remains) + // it's still in application phase (not registered yet) + if (!application.registered) { + // insert in Registry app + registry.add(application.data); + application.registered = true; + } + // Remove applicant used lock + delete(usedLocks[application.lockId]); + // Unlock challenger tokens from Staking app + // TODO: unlock partially only! + staking.unlock(challenge.challenger, challenge.lockId); + // Redistribute tokens + staking.moveTokens(challenge.challenger, application.applicant, challenge.amount.mul(dispensationPct) / PCT_BASE); + // TODO: unlock?!! + } else { // challenge accepted (application rejected) + // it has been already registered + if (application.registered) { + // remove from Registry app + registry.remove(challengeId); + } + // Remove challenger used lock + delete(usedLocks[challenge.lockId]); + // Unlock applicant tokens from Staking app + // TODO: unlock partially only! + staking.unlock(application.applicant, application.lockId); + // Redistribute tokens + staking.moveTokens(application.applicant, challenge.challenger, application.amount.mul(dispensationPct) / PCT_BASE); + } + + challenge.resolved = true; + } + + function claimReward(bytes32 challengeId) isInitialized public { + require(isChallengeResolved(challengeId)); + + Challenge storage challenge = challenges[challengeId]; + Application memory application = applications[challengeId]; + + // avoid claiming twice + require(!challenge.claims[msg.sender]); + + bool voteResult; + uint256 totalWinningStake; + (voteResult, totalWinningStake,) = voting.getVoteResult(challenge.voteId); + + address loser; + uint256 loserLockId; + if (voteResult == false) { // applicant and won + loser = challenge.challenger; + loserLockId = challenge.lockId; + } else if (voteResult == true) { // challenger and won + loser = application.applicant; + loserLockId = application.lockId; + } + + // reward as a voter + uint256 voterWinningStake = voting.getVoterWinningStake(challenge.voteId, msg.sender); + require(voterWinningStake > 0); + // amount * (voter / total) * (1 - dispensationPct) + uint256 reward = challenge.amount.mul(voterWinningStake).mul(PCT_BASE.sub(dispensationPct)) / (totalWinningStake * PCT_BASE); + // TODO: partial unlock + // Redistribute tokens + staking.moveTokens(loser, msg.sender, reward); + + // check if lock can be released + uint256 amount; + (amount, ) = staking.getLock(loser, loserLockId); + if (amount == 0) { // TODO: with truncating, this may never happen!! + delete(usedLocks[loserLockId]); + // Remove application, if it lost, as redistribution is done + if (voteResult == true) { + delete(applications[challengeId]); + } + } + + // register claim to avoid claiming it again + challenge.claims[msg.sender] = true; + } + + function registerApplication(bytes32 applicationId) isInitialized public { + require(canBeRegistered(applicationId)); + + Application storage application = applications[applicationId]; + require(!application.registered); + + // insert in Registry app + registry.add(application.data); + application.registered = true; + } + + function setVotingApp(IVoting _voting) authP(CHANGE_VOTING_APP_ROLE, arr(voting, _voting)) public { + _setVotingApp(_voting); + } + + function setMinDeposit(uint256 _minDeposit) authP(CHANGE_PARAMS_ROLE, arr(uint256(MIN_DEPOSIT_PARAM), _minDeposit)) public { + _setMinDeposit(_minDeposit); + } + + function setApplyStageLen(uint64 _applyStageLen) authP(CHANGE_PARAMS_ROLE, arr(uint256(APPLY_STAGE_LEN_PARAM), _applyStageLen)) public { + _setApplyStageLen(_applyStageLen); + } + + function setDispensationPct(uint256 _dispensationPct) authP(CHANGE_PARAMS_ROLE, arr(uint256(DISPENSATION_PCT_PARAM), _dispensationPct)) public { + require(_dispensationPct <= PCT_BASE); + + _setDispensationPct(_dispensationPct); + } + + function canBeRegistered(bytes32 applicationId) view public returns (bool) { + // no challenges + if (uint64(getTimestamp()) > applications[applicationId].date.add(applyStageLen) + && challenges[applicationId].challenger == address(0) ) { + return true; + } + + return false; + } + + function isChallengeResolved(bytes32 challengeId) view public returns (bool) { + return challenges[challengeId].resolved; + } + + function getApplication( + bytes32 applicationId + ) + view + external + returns ( + address applicant, + uint64 date, + bool registered, + bytes data, + uint256 amount, + uint256 lockId + ) + { + Application memory application = applications[applicationId]; + return ( + application.applicant, + application.date, + application.registered, + application.data, + application.amount, + application.lockId + ); + } + + function getChallenge( + bytes32 challengeId + ) + view + external + returns ( + address challenger, + uint64 date, + bool resolved, + uint256 amount, + uint256 lockId, + uint256 voteId, + uint256 dipsensationPct + ) + { + Challenge memory challenge = challenges[challengeId]; + return ( + challenge.challenger, + challenge.date, + challenge.resolved, + challenge.amount, + challenge.lockId, + challenge.voteId, + challenge.dispensationPct + ); + } + + function _checkLock(uint256 lockId, uint64 date) internal returns (uint256) { + // check lockId was not used before + require(!usedLocks[lockId]); + // get the lock + uint256 amount; + uint8 lockUnit; + uint64 lockEnds; + address unlocker; + (amount, lockUnit, lockEnds, unlocker, ) = staking.getLock(msg.sender, lockId); + // check unlocker + require(unlocker == address(this)); + // check enough amount + require(amount >= minDeposit); + // check time + require(lockUnit == uint8(TimeUnit.Seconds)); + require(lockEnds >= date); + + // mark it as used + usedLocks[lockId] = true; + + return amount; + } + + function _setVotingApp(IVoting _voting) internal { + require(isContract(address(_voting))); + + voting = _voting; + } + + function _setMinDeposit(uint256 _minDeposit) internal { + minDeposit = _minDeposit; + } + + function _setApplyStageLen(uint64 _applyStageLen) internal { + applyStageLen = _applyStageLen; + } + + function _setDispensationPct(uint256 _dispensationPct) internal { + dispensationPct = _dispensationPct; + } + + function applicationExists(bytes32 applicationId) view internal returns (bool) { + return applications[applicationId].data.length > 0; + } + + function challengeExists(bytes32 challengeId) view internal returns (bool) { + return challenges[challengeId].challenger != address(0); + } + + function getTimestamp() view internal returns (uint256) { + return now; + } +} diff --git a/contracts/interfaces/IRegistry.sol b/contracts/interfaces/IRegistry.sol new file mode 100644 index 0000000..da5b4a3 --- /dev/null +++ b/contracts/interfaces/IRegistry.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.4.18; + + +interface IRegistry { + function exists(bytes32 _id) public constant returns (bool); + function add(bytes _data) public returns (bytes32 _id); + function remove(bytes32 _id) public; +} + + +contract FakeRegistry { + // to work around coverage issue +} diff --git a/contracts/interfaces/IStaking.sol b/contracts/interfaces/IStaking.sol new file mode 100644 index 0000000..717c83c --- /dev/null +++ b/contracts/interfaces/IStaking.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.4.18; + + +interface IStaking { + function unlock(address acct, uint256 lockId) public; + function moveTokens(address from, address to, uint256 amount) external; + function getLock(address acct, uint256 lockId) public view returns (uint256 amount, uint8 lockUnit, uint64 lockEnds, address unlocker, bytes32 metadata); +} + + +contract FakeStaking { + // to work around coverage issue +} diff --git a/contracts/interfaces/IVoting.sol b/contracts/interfaces/IVoting.sol new file mode 100644 index 0000000..3ea00e0 --- /dev/null +++ b/contracts/interfaces/IVoting.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.4.18; + + +interface IVoting { + function newVote(bytes _executionScript, string _metadata) external returns (uint256 voteId); + function setVoteResult(uint256 voteId, bool result, uint256 winningStake, uint256 totalStake) public; + // TODO: canExecute or isClosed?? + function isClosed(uint256 voteId) view public returns (bool); + function getVoteResult(uint256 voteId) view public returns (bool, uint256, uint256); + function getVoterWinningStake(uint256 voteId, address voter) view public returns (uint256); +} + + +contract FakeVoting { + // to work around coverage issue +} diff --git a/migrations/1_initial_migration.js b/migrations/1_initial_migration.js new file mode 100644 index 0000000..1eb6f9d --- /dev/null +++ b/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +var Migrations = artifacts.require('./Migrations.sol') + +module.exports = function(deployer) { + deployer.deploy(Migrations) +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..04ace05 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10473 @@ +{ + "name": "curation", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@aragon/os": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@aragon/os/-/os-3.1.9.tgz", + "integrity": "sha512-KJZZuA/LeJti1OkNbA63J8oJq/iMqller8L1EooAX2JAHCDoE42ym0Mhu0k1PPRoHCcB1iBMJUgK6MHUR/5SOQ==", + "requires": { + "homedir": "0.6.0", + "truffle-hdwallet-provider": "0.0.3", + "truffle-privatekey-provider": "0.0.6" + } + }, + "@aragon/test-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@aragon/test-helpers/-/test-helpers-1.0.1.tgz", + "integrity": "sha512-CaROSFATybF2sr8jnmrhp9Br5RfLStFW3HAZ8CUFA4SSc9AlW2NfC30hIZM1L3X65tePzKVyF9uMT+WGaKw09g==", + "dev": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "1.0.1", + "glob-to-regexp": "0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.0.tgz", + "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", + "dev": true + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "0.3.0" + } + }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true + }, + "@types/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", + "dev": true, + "requires": { + "@types/node": "9.6.21" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "dev": true, + "requires": { + "@types/node": "9.6.21" + } + }, + "@types/node": { + "version": "9.6.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.21.tgz", + "integrity": "sha512-zQS6mHzxEstR8Vvnpc3JDUCDGWnHFzMTcBu9UCZoVLuj1Uvkkk0qFKJQEhlvbsX34m3xt12ejV09eO/ljZcn7A==", + "dev": true + }, + "@types/qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-mNhVdZHdtKHMMxbqzNK3RzkBcN1cux3AvuCYGTvjEIQT2uheH3eCAyYsbMbh2Bq8nXkeOWs1kyDiF7geWRFQ4Q==", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "abi-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-1.1.0.tgz", + "integrity": "sha512-nvLArBx0XOJufWyaghMKtIofZDBwEMdVZoqcetQOIe1qYeKZk4+kRYGPEJ5lt7dD3MLulw//amUzOJLM8eW5RA==", + "dev": true, + "requires": { + "babel-core": "6.26.3", + "babel-loader": "6.4.1", + "babel-plugin-add-module-exports": "0.2.1", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-runtime": "6.23.0", + "babel-preset-es2015": "6.24.1", + "chai": "3.5.0", + "web3": "0.18.4", + "webpack": "2.7.0" + } + }, + "abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "requires": { + "xtend": "4.0.1" + } + }, + "acorn": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.2.tgz", + "integrity": "sha512-zUzo1E5dI2Ey8+82egfnttyMlMZ2y0D8xOCO3PNPPlYXpl8NZvF6Qk9L9BEtJs+43FqEmfBViDqc5d1ckRDguw==", + "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 + } + } + }, + "aes-js": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", + "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=" + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "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=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "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=", + "dev": true + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "3.1.10", + "normalize-path": "2.1.1" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "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=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "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=", + "dev": true + }, + "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.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" + } + }, + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "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" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types": { + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", + "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", + "dev": true + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "4.17.10" + } + }, + "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-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "requires": { + "async": "2.6.1" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + }, + "babel-cli": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", + "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", + "dev": true, + "requires": { + "babel-core": "6.26.3", + "babel-polyfill": "6.26.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "chokidar": "1.7.0", + "commander": "2.15.1", + "convert-source-map": "1.5.1", + "fs-readdir-recursive": "1.1.0", + "glob": "7.1.2", + "lodash": "4.17.10", + "output-file-sync": "1.1.2", + "path-is-absolute": "1.0.1", + "slash": "1.0.0", + "source-map": "0.5.7", + "v8flags": "2.1.1" + }, + "dependencies": { + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true, + "optional": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "optional": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "optional": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.2.4", + "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" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "optional": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "optional": 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" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "optional": true, + "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.4" + } + } + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.1", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.10", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.10", + "source-map": "0.5.7", + "trim-right": "1.0.1" + } + }, + "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.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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.26.0", + "babel-types": "6.26.0" + } + }, + "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=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" + } + }, + "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.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" + } + }, + "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.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-loader": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.1.tgz", + "integrity": "sha1-CzQRLVsHSKjc2/Uaz2+b1C1QuMo=", + "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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-add-module-exports": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", + "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "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-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-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.26.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.26.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.26.0", + "babel-template": "6.26.0" + } + }, + "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.26.0", + "babel-template": "6.26.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.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" + } + }, + "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=", + "dev": true, + "requires": { + "babel-helper-define-map": "6.26.0", + "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.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.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=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.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=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.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.26.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.26.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.26.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "0.10.1" + } + }, + "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.26.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=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "regenerator-runtime": "0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + } + } + }, + "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=", + "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.26.0", + "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.26.2", + "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.26.0" + } + }, + "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" + } + }, + "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.26.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "6.26.3", + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "home-or-tmp": "2.0.0", + "lodash": "4.17.10", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.10" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.4", + "lodash": "4.17.10" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base-x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", + "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=" + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "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" + } + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "bignumber.js": { + "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "binaryextensions": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.1.tgz", + "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", + "dev": true + }, + "bindings": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" + }, + "bip39": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", + "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", + "requires": { + "create-hash": "1.2.0", + "pbkdf2": "3.0.16", + "randombytes": "2.0.6", + "safe-buffer": "5.1.2", + "unorm": "1.4.1" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "1.2.0", + "browserify-des": "1.0.1", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", + "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", + "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.8", + "randombytes": "2.0.6" + } + }, + "browserify-sha3": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", + "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", + "requires": { + "js-sha3": "0.3.1" + } + }, + "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.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.1" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" + } + }, + "bs58": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", + "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", + "requires": { + "base-x": "1.1.0" + } + }, + "bs58check": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", + "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", + "requires": { + "bs58": "3.1.0", + "create-hash": "1.2.0" + } + }, + "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.3.0", + "ieee754": "1.1.11", + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, + "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 + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + } + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + } + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "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.1.0", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "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" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "checkpoint-store": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", + "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", + "requires": { + "functional-red-black-tree": "1.0.1" + } + }, + "chokidar": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", + "dev": true, + "requires": { + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.2.4", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" + } + }, + "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.2" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.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=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-spinners": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", + "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "dev": true + }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "dev": true, + "requires": { + "colors": "1.0.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + } + } + }, + "cli-table2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz", + "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=", + "dev": true, + "requires": { + "colors": "1.3.0", + "lodash": "3.10.1", + "string-width": "1.0.2" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "1.0.2" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "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": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "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=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", + "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "process-nextick-args": "2.0.0", + "readable-stream": "2.3.6" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "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=" + }, + "coinstring": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", + "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", + "requires": { + "bs58": "2.0.1", + "create-hash": "1.2.0" + }, + "dependencies": { + "bs58": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", + "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=" + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz", + "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==", + "dev": true + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "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" + } + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "1.1.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "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" + } + }, + "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 + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "inherits": "2.0.3", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "1.0.4", + "path-key": "2.0.1", + "semver": "5.5.0", + "shebang-command": "1.2.0", + "which": "1.3.1" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.1", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.3", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", + "inherits": "2.0.3", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", + "randombytes": "2.0.6", + "randomfill": "1.0.4" + } + }, + "crypto-js": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", + "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" + }, + "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.45" + } + }, + "dargs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz", + "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "date-fns": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", + "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==", + "dev": true + }, + "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 + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "1.0.0" + } + }, + "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=" + }, + "deep-extend": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "dev": true + }, + "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 + }, + "deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "requires": { + "abstract-leveldown": "2.6.3" + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + }, + "dependencies": { + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + } + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "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.1" + } + }, + "detect-conflict": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", + "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" + } + }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "path-type": "3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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=" + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "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.2.0", + "create-hash": "1.2.0", + "create-hmac": "1.1.7" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "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.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", + "dev": true + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", + "dev": true + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "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.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1", + "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=", + "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.23" + } + }, + "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.8" + } + }, + "envinfo": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.10.0.tgz", + "integrity": "sha512-rXbzXWvnQxy+TcqZlARbWVQwgGVVouVJgFZhLVN5htjLxl1thstrP2ZGi0pXC309AbK7gVOPU+ulz/tmpCI7iw==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "1.0.1" + } + }, + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "dev": true, + "requires": { + "string-template": "0.2.1", + "xtend": "4.0.1" + } + }, + "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" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.3", + "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=", + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "next-tick": "1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "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.45", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "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.45", + "es6-iterator": "2.0.3", + "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.45" + } + }, + "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.45", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "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=", + "dev": true + }, + "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": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "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.1", + "estraverse": "4.2.0" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eth-gas-reporter": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.1.7.tgz", + "integrity": "sha512-OhB96aGc6RA7dBp3VRx+LsWSS0vaV0bNgRhyV1Q7t58lpfGhuDEmDA+DDRM14YEKVzagOouXsg948fPaWnFlLg==", + "dev": true, + "requires": { + "abi-decoder": "1.1.0", + "cli-table2": "0.2.0", + "colors": "1.3.0", + "lodash": "4.17.10", + "mocha": "3.5.3", + "req-cwd": "2.0.0", + "request": "2.87.0", + "request-promise-native": "1.0.5", + "shelljs": "0.7.8", + "solidity-parser-antlr": "0.2.11", + "sync-request": "6.0.0" + } + }, + "ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" + }, + "ethereumjs-account": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", + "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", + "requires": { + "ethereumjs-util": "5.2.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "ethjs-util": "0.1.5", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2", + "secp256k1": "3.5.0" + } + } + } + }, + "ethereumjs-block": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", + "requires": { + "async": "2.6.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.2.0", + "merkle-patricia-tree": "2.3.1" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "ethjs-util": "0.1.5", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2", + "secp256k1": "3.5.0" + } + } + } + }, + "ethereumjs-testrpc-sc": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.0.7.tgz", + "integrity": "sha512-6X/FknTe702L0UGtJ3V3qlh6HNavJkuuRxB18fbITOuOyvCike7O5TVYOthqyCdxgW+ZW/FQGtFpoKeuRZnbNg==", + "dev": true, + "requires": { + "webpack": "3.12.0" + }, + "dependencies": { + "ajv": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", + "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1", + "uri-js": "4.2.2" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "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" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "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.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "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" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "webpack": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", + "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==", + "dev": true, + "requires": { + "acorn": "5.6.2", + "acorn-dynamic-import": "2.0.2", + "ajv": "6.5.0", + "ajv-keywords": "3.2.0", + "async": "2.6.1", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.6.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "ethereumjs-tx": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", + "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", + "requires": { + "ethereum-common": "0.0.18", + "ethereumjs-util": "5.2.0" + }, + "dependencies": { + "ethereum-common": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", + "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" + }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "ethjs-util": "0.1.5", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2", + "secp256k1": "3.5.0" + } + } + } + }, + "ethereumjs-util": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", + "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "keccakjs": "0.2.1", + "rlp": "2.0.0", + "secp256k1": "3.5.0" + } + }, + "ethereumjs-vm": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz", + "integrity": "sha512-AJ7x44+xqyE5+UO3Nns19WkTdZfyqFZ+sEjIEpvme7Ipbe3iBU1uwCcHEdiu/yY9bdhr3IfSa/NfIKNeXPaRVQ==", + "requires": { + "async": "2.6.1", + "async-eventemitter": "0.2.4", + "ethereum-common": "0.2.0", + "ethereumjs-account": "2.0.5", + "ethereumjs-block": "1.7.1", + "ethereumjs-util": "5.2.0", + "fake-merkle-patricia-tree": "1.0.1", + "functional-red-black-tree": "1.0.1", + "merkle-patricia-tree": "2.3.1", + "rustbn.js": "0.1.2", + "safe-buffer": "5.1.2" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "ethjs-util": "0.1.5", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2", + "secp256k1": "3.5.0" + } + } + } + }, + "ethereumjs-wallet": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", + "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", + "requires": { + "aes-js": "0.2.4", + "bs58check": "1.3.4", + "ethereumjs-util": "4.5.0", + "hdkey": "0.7.1", + "scrypt.js": "0.2.0", + "utf8": "2.1.2", + "uuid": "2.0.3" + } + }, + "ethjs-util": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.5.tgz", + "integrity": "sha512-no39KWWT6yELU9HU+BMuEXUCzzQoiBqdXmCNB6HebXD2u+XJKV5XoI0DarEz7E28Ve0voGKztxaEChOcYa62XA==", + "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.45" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.2" + } + }, + "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" + }, + "dependencies": { + "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.3", + "shebang-command": "1.2.0", + "which": "1.3.1" + } + } + } + }, + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.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=", + "dev": true, + "requires": { + "fill-range": "2.2.4" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "3.0.0", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.23", + "tmp": "0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fake-merkle-patricia-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", + "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", + "requires": { + "checkpoint-store": "1.1.0" + } + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz", + "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "2.2.1", + "@nodelib/fs.stat": "1.1.0", + "glob-parent": "3.1.0", + "is-glob": "4.0.0", + "merge2": "1.2.2", + "micromatch": "3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "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-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" + } + }, + "first-chunk-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", + "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, + "flow-parser": { + "version": "0.74.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.74.0.tgz", + "integrity": "sha512-iQHi88aFCkPLr8cW1L9FtP9lmiT/9g20YaycW6sSWX6U9EdwN6K6OkWBlLhrfG5rbDJfJ9k0npVSfAkGNR7x2Q==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "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=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.6" + } + }, + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.10.0", + "node-pre-gyp": "0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "2.2.4" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.2.0", + "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" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": 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-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "2.1.2" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.1.1", + "yallist": "3.0.2" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "2.2.4" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.3", + "mkdirp": "0.5.1", + "needle": "2.2.0", + "nopt": "4.0.1", + "npm-packlist": "1.1.10", + "npmlog": "4.1.2", + "rc": "1.2.7", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "4.4.1" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.5.1", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.4", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.1", + "yallist": "3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "ganache-cli": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.1.0.tgz", + "integrity": "sha512-FdTeyk4uLRHGeFiMe+Qnh4Hc5KiTVqvRVVvLDFJEVVKC1P1yHhEgZeh9sp1KhuvxSrxToxgJS25UapYQwH4zHw==", + "dev": true, + "requires": { + "source-map-support": "0.5.6", + "webpack-cli": "2.1.5" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "requires": { + "buffer-from": "1.1.0", + "source-map": "0.6.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-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "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 + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "gh-got": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gh-got/-/gh-got-6.0.0.tgz", + "integrity": "sha512-F/mS+fsWQMo1zfgG9MD8KWvTWPPzzhuVwY++fhQ5Ggd+0P+CAMHtzMZhNxG+TqGfHDChJKsbh6otfMGqO2AKBw==", + "dev": true, + "requires": { + "got": "7.1.0", + "is-plain-obj": "1.1.0" + }, + "dependencies": { + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "requires": { + "decompress-response": "3.3.0", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-plain-obj": "1.1.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "isurl": "1.0.0", + "lowercase-keys": "1.0.1", + "p-cancelable": "0.3.0", + "p-timeout": "1.2.1", + "safe-buffer": "5.1.2", + "timed-out": "4.0.1", + "url-parse-lax": "1.0.0", + "url-to-options": "1.0.1" + } + }, + "p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true + }, + "p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "requires": { + "p-finally": "1.0.0" + } + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "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=", + "dev": true, + "requires": { + "prepend-http": "1.0.4" + } + } + } + }, + "github-username": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/github-username/-/github-username-4.1.0.tgz", + "integrity": "sha1-y+KABBiDIG2kISrp5LXxacML9Bc=", + "dev": true, + "requires": { + "gh-got": "6.0.0" + } + }, + "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" + } + }, + "glob-all": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.1.0.tgz", + "integrity": "sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs=", + "dev": true, + "requires": { + "glob": "7.1.2", + "yargs": "1.2.6" + }, + "dependencies": { + "minimist": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", + "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=", + "dev": true + }, + "yargs": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz", + "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=", + "dev": true, + "requires": { + "minimist": "0.1.0" + } + } + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "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=", + "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" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "requires": { + "min-document": "2.19.0", + "process": "0.5.2" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "1.0.2", + "is-windows": "1.0.2", + "resolve-dir": "1.0.1" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "2.0.2", + "homedir-polyfill": "1.0.1", + "ini": "1.3.5", + "is-windows": "1.0.2", + "which": "1.3.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", + "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", + "dev": true, + "requires": { + "array-union": "1.0.2", + "dir-glob": "2.0.0", + "fast-glob": "2.2.2", + "glob": "7.1.2", + "ignore": "3.3.8", + "pify": "3.0.0", + "slash": "1.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 + } + } + }, + "got": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.1.tgz", + "integrity": "sha512-tiLX+bnYm5A56T5N/n9Xo89vMaO1mrS9qoDqj3u/anVooqGozvY/HbXzEpDfbNeKsHCBpK40gSbz8wGYSp3i1w==", + "dev": true, + "requires": { + "@sindresorhus/is": "0.7.0", + "cacheable-request": "2.1.4", + "decompress-response": "3.3.0", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "into-stream": "3.1.0", + "is-retry-allowed": "1.1.0", + "isurl": "1.0.0", + "lowercase-keys": "1.0.1", + "mimic-response": "1.0.0", + "p-cancelable": "0.4.1", + "p-timeout": "2.0.1", + "pify": "3.0.0", + "safe-buffer": "5.1.2", + "timed-out": "4.0.1", + "url-parse-lax": "3.0.0", + "url-to-options": "1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "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=", + "dev": true + }, + "grouped-queue": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-0.3.3.tgz", + "integrity": "sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw=", + "dev": true, + "requires": { + "lodash": "4.17.10" + } + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "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" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "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 + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "1.4.2" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "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.1" + } + }, + "hdkey": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", + "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", + "requires": { + "coinstring": "2.3.0", + "secp256k1": "3.5.0" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "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=", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "homedir": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/homedir/-/homedir-0.6.0.tgz", + "integrity": "sha1-KyHbZr8Ipts4JJo+/1LX0YcGrx4=" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, + "requires": { + "parse-passwd": "1.0.0" + } + }, + "hosted-git-info": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==" + }, + "http-basic": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-7.0.0.tgz", + "integrity": "sha1-gvClBr6UJzLsje6+6A50bvVzbbo=", + "dev": true, + "requires": { + "@types/concat-stream": "1.6.0", + "@types/node": "9.6.21", + "caseless": "0.12.0", + "concat-stream": "1.6.2", + "http-response-object": "3.0.1", + "parse-cache-control": "1.0.1" + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "http-response-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.1.tgz", + "integrity": "sha512-6L0Fkd6TozA8kFSfh9Widst0wfza3U1Ex2RjJ6zNDK0vR1U1auUR6jY4Nn2Xl7CCy0ikFmxW1XcspVpb9RvwTg==", + "dev": true, + "requires": { + "@types/node": "9.6.21" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.2" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": "2.1.2" + } + }, + "ieee754": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", + "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", + "dev": true + }, + "ignore": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", + "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", + "dev": true + }, + "immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" + }, + "import-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", + "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "dev": true, + "requires": { + "pkg-dir": "2.0.0", + "resolve-cwd": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "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.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", + "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.1.0", + "chalk": "2.4.1", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.2.0", + "figures": "2.0.0", + "lodash": "4.17.10", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rxjs": "5.5.11", + "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=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "requires": { + "from2": "2.3.0", + "p-is-promise": "1.1.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "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=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "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.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-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-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "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=", + "dev": true, + "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=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "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-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", + "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "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-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "1.2.0" + }, + "dependencies": { + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + } + } + }, + "is-odd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "dev": true, + "requires": { + "is-number": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "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=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "1.0.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=", + "dev": true + }, + "is-scoped": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-scoped/-/is-scoped-1.0.0.tgz", + "integrity": "sha1-RJypgpnnEwOCViieyytUDcQ3yzA=", + "dev": true, + "requires": { + "scoped-regex": "1.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isbinaryfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "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.3", + "whatwg-fetch": "2.0.4" + } + }, + "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": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.11", + "js-yaml": "3.12.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.1", + "wordwrap": "1.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "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" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "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" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "istextorbinary": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", + "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", + "dev": true, + "requires": { + "binaryextensions": "2.1.1", + "editions": "1.3.4", + "textextensions": "2.2.0" + } + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "requires": { + "has-to-string-tag-x": "1.4.1", + "is-object": "1.0.1" + } + }, + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "dev": true, + "requires": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "dev": true + } + } + }, + "js-sha3": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", + "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "1.0.10", + "esprima": "4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jscodeshift": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.5.1.tgz", + "integrity": "sha512-sRMollbhbmSDrR79JMAnhEjyZJlQQVozeeY9A6/KNuV26DNcuB3mGSCWXp0hks9dcwRNOELbNOiwraZaXXRk5Q==", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "6.22.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-1": "6.24.1", + "babel-register": "6.26.0", + "babylon": "7.0.0-beta.47", + "colors": "1.3.0", + "flow-parser": "0.74.0", + "lodash": "4.17.10", + "micromatch": "2.3.11", + "neo-async": "2.5.1", + "node-dir": "0.1.8", + "nomnom": "1.8.1", + "recast": "0.15.0", + "temp": "0.8.3", + "write-file-atomic": "1.3.4" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "babylon": { + "version": "7.0.0-beta.47", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.47.tgz", + "integrity": "sha512-+rq2cr4GDhtToEzKFD6KZZMDBXhjFAr9JjPw9pAppZACeEWqNM294j+NdBzkSHYXwzzBmVjZ3nEVJlOhbR2gOQ==", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "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" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "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.4" + } + } + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "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=", + "dev": true, + "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=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keccak": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", + "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", + "requires": { + "bindings": "1.3.0", + "inherits": "2.0.3", + "nan": "2.10.0", + "safe-buffer": "5.1.2" + } + }, + "keccakjs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", + "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", + "requires": { + "browserify-sha3": "0.0.1", + "sha3": "1.2.2" + } + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "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" + } + }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true + }, + "level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" + }, + "level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "requires": { + "errno": "0.1.7" + } + }, + "level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "requires": { + "inherits": "2.0.3", + "level-errors": "1.0.5", + "readable-stream": "1.1.14", + "xtend": "4.0.1" + }, + "dependencies": { + "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" + } + } + } + }, + "level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "2.1.2" + }, + "dependencies": { + "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" + } + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "requires": { + "object-keys": "0.4.0" + } + } + } + }, + "levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "requires": { + "deferred-leveldown": "1.2.2", + "level-codec": "7.0.1", + "level-errors": "1.0.5", + "level-iterator-stream": "1.3.1", + "prr": "1.0.1", + "semver": "5.4.1", + "xtend": "4.0.1" + } + }, + "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" + } + }, + "listr": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.1.tgz", + "integrity": "sha512-MSMUUVN1f8aRnPi4034RkOqdiUlpYW+FqwFE3aL0uYNPRavkt2S2SsSpDDofn8BDpqv2RNnsdOcCHWsChcq77A==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "0.3.0", + "cli-truncate": "0.2.1", + "figures": "1.7.0", + "indent-string": "2.1.0", + "is-observable": "1.1.0", + "is-promise": "2.1.0", + "is-stream": "1.1.0", + "listr-silent-renderer": "1.1.1", + "listr-update-renderer": "0.4.0", + "listr-verbose-renderer": "0.4.1", + "log-symbols": "1.0.2", + "log-update": "1.0.2", + "ora": "0.2.3", + "p-map": "1.2.0", + "rxjs": "6.2.0", + "strip-ansi": "3.0.1" + }, + "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" + } + }, + "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" + } + }, + "rxjs": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.0.tgz", + "integrity": "sha512-qBzf5uu6eOKiCZuAE0SgZ0/Qp+l54oeVxFfC2t+mJ2SFI6IB8gmMdJHs5DUMu5kqifqcCtsKS2XHjhZu6RKvAw==", + "dev": true, + "requires": { + "tslib": "1.9.2" + } + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz", + "integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-truncate": "0.2.1", + "elegant-spinner": "1.0.1", + "figures": "1.7.0", + "indent-string": "3.2.0", + "log-symbols": "1.0.2", + "log-update": "1.0.2", + "strip-ansi": "3.0.1" + }, + "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" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "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" + } + } + } + }, + "listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "date-fns": "1.29.0", + "figures": "1.7.0" + }, + "dependencies": { + "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" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "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" + } + } + } + }, + "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=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "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.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + }, + "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=", + "dev": true + }, + "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._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "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.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "2.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "log-update": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "cli-cursor": "1.0.2" + }, + "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" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "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" + } + } + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "3.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 + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "mem-fs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz", + "integrity": "sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw=", + "dev": true, + "requires": { + "through2": "2.0.3", + "vinyl": "1.2.0", + "vinyl-file": "2.0.0" + } + }, + "mem-fs-editor": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-4.0.2.tgz", + "integrity": "sha512-QHvdXLLNmwJXxKdf7x27aNUren6IoPxwcM8Sfd+S6/ddQQMcYdEtVKsh6ilpqMrU18VQuKZEaH0aCGt3JDbA0g==", + "dev": true, + "requires": { + "commondir": "1.0.1", + "deep-extend": "0.5.1", + "ejs": "2.6.1", + "glob": "7.1.2", + "globby": "8.0.1", + "isbinaryfile": "3.0.2", + "mkdirp": "0.5.1", + "multimatch": "2.1.0", + "rimraf": "2.6.2", + "through2": "2.0.3", + "vinyl": "2.1.0" + }, + "dependencies": { + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vinyl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", + "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, + "requires": { + "clone": "2.1.1", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.1.2", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + } + } + }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "requires": { + "abstract-leveldown": "2.7.2", + "functional-red-black-tree": "1.0.1", + "immediate": "3.2.3", + "inherits": "2.0.3", + "ltgt": "2.2.1", + "safe-buffer": "5.1.2" + }, + "dependencies": { + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "requires": { + "xtend": "4.0.1" + } + } + } + }, + "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.7", + "readable-stream": "2.3.6" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, + "merge2": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", + "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", + "dev": true + }, + "merkle-patricia-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", + "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", + "requires": { + "async": "1.5.2", + "ethereumjs-util": "5.2.0", + "level-ws": "0.0.0", + "levelup": "1.3.9", + "memdown": "1.4.1", + "readable-stream": "2.3.6", + "rlp": "2.0.0", + "semaphore": "1.1.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "ethjs-util": "0.1.5", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2", + "secp256k1": "3.5.0" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "requires": { + "mime-db": "1.33.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mimic-response": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", + "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", + "dev": true + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "0.1.1" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "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=", + "dev": true + } + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "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" + } + }, + "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" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "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" + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + }, + "nanomatch": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "neo-async": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", + "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nice-try": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", + "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", + "dev": true + }, + "node-dir": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.8.tgz", + "integrity": "sha1-VfuN62mQcHB/tn+RpGDwRIKUx30=", + "dev": true + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.2.0", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "1.2.0", + "events": "1.1.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.6", + "stream-browserify": "2.0.1", + "stream-http": "2.8.3", + "string_decoder": "1.1.1", + "timers-browserify": "2.0.10", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.4", + "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": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + } + } + }, + "nomnom": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", + "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", + "dev": true, + "requires": { + "chalk": "0.4.0", + "underscore": "1.6.0" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.0.9" + } + }, + "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.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.3" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "requires": { + "prepend-http": "2.0.0", + "query-string": "5.1.1", + "sort-keys": "2.0.0" + } + }, + "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" + } + }, + "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=" + }, + "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=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "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 + } + } + }, + "ora": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", + "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-spinners": "0.1.2", + "object-assign": "4.1.1" + }, + "dependencies": { + "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" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "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" + } + } + } + }, + "original-require": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", + "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=", + "dev": true + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "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=", + "dev": true + }, + "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=", + "dev": true + }, + "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-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true + }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "1.0.0" + } + }, + "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-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, + "p-lazy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-lazy/-/p-lazy-1.0.0.tgz", + "integrity": "sha1-7FPIAvLuOsKPFmzILQsrAt4nqDU=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.3.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "requires": { + "p-finally": "1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "dev": true, + "requires": { + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.16" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "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=", + "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" + } + } + } + }, + "parse-headers": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", + "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", + "requires": { + "for-each": "0.3.3", + "trim": "0.0.1" + } + }, + "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" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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=", + "dev": true + }, + "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-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=" + }, + "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.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "requires": { + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" + } + }, + "pegjs": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", + "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "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" + } + }, + "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" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "prettier": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.13.4.tgz", + "integrity": "sha512-emsEZ2bAigL1lq6ssgkpPm1MIBqgeTvcp90NxOP5XDqprub/V/WS2Hfgih3mS7/1dqTUvhG+sxx1Dv8crnVexA==", + "dev": true + }, + "pretty-bytes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "promise": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.1.tgz", + "integrity": "sha1-5F1osAoXZHttpxG/he1u1HII9FA=", + "dev": true, + "requires": { + "asap": "2.0.6" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "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.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", + "randombytes": "2.0.6" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "0.2.0", + "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 + }, + "randomatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "dev": true, + "requires": { + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "2.0.6", + "safe-buffer": "5.1.2" + } + }, + "read-chunk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", + "integrity": "sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU=", + "dev": true, + "requires": { + "pify": "3.0.0", + "safe-buffer": "5.1.2" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "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.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.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.6", + "set-immediate-shim": "1.0.1" + } + }, + "recast": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.15.0.tgz", + "integrity": "sha512-47C2mIxQYvFICrTNuV4+xGgBa1nAoq42ANN5oDTSBIJ50NX7jcki7gAC6HWYptnQgHmqIRTHJq8OKdi3fwgyNQ==", + "dev": true, + "requires": { + "ast-types": "0.11.5", + "esprima": "4.0.0", + "private": "0.1.8", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.7.1" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "1.4.0", + "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=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "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=", + "dev": true + }, + "req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "dev": true, + "requires": { + "req-from": "2.0.0" + } + }, + "req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "dev": true, + "requires": { + "resolve-from": "3.0.0" + } + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + }, + "dependencies": { + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + } + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "dev": true, + "requires": { + "lodash": "4.17.10" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "dev": true, + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.4" + } + }, + "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=" + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "2.0.2", + "global-modules": "1.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "1.0.1" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "requires": { + "through": "2.3.8" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + } + }, + "rlp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", + "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=" + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rustbn.js": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.2.tgz", + "integrity": "sha512-bAkNqSHYdJdFsBC7Z11JgzYktL31HIpB2o70jZcGiL1U1TVtPyvaVhDrGWwS8uZtaqwW2k6NOPGZCqW/Dgh5Lg==" + }, + "rxjs": { + "version": "5.5.11", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", + "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scoped-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz", + "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", + "dev": true + }, + "scrypt": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", + "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", + "requires": { + "nan": "2.10.0" + } + }, + "scrypt.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", + "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", + "requires": { + "scrypt": "6.0.3", + "scryptsy": "1.2.1" + } + }, + "scryptsy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", + "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", + "requires": { + "pbkdf2": "3.0.16" + } + }, + "secp256k1": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", + "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", + "requires": { + "bindings": "1.3.0", + "bip66": "1.1.5", + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "drbg.js": "1.0.1", + "elliptic": "6.4.0", + "nan": "2.10.0", + "safe-buffer": "5.1.2" + } + }, + "semaphore": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", + "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "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=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "sha3": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", + "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", + "requires": { + "nan": "2.10.0" + } + }, + "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.1.0", + "rechoir": "0.6.2" + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "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=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "sol-digger": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/sol-digger/-/sol-digger-0.0.2.tgz", + "integrity": "sha1-QGxKnTHiaef4jrHC6hATGOXgkCU=", + "dev": true + }, + "sol-explore": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.2.tgz", + "integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI=", + "dev": true + }, + "solc": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", + "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", + "requires": { + "fs-extra": "0.30.0", + "memorystream": "0.3.1", + "require-from-string": "1.2.1", + "semver": "5.4.1", + "yargs": "4.8.1" + } + }, + "solidity-coverage": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.4.3.tgz", + "integrity": "sha512-ARsACPfgUgZahaHIiVmuYxkJczKXPDekdxdGMtq+78zCA62eCVpSzth1gyVkv+pVdQ5XOmQ/eRWLOFgNsfvxqA==", + "dev": true, + "requires": { + "death": "1.1.0", + "ethereumjs-testrpc-sc": "6.0.7", + "istanbul": "0.4.5", + "keccakjs": "0.2.1", + "req-cwd": "1.0.1", + "shelljs": "0.7.8", + "sol-explore": "1.6.2", + "solidity-parser-sc": "0.4.1", + "web3": "0.18.4" + }, + "dependencies": { + "req-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-1.0.1.tgz", + "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", + "dev": true, + "requires": { + "req-from": "1.0.1" + } + }, + "req-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-1.0.1.tgz", + "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", + "dev": true, + "requires": { + "resolve-from": "2.0.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + } + } + }, + "solidity-parser-antlr": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/solidity-parser-antlr/-/solidity-parser-antlr-0.2.11.tgz", + "integrity": "sha512-9Fnd58I0WTeRIqJQPNxnrO3699gkIiPBkN3MGdLN1WfNVbbbMIo9qTB1UdCYIU7OGx5xKUTUNH6tqudg4wFiUw==", + "dev": true + }, + "solidity-parser-sc": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/solidity-parser-sc/-/solidity-parser-sc-0.4.1.tgz", + "integrity": "sha512-51kDgZXLCfgOtmxrPPK1Jhgi257emdf8g9xBA7BA5TgFTM8tSEgRzvJGlGTPbI03txLETuSvNpPhy46c+srOyQ==", + "dev": true, + "requires": { + "mocha": "2.5.3", + "pegjs": "0.10.0", + "yargs": "4.8.1" + }, + "dependencies": { + "commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", + "dev": true + }, + "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" + } + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "dev": true + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "dev": true, + "requires": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + } + }, + "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": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", + "dev": true + } + } + }, + "solidity-sha3": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/solidity-sha3/-/solidity-sha3-0.4.1.tgz", + "integrity": "sha1-F1d+k/bP1YSJxOx/LaMEdTAynsE=", + "dev": true, + "requires": { + "babel-cli": "6.26.0", + "babel-preset-es2015": "6.24.1", + "babel-register": "6.26.0", + "left-pad": "1.3.0", + "web3": "0.16.0" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "dev": true + }, + "web3": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.16.0.tgz", + "integrity": "sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk=", + "dev": true, + "requires": { + "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "crypto-js": "3.1.8", + "utf8": "2.1.2", + "xmlhttprequest": "1.8.0" + } + } + } + }, + "solium": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/solium/-/solium-1.1.7.tgz", + "integrity": "sha512-yYbalsrzJCU+QJ0HZvxAT4IQIqI1e6KPW2vop0NaHwdijqhQC9fJkVioCrL18NbO2Z8rdcnx8Y0JpvYJWrIjRg==", + "dev": true, + "requires": { + "ajv": "5.5.2", + "chokidar": "1.7.0", + "colors": "1.3.0", + "commander": "2.9.0", + "js-string-escape": "1.0.1", + "lodash": "4.17.10", + "sol-digger": "0.0.2", + "sol-explore": "1.6.1", + "solium-plugin-security": "0.1.1", + "solparse": "2.2.5", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "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", + "fsevents": "1.2.4", + "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" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "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" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "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-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 + }, + "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" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "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.4" + } + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + } + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "sol-explore": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.1.tgz", + "integrity": "sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs=", + "dev": true + }, + "solparse": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/solparse/-/solparse-2.2.5.tgz", + "integrity": "sha512-t7tvtR6KU6QfPYLMv1nlCh9DA8HYIu5tbjHpKu0fhGFZ1NuSp0KKDHfFHv07g6v1xgcuUY3rVqNFjZt5b9+5qA==", + "dev": true, + "requires": { + "mocha": "4.1.0", + "pegjs": "0.10.0", + "yargs": "10.1.2" + } + }, + "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" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", + "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", + "dev": true, + "requires": { + "cliui": "4.1.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "8.1.0" + } + }, + "yargs-parser": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", + "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "solium-plugin-security": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/solium-plugin-security/-/solium-plugin-security-0.1.1.tgz", + "integrity": "sha512-kpLirBwIq4mhxk0Y/nn5cQ6qdJTI+U1LO3gpoNIcqNaW+sI058moXBe2UiHs+9wvF9IzYD49jcKhFTxcR9u9SQ==", + "dev": true + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "2.1.1", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "requires": { + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "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", + "safer-buffer": "2.1.2", + "tweetnacl": "0.14.5" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "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.6" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "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=", + "dev": true + }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "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.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.12.0", + "function-bind": "1.1.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", + "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", + "dev": true, + "requires": { + "first-chunk-stream": "2.0.0", + "strip-bom": "2.0.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true + }, + "sync-request": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.0.0.tgz", + "integrity": "sha512-jGNIAlCi9iU4X3Dm4oQnNQshDD3h0/1A7r79LyqjbjUnj69sX6mShAXlhRXgImsfVKtTcnra1jfzabdZvp+Lmw==", + "dev": true, + "requires": { + "http-response-object": "3.0.1", + "sync-rpc": "1.3.4", + "then-request": "6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.4.tgz", + "integrity": "sha512-Iug+t1ICVFenUcTnDu8WXFnT+k8IVoLKGh8VA3eXUtl2Rt9SjKX3YEv33OenABqpTPL9QEaHv1+CNn2LK8vMow==", + "dev": true, + "requires": { + "get-port": "3.2.0" + } + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "requires": { + "deep-equal": "1.0.1", + "defined": "1.0.0", + "for-each": "0.3.3", + "function-bind": "1.1.1", + "glob": "7.1.2", + "has": "1.0.3", + "inherits": "2.0.3", + "minimist": "1.2.0", + "object-inspect": "1.6.0", + "resolve": "1.7.1", + "resumer": "0.0.0", + "string.prototype.trim": "1.1.2", + "through": "2.3.8" + } + }, + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "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 + }, + "textextensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.2.0.tgz", + "integrity": "sha512-j5EMxnryTvKxwH2Cq+Pb43tsf6sdEgw6Pdwxk83mPaq0ToeFJt6WE4J3s5BqY7vmjlLgkgXvhtXUxo80FyBhCA==", + "dev": true + }, + "then-request": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.0.tgz", + "integrity": "sha512-xA+7uEMc+jsQIoyySJ93Ad08Kuqnik7u6jLS5hR91Z3smAoCfL3M8/MqMlobAa9gzBfO9pA88A/AntfepkkMJQ==", + "dev": true, + "requires": { + "@types/concat-stream": "1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "8.10.19", + "@types/qs": "6.5.1", + "caseless": "0.12.0", + "concat-stream": "1.6.2", + "form-data": "2.3.2", + "http-basic": "7.0.0", + "http-response-object": "3.0.1", + "promise": "8.0.1", + "qs": "6.5.2" + }, + "dependencies": { + "@types/node": { + "version": "8.10.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.19.tgz", + "integrity": "sha512-+PU57o6DtOSx0/algmxgCwWrmCiomwC/K+LPfXonT0tQMbNTjHEqVzwL9dFEhFoPmLFIiSWjRorLH6Z0hJMT+Q==", + "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": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.6", + "xtend": "4.0.1" + } + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "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=", + "dev": true + }, + "to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "1.4.1" + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "truffle": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.0.5.tgz", + "integrity": "sha512-Hyj4LFRdfgoeb1SVV17hLAlO/szCXuuWS3tq26N5BI+avcEYdZl4KhxKMVgf6O/HeEIEuDYCpfLOWplXMfjeHQ==", + "dev": true, + "requires": { + "mocha": "3.5.3", + "original-require": "1.0.1", + "solc": "0.4.18" + }, + "dependencies": { + "solc": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.18.tgz", + "integrity": "sha512-Kq+O3PNF9Pfq7fB+lDYAuoqRdghLmZyfngsg0h1Hj38NKAeVHeGPOGeZasn5KqdPeCzbMFvaGyTySxzGv6aXCg==", + "dev": true, + "requires": { + "fs-extra": "0.30.0", + "memorystream": "0.3.1", + "require-from-string": "1.2.1", + "semver": "5.4.1", + "yargs": "4.8.1" + } + } + } + }, + "truffle-hdwallet-provider": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider/-/truffle-hdwallet-provider-0.0.3.tgz", + "integrity": "sha1-Dh3gIQS3PTh14c9wkzBbTqii2EM=", + "requires": { + "bip39": "2.5.0", + "ethereumjs-wallet": "0.6.0", + "web3": "0.18.4", + "web3-provider-engine": "8.6.1" + } + }, + "truffle-privatekey-provider": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/truffle-privatekey-provider/-/truffle-privatekey-provider-0.0.6.tgz", + "integrity": "sha512-x4tsMeXolhae9mzIA5k9bbq4FdhzSI/UGyAKU/B9xepE0lMCfhpuQv8WM2xdLlqyDtiHouC8z5+rmSmcK8bGEQ==", + "requires": { + "ethereumjs-wallet": "0.6.0", + "web3": "0.20.6", + "web3-provider-engine": "8.6.1" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + }, + "web3": { + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.6.tgz", + "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", + "requires": { + "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "crypto-js": "3.1.8", + "utf8": "2.1.2", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" + } + } + } + }, + "tslib": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz", + "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==", + "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.2" + } + }, + "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 + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "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=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "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=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "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=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" + } + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, + "unorm": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", + "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "untildify": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz", + "integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==", + "dev": true + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "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-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "2.0.0" + } + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, + "use": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "utf8": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", + "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + }, + "v8-compile-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.0.tgz", + "integrity": "sha512-qNdTUMaCjPs4eEnM3W9H94R3sU70YCuT+/ST7nUf+id1bVOrdjrpUaeZLqPBPRph3hsgn4a4BvwpxhHZx+oSDg==", + "dev": true + }, + "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" + } + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "requires": { + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.4", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + } + } + }, + "vinyl-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", + "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0", + "strip-bom-stream": "2.0.0", + "vinyl": "1.2.0" + } + }, + "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" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "2.0.3", + "graceful-fs": "4.1.11", + "neo-async": "2.5.1" + } + }, + "web3": { + "version": "0.18.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", + "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", + "requires": { + "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "crypto-js": "3.1.8", + "utf8": "2.1.2", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" + } + }, + "web3-provider-engine": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-8.6.1.tgz", + "integrity": "sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs=", + "requires": { + "async": "2.6.1", + "clone": "2.1.1", + "ethereumjs-block": "1.7.1", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.2.0", + "ethereumjs-vm": "2.3.5", + "isomorphic-fetch": "2.2.1", + "request": "2.87.0", + "semaphore": "1.1.0", + "solc": "0.4.24", + "tape": "4.9.1", + "web3": "0.16.0", + "xhr": "2.5.0", + "xtend": "4.0.1" + }, + "dependencies": { + "bignumber.js": { + "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9" + }, + "ethereumjs-util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", + "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "requires": { + "bn.js": "4.11.8", + "create-hash": "1.2.0", + "ethjs-util": "0.1.5", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.2", + "secp256k1": "3.5.0" + } + }, + "web3": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.16.0.tgz", + "integrity": "sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk=", + "requires": { + "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "crypto-js": "3.1.8", + "utf8": "2.1.2", + "xmlhttprequest": "1.8.0" + } + } + } + }, + "webpack": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.7.0.tgz", + "integrity": "sha512-MjAA0ZqO1ba7ZQJRnoCdbM56mmFpipOPUv/vQpwwfSI42p5PVDdoiuK2AL2FwFUVgT859Jr43bFZXRg/LNsqvg==", + "dev": true, + "requires": { + "acorn": "5.6.2", + "acorn-dynamic-import": "2.0.2", + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "async": "2.6.1", + "enhanced-resolve": "3.4.1", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "0.2.17", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "3.2.3", + "tapable": "0.2.8", + "uglify-js": "2.8.29", + "watchpack": "1.6.0", + "webpack-sources": "1.1.0", + "yargs": "6.6.0" + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "webpack-addons": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/webpack-addons/-/webpack-addons-1.1.5.tgz", + "integrity": "sha512-MGO0nVniCLFAQz1qv22zM02QPjcpAoJdy7ED0i3Zy7SY1IecgXCm460ib7H/Wq7e9oL5VL6S2BxaObxwIcag0g==", + "dev": true, + "requires": { + "jscodeshift": "0.4.1" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "ast-types": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz", + "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "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" + } + }, + "jscodeshift": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.4.1.tgz", + "integrity": "sha512-iOX6If+hsw0q99V3n31t4f5VlD1TQZddH08xbT65ZqA7T4Vkx68emrDZMUOLVvCEAJ6NpAk7DECe3fjC/t52AQ==", + "dev": true, + "requires": { + "async": "1.5.2", + "babel-plugin-transform-flow-strip-types": "6.22.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-1": "6.24.1", + "babel-register": "6.26.0", + "babylon": "6.18.0", + "colors": "1.3.0", + "flow-parser": "0.74.0", + "lodash": "4.17.10", + "micromatch": "2.3.11", + "node-dir": "0.1.8", + "nomnom": "1.8.1", + "recast": "0.12.9", + "temp": "0.8.3", + "write-file-atomic": "1.3.4" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "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.4" + } + }, + "recast": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.12.9.tgz", + "integrity": "sha512-y7ANxCWmMW8xLOaiopiRDlyjQ9ajKRENBH+2wjntIbk3A6ZR1+BLQttkmSHMY7Arl+AAZFwJ10grg2T6f1WI8A==", + "dev": true, + "requires": { + "ast-types": "0.10.1", + "core-js": "2.5.7", + "esprima": "4.0.0", + "private": "0.1.8", + "source-map": "0.6.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.1.5.tgz", + "integrity": "sha512-CiWQR+1JS77rmyiO6y1q8Kt/O+e8nUUC9YfJ25JtSmzDwbqJV7vIsh3+QKRHVTbTCa0DaVh8iY1LBiagUIDB3g==", + "dev": true, + "requires": { + "chalk": "2.4.1", + "cross-spawn": "6.0.5", + "diff": "3.5.0", + "enhanced-resolve": "4.0.0", + "envinfo": "5.10.0", + "glob-all": "3.1.0", + "global-modules": "1.0.0", + "got": "8.3.1", + "import-local": "1.0.0", + "inquirer": "5.2.0", + "interpret": "1.1.0", + "jscodeshift": "0.5.1", + "listr": "0.14.1", + "loader-utils": "1.1.0", + "lodash": "4.17.10", + "log-symbols": "2.2.0", + "mkdirp": "0.5.1", + "p-each-series": "1.0.0", + "p-lazy": "1.0.0", + "prettier": "1.13.4", + "supports-color": "5.4.0", + "v8-compile-cache": "2.0.0", + "webpack-addons": "1.1.5", + "yargs": "11.1.0", + "yeoman-environment": "2.2.0", + "yeoman-generator": "2.0.5" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "enhanced-resolve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz", + "integrity": "sha512-jox/62b2GofV1qTUQTMPEJSDIGycS43evqYzD/KVtEb9OCoki9cnacUPxCrZa7JfPzZSYOCZhu9O9luaMxAX8g==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "tapable": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 + }, + "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.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "tapable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", + "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "dev": true + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "dev": true, + "requires": { + "cliui": "4.1.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "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=" + }, + "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=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "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=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "xhr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", + "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", + "requires": { + "global": "4.3.2", + "is-function": "1.0.1", + "parse-headers": "2.0.1", + "xtend": "4.0.1" + } + }, + "xhr2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", + "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "yeoman-environment": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.2.0.tgz", + "integrity": "sha512-gQ+hIW8QRlUo4jGBDCm++qg01SXaIVJ7VyLrtSwk2jQG4vtvluWpsGIl7V8DqT2jGiqukdec0uEyffVEyQgaZA==", + "dev": true, + "requires": { + "chalk": "2.4.1", + "cross-spawn": "6.0.5", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "globby": "8.0.1", + "grouped-queue": "0.3.3", + "inquirer": "5.2.0", + "is-scoped": "1.0.0", + "lodash": "4.17.10", + "log-symbols": "2.2.0", + "mem-fs": "1.1.3", + "strip-ansi": "4.0.0", + "text-table": "0.2.0", + "untildify": "3.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "yeoman-generator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz", + "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==", + "dev": true, + "requires": { + "async": "2.6.1", + "chalk": "2.4.1", + "cli-table": "0.3.1", + "cross-spawn": "6.0.5", + "dargs": "5.1.0", + "dateformat": "3.0.3", + "debug": "3.1.0", + "detect-conflict": "1.0.1", + "error": "7.0.2", + "find-up": "2.1.0", + "github-username": "4.1.0", + "istextorbinary": "2.2.1", + "lodash": "4.17.10", + "make-dir": "1.3.0", + "mem-fs-editor": "4.0.2", + "minimist": "1.2.0", + "pretty-bytes": "4.0.2", + "read-chunk": "2.1.0", + "read-pkg-up": "3.0.0", + "rimraf": "2.6.2", + "run-async": "2.3.0", + "shelljs": "0.8.2", + "text-table": "0.2.0", + "through2": "2.0.3", + "yeoman-environment": "2.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "4.0.0", + "pify": "3.0.0", + "strip-bom": "3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.2" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "4.0.0", + "normalize-package-data": "2.4.0", + "path-type": "3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "3.0.0" + } + }, + "shelljs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", + "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8954bfd --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "@aragon/apps-curation", + "version": "1.0.0", + "description": "Curation App for Aragon TCR", + "main": "index.js", + "scripts": { + "compile": "truffle compile", + "lint": "solium --dir ./contracts", + "test": "TRUFFLE_TEST=true npm run ganache-cli:test", + "test:gas": "GAS_REPORTER=true npm test", + "coverage": "SOLIDITY_COVERAGE=true npm run ganache-cli:test", + "truffle:dev": "node_modules/.bin/truffle dev", + "ganache-cli:test": "./node_modules/@aragon/test-helpers/ganache-cli.sh", + "prepublishOnly": "truffle compile --all" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/aragonlabs/curation.git" + }, + "author": "Aragon One AG", + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/aragonlabs/curation/issues" + }, + "homepage": "https://github.com/aragonlabs/curation#readme", + "devDependencies": { + "@aragon/apps-registry": "^1.0.0", + "@aragon/test-helpers": "^1.0.0", + "eth-gas-reporter": "^0.1.5", + "ganache-cli": "^6.1.0", + "solidity-coverage": "0.4.3", + "solidity-sha3": "^0.4.1", + "solium": "^1.0.4", + "truffle": "4.0.5", + "truffle-hdwallet-provider": "0.0.3" + }, + "dependencies": { + "@aragon/os": "^3.1.2" + } +} diff --git a/test/TestCuration.sol b/test/TestCuration.sol new file mode 100644 index 0000000..e12b1ca --- /dev/null +++ b/test/TestCuration.sol @@ -0,0 +1,19 @@ +pragma solidity 0.4.18; + +import "@aragon/apps-registry/contracts/RegistryApp.sol"; + +// You might think this file is a bit odd, but let me explain. +// We only use these contracts in our tests, which +// means Truffle will not compile them for us, because it is +// from an external dependency. +// +// We are now left with three options: +// - Copy/paste these contracts +// - Run the tests with `truffle compile --all` on +// - Or trick Truffle by claiming we use it in a Solidity test +// +// You know which one I went for. + +contract TestCuration { + // ... +} diff --git a/test/curation.js b/test/curation.js new file mode 100644 index 0000000..736bd31 --- /dev/null +++ b/test/curation.js @@ -0,0 +1,537 @@ +const { assertRevert } = require('@aragon/test-helpers/assertThrow') + +const getContract = name => artifacts.require(name) +const getEvent = (receipt, event, arg) => { return receipt.logs.filter(l => l.event == event)[0].args[arg] } +const pct16 = x => new web3.BigNumber(x).times(new web3.BigNumber(10).toPower(16)) + +contract('Curation', ([owner, applicant, challenger, voter, _]) => { + let curation, registry, staking, voting, MAX_UINT64 + const minDeposit = 100 + const applyStageLen = 1000 + const dispensationPct = pct16(60) + const WINNING_STAKE = 70 + const TOTAL_STAKE = 100 + const VOTER_WINNING_STAKE = 10 + + const zeroAddress = "0x0000000000000000000000000000000000000000" + const TIME_UNIT_BLOCKS = 0 + const TIME_UNIT_SECONDS = 1 + + context('Regular App', async () => { + const appLockId = 1 + const challengeLockId = 2 + const voteId = 1 + const data = "Test" + + beforeEach(async () => { + registry = await getContract('RegistryApp').new() + staking = await getContract('StakingMock').new() + voting = await getContract('VotingMock').new() + + curation = await getContract('CurationMock').new() + MAX_UINT64 = await curation.MAX_UINT64() + await curation.initialize(registry.address, staking.address, voting.address, minDeposit, applyStageLen, dispensationPct) + }) + + it('checks initial values are right', async () => { + assert.equal(await curation.registry(), registry.address, "Registry address should match") + assert.equal(await curation.staking(), staking.address, "Staking address should match") + assert.equal(await curation.voting(), voting.address, "Voting address should match") + assert.equal(await curation.minDeposit(), minDeposit, "minDeposit address should match") + assert.equal(await curation.applyStageLen(), applyStageLen, "applyStageLen address should match") + assert.equal((await curation.dispensationPct()).toString(), dispensationPct.toString(), "dispensationPct address should match") + }) + + it('fails on reinitialization', async () => { + return assertRevert(async () => { + await curation.initialize(registry.address, staking.address, voting.address, minDeposit, applyStageLen, dispensationPct) + }) + }) + + // ----------- Create applications -------------- + + it('creates new Application', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + const r = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r, "NewApplication", "applicationId") + const application = await curation.getApplication(applicationId) + assert.equal(application[0], applicant, "Applicant should match") + //assert.equal(application[1], , "Date should match") + assert.equal(application[2], false, "Registered bool should match") + assert.equal(application[3], web3.toHex(data), "Data should match") + assert.equal(application[4], minDeposit, "Amount should match") + assert.equal(application[5], appLockId, "LockId should match") + }) + + it('fails creating new Application with an already used lock', async () => { + const data1 = "Test 1" + const data2 = "Test 2" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + await curation.newApplication(data1, appLockId, { from: applicant }) + // repeat + return assertRevert(async () => { + await curation.newApplication(data2, appLockId, { from: applicant }) + }) + }) + + it('fails creating new Application with an ongoing application', async () => { + const lockId1 = 1 + const lockId2 = 2 + const data = "Test" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + await curation.newApplication(data, lockId1, { from: applicant }) + // repeat + return assertRevert(async () => { + await curation.newApplication(data, lockId2, { from: applicant }) + }) + }) + + it('fails creating new Application with an already registered data', async () => { + const lockId1 = 1 + const lockId2 = 2 + const data = "Test" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // register data - this won't happen with real app, as ACLs will be working! + await registry.add(data) + // create application + return assertRevert(async () => { + await curation.newApplication(data, lockId2, { from: applicant }) + }) + }) + + // ----------- Challenge applications -------------- + + const applyAndChallenge = async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const r1 = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r1, "NewApplication", "applicationId") + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + const r2 = await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) + const challengeId = getEvent(r2, "NewChallenge", "challengeId") + + return challengeId + } + + it('challenges application', async () => { + const challengeId = await applyAndChallenge() + // checks + const challenge = await curation.getChallenge(challengeId) + assert.equal(challenge[0], challenger, "Challenger should match") + //assert.equal(challenge[1], , "Date should match") + assert.equal(challenge[2], false, "Resolved bool should match") + assert.equal(challenge[3], minDeposit, "Amount should match") + assert.equal(challenge[4], challengeLockId, "LockId should match") + assert.equal(challenge[5], voteId, "Vote Id should match") + assert.equal(challenge[6].toString(), dispensationPct.toString(), "Dipsensation Pct should match") + }) + + it('challenges touch-and-remove application', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const r1 = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r1, "NewApplication", "applicationId") + + // increase minDeposit + await curation.setMinDeposit(minDeposit + 1) + + // mock lock + await staking.setLock(minDeposit + 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + // challenge + const r2 = await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) + const challenge = await curation.getChallenge(applicationId) + // no challenge has been created + assert.equal(challenge[0], zeroAddress, "Challenger should be zero") + assert.equal(challenge[1], 0, "Date should be zero") + assert.equal(challenge[2], false, "Resolved should be false") + assert.equal(challenge[3], 0, "Amount should be zero") + assert.equal(challenge[4], 0, "LockId should be zero") + assert.equal(challenge[5], 0, "Vote Id should be zero") + assert.equal(challenge[6], 0, "Dipsensation Pct should be zero") + }) + + it('fails challenging with an already used lock', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const r1 = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r1, "NewApplication", "applicationId") + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + return assertRevert(async () => { + // challenge + const r2 = await curation.challengeApplication(applicationId, appLockId) + }) + }) + + it('fails challenging an already challenged application', async () => { + const applicationId = await applyAndChallenge() + const newChallengeLockId = 3 + // repeat + return assertRevert(async () => { + await curation.challengeApplication(applicationId, newChallengeLockId, { from: challenger }) + }) + }) + + // ----------- Resolve challenges -------------- + + // checks if a log for moving tokens was generated with the given params + // if amount is 0, it will check for any + /* this doesn't work, only shows called contract logs + const checkMovedTokens = (receipt, from, to, amount) => { + const logs = receipt.logs.filter( + l => + l.event == 'MovedTokens' && + l.args['from'] == from && + l.args['to'] == to && + (l.args['amount'] == amount || amount == 0) + ) + return logs.length == 1 || (amount == 0 && logs.length >= 1) + } + */ + const checkMovedTokens = (receipt, from, to, amount) => { + const logs = receipt.receipt.logs.filter( + l => + l.topics[0] == web3.sha3('MovedTokens(address,address,uint256)') && + '0x' + l.topics[1].slice(26) == from && + '0x' + l.topics[2].slice(26) == to && + (web3.toDecimal(l.data) == amount || amount == 0) + ) + return logs.length == 1 || (amount == 0 && logs.length >= 1) + } + + const applyChallengeAndResolve = async (result) => { + const applicationId = await applyAndChallenge() + // mock vote result + await voting.setVoteClosed(voteId, true) + await voting.setVoteResult(voteId, result, WINNING_STAKE, TOTAL_STAKE) + // resolve + const receipt = await curation.resolveChallenge(applicationId) + + return { applicationId: applicationId, receipt: receipt } + } + + it('resolves challenge, rejected', async () => { + const {applicationId, receipt} = await applyChallengeAndResolve(false) + // checks + // registry + assert.isTrue(await registry.exists(applicationId), "Data should have been registered") + // application + const application = await curation.getApplication(applicationId) + assert.isTrue(application[2], "Registered should be true") + // challenge + const challenge = await curation.getChallenge(applicationId) + assert.isTrue(challenge[2], "Resolved should be true") + // redistribution + const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) + assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) + assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) + // used locks + const appUsedLock = await curation.getUsedLock(appLockId) + const challengeUsedLock = await curation.getUsedLock(challengeLockId) + assert.isFalse(appUsedLock) + assert.isTrue(challengeUsedLock) + }) + + it('resolves challenge, accepted', async () => { + const {applicationId, receipt} = await applyChallengeAndResolve(true) + + // checks + // registry + assert.isFalse(await registry.exists(data), "Data should not have been registered") + // application + const application = await curation.getApplication(applicationId) + assert.isFalse(application[2], "Registered should be false") + // challenge + const challenge = await curation.getChallenge(applicationId) + assert.isTrue(challenge[2], "Resolved should be true") + // redistribution + const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) + assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) + assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) + // used locks + const appUsedLock = await curation.getUsedLock(appLockId) + const challengeUsedLock = await curation.getUsedLock(challengeLockId) + assert.isTrue(appUsedLock) + assert.isFalse(challengeUsedLock) + }) + + it('fails resolving challenge if vote has not ended', async () => { + const appLockId = 1 + const challengeLockId = 2 + const voteId = 1 + const data = "Test" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const r1 = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r1, "NewApplication", "applicationId") + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) + // mock vote result + await voting.setVoteClosed(voteId, false) + // resolve + return assertRevert(async () => { + await curation.resolveChallenge(applicationId) + }) + }) + + // ----------- Claim rewards -------------- + + it('claims reward as voter in the winning party', async () => { + const {applicationId} = await applyChallengeAndResolve(true) + await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) + const receipt = await curation.claimReward(applicationId, { from: voter }) + const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) + assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") + }) + + it('fails claiming reward if not voter in the winning party', async () => { + const {applicationId} = await applyChallengeAndResolve(true) + await voting.setVoterWinningStake(voter, 0) + return assertRevert(async () => { + await curation.claimReward(applicationId, { from: voter }) + }) + + }) + + it('claims reward and lock can be released, challenge rejected', async () => { + const {applicationId} = await applyChallengeAndResolve(false) + await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) + // mock Staking to pretend losing party tokens were already distributed + await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + // claim reward + const receipt = await curation.claimReward(applicationId, { from: voter }) + const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) + assert.isTrue(checkMovedTokens(receipt, challenger, voter, reward), "Reward should be payed") + const appUsedLock = await curation.getUsedLock(appLockId) + const challengeUsedLock = await curation.getUsedLock(challengeLockId) + assert.isFalse(appUsedLock) + assert.isFalse(challengeUsedLock) + }) + + it('claims reward and lock can be released, challenge accepted', async () => { + const {applicationId} = await applyChallengeAndResolve(true) + await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) + // mock Staking to pretend losing party tokens were already distributed + await staking.setLock(0, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // claim reward + const receipt = await curation.claimReward(applicationId, { from: voter }) + const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) + assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") + const application = await curation.getApplication(applicationId) + assert.equal(application[0], zeroAddress, "Application should be empty") + const appUsedLock = await curation.getUsedLock(appLockId) + const challengeUsedLock = await curation.getUsedLock(challengeLockId) + assert.isFalse(appUsedLock) + assert.isFalse(challengeUsedLock) + }) + + it('fails claiming reward if challenge is not resolved', async () => { + const applicationId = await applyAndChallenge() + return assertRevert(async () => { + await curation.claimReward(applicationId, { from: challenger }) + }) + }) + + it('fails claiming a reward twice', async () => { + const {applicationId} = await applyChallengeAndResolve(true) + await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) + await curation.claimReward(applicationId, { from: voter }) + return assertRevert(async () => { + await curation.claimReward(applicationId, { from: voter }) + }) + }) + + // ----------- Register applications -------------- + + it('registers application after stage period with no challenge', async () => { + const appLockId = 1 + const data = "Test" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + const r = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r, "NewApplication", "applicationId") + + // time travel + await curation.addTime(applyStageLen + 1) + + // register + await curation.registerApplication(applicationId) + + // checks + // registry + assert.isTrue(await registry.exists(applicationId), "Data should have been registered") + // application + const application = await curation.getApplication(applicationId) + assert.isTrue(application[2], "Registered should be true") + }) + + it('fails registering an application if time has not gone by', async () => { + const appLockId = 1 + const data = "Test" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + const r = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r, "NewApplication", "applicationId") + + // make sure time has not gone by + const application = await curation.getApplication(applicationId) + await curation.setTimestamp(application[1]) + + // register + return assertRevert(async () => { + await curation.registerApplication(applicationId) + }) + }) + + it('fails registering an application if it has a challenge', async () => { + const appLockId = 1 + const data = "Test" + const challengeLockId = 2 + const voteId = 1 + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + const r = await curation.newApplication(data, appLockId, { from: applicant }) + const applicationId = getEvent(r, "NewApplication", "applicationId") + + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + const r2 = await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) + + // time travel + await curation.addTime(applyStageLen + 1) + + // register + return assertRevert(async () => { + await curation.registerApplication(applicationId) + }) + }) + + // ----------- Modify parameters -------------- + + it('changes voting app', async () => { + const newVoting = await getContract('VotingMock').new() + await curation.setVotingApp(newVoting.address) + assert.equal(await curation.voting(), newVoting.address, "Voting app should match") + }) + + it('fails changing voting app if it is not a contract', async () => { + return assertRevert(async () => { + await curation.setVotingApp(applicant) + }) + }) + + it('changes min deposit', async () => { + const newMinDeposit = minDeposit + 1 + await curation.setMinDeposit(newMinDeposit) + assert.equal(await curation.minDeposit(), newMinDeposit, "MinDeposit should match") + }) + + it('changes apply stage len', async () => { + const newApplyStageLen = applyStageLen + 1 + await curation.setApplyStageLen(newApplyStageLen) + assert.equal(await curation.applyStageLen(), newApplyStageLen, "ApplyStageLen should match") + }) + + it('changes dispensation pct', async () => { + const newDispensationPct = dispensationPct.plus(1) + await curation.setDispensationPct(newDispensationPct) + assert.equal((await curation.dispensationPct()).toString(), newDispensationPct.toString(), "DispensationPct should match") + }) + + it('fails changing dispensation pct if is more 100%', async () => { + const newDispensationPct = pct16(100) + 1 + return assertRevert(async () => { + await curation.setDispensationPct(newDispensationPct) + }) + }) + }) + + context('Without init', async () => { + beforeEach(async () => { + registry = await getContract('RegistryApp').new() + staking = await getContract('StakingMock').new() + voting = await getContract('VotingMock').new() + + curation = await getContract('Curation').new() + }) + + it('fails creating new application', async () => { + const lockId = 1 + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + return assertRevert(async () => { + await curation.newApplication("test", lockId) + }) + }) + + it('fails challenging', async () => { + const applicationId = 1 + const lockId = 1 + return assertRevert(async () => { + await curation.challengeApplication(applicationId, lockId) + }) + }) + + it('fails resolving a challenge', async () => { + return assertRevert(async () => { + const challengeId = 1 + await curation.resolveChallenge(challengeId) + }) + }) + + it('fails registering an application', async () => { + return assertRevert(async () => { + const applicationId = 1 + await curation.registerApplication(applicationId) + }) + }) + + it('fails claiming reward', async () => { + return assertRevert(async () => { + const challengeId = 1 + await curation.claimReward(challengeId) + }) + }) + + it('fails trying to init with empty registry', async () => { + return assertRevert(async () => { + await curation.initialize("0x0", staking.address, voting.address, minDeposit, applyStageLen, dispensationPct) + }) + }) + + it('fails trying to init with empty staking', async () => { + return assertRevert(async () => { + await curation.initialize(registry.address, "0x0", voting.address, minDeposit, applyStageLen, dispensationPct) + }) + }) + + it('fails trying to init with empty voting', async () => { + return assertRevert(async () => { + await curation.initialize(registry.address, staking.address, "0x0", minDeposit, applyStageLen, dispensationPct) + }) + }) + }) +}) diff --git a/test/mocks/CurationMock.sol b/test/mocks/CurationMock.sol new file mode 100644 index 0000000..d9b3b34 --- /dev/null +++ b/test/mocks/CurationMock.sol @@ -0,0 +1,28 @@ +pragma solidity 0.4.18; + +import "../../contracts/Curation.sol"; + + +contract CurationMock is Curation { + uint256 _mockTime = now; + + function getTimestampExt() external view returns (uint256) { + return getTimestamp(); + } + + function setTimestamp(uint i) public { + _mockTime = i; + } + + function addTime(uint i) public { + _mockTime += i; + } + + function getTimestamp() internal view returns (uint256) { + return _mockTime; + } + + function getUsedLock(uint256 lockId) view public returns (bool) { + return usedLocks[lockId]; + } +} diff --git a/test/mocks/StakingMock.sol b/test/mocks/StakingMock.sol new file mode 100644 index 0000000..87eced4 --- /dev/null +++ b/test/mocks/StakingMock.sol @@ -0,0 +1,35 @@ +pragma solidity 0.4.18; + +import "../../contracts/interfaces/IStaking.sol"; + + +contract StakingMock is IStaking { + uint256 amount; + uint8 lockUnit; + uint64 lockEnds; + address unlocker; + bytes32 metadata; + + event MovedTokens(address indexed from, address indexed to, uint256 amount); + + function setLock(uint256 _amount, uint8 _lockUnit, uint64 _lockEnds, address _unlocker, bytes32 _metadata) public { + amount = _amount; + lockUnit = _lockUnit; + lockEnds = _lockEnds; + unlocker = _unlocker; + } + + function unlock(address acct, uint256 lockId) public { + // do nothing + } + + function moveTokens(address from, address to, uint256 amount) external { + MovedTokens(from, to, amount); + } + + function getLock(address acct, uint256 lockId) public view returns (uint256, uint8, uint64, address, bytes32) { + return (amount, lockUnit, lockEnds, unlocker, metadata); + } + + +} diff --git a/test/mocks/VotingMock.sol b/test/mocks/VotingMock.sol new file mode 100644 index 0000000..5e35d2c --- /dev/null +++ b/test/mocks/VotingMock.sol @@ -0,0 +1,53 @@ +pragma solidity 0.4.18; + +import "../../contracts/interfaces/IVoting.sol"; + + +contract VotingMock is IVoting { + uint256 voteId; + struct Vote { + bool result; + uint256 winningStake; + uint256 totalStake; + } + mapping(uint256 => Vote) results; + mapping(uint256 => bool) closed; // TODO + mapping(address => uint256) voterWinningStake; + + function newVote(bytes _executionScript, string _metadata) external returns (uint256) { + return voteId; + } + + function setVoteClosed(uint256 _voteId, bool _closed) public { + closed[_voteId] = _closed; + } + + function setVoteId(uint256 _voteId) public { + voteId = _voteId; + } + + function setVoteResult(uint256 _voteId, bool _result, uint256 _winningStake, uint256 _totalStake) public { + results[_voteId] = Vote(_result, _winningStake, _totalStake); + } + + function setVoterWinningStake(address _voter, uint256 _stake) { + voterWinningStake[_voter] = _stake; + } + + // TODO: canExecute or isClosed?? + function isClosed(uint256 _voteId) view public returns (bool) { + return closed[_voteId]; + } + + function getVoteResult(uint256 _voteId) view public returns (bool _result, uint256 _winningStake, uint256 _totalStake) { + return (results[_voteId].result, results[_voteId].winningStake, results[_voteId].totalStake); + } + + function getVoterWinningStake(uint256 _voteId, address _voter) view public returns (uint256) { + if (!isClosed(_voteId)) { + return 0; + } + + return voterWinningStake[_voter]; + } +} diff --git a/truffle.js b/truffle.js new file mode 100644 index 0000000..466a16a --- /dev/null +++ b/truffle.js @@ -0,0 +1 @@ +module.exports = require("@aragon/os/truffle-config") From 8458619ee6813e2541f085450fb889ed89615aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Thu, 14 Jun 2018 18:32:53 +0200 Subject: [PATCH 02/22] Unify ids As there can only be one application per registry entry, and only one challenge per application/entry, we can use the same id for all of them. --- contracts/Curation.sol | 83 ++++++++++++++-------------- test/curation.js | 121 +++++++++++++++++++++-------------------- 2 files changed, 103 insertions(+), 101 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 2c45d55..bd6389a 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -58,9 +58,9 @@ contract Curation is AragonApp { mapping(bytes32 => Challenge) challenges; mapping(uint256 => bool) usedLocks; - event NewApplication(bytes32 applicationId, address applicant); - event NewChallenge(bytes32 applicationId, bytes32 challengeId, address challenger); - event ResolvedChallenge(bytes32 applicationId, bytes32 challengeId, bool result); + event NewApplication(bytes32 entryId, address applicant); + event NewChallenge(bytes32 entryId, address challenger); + event ResolvedChallenge(bytes32 entryId, bool result); /** * @notice Initializes Curation app with @@ -91,19 +91,19 @@ contract Curation is AragonApp { _setDispensationPct(_dispensationPct); } - function newApplication(bytes data, uint256 lockId) isInitialized public returns (bytes32 applicationId) { - applicationId = keccak256(data); + function newApplication(bytes data, uint256 lockId) isInitialized public returns (bytes32 entryId) { + entryId = keccak256(data); require(data.length != 0); // check data doesn't have an ongoing application - require(!applicationExists(applicationId)); + require(!applicationExists(entryId)); // check data doesn't exist in Registry - require(!registry.exists(applicationId)); + require(!registry.exists(entryId)); // check locked tokens uint256 amount = _checkLock(lockId, MAX_UINT64); - applications[applicationId] = Application({ + applications[entryId] = Application({ applicant: msg.sender, date: uint64(getTimestamp()), registered: false, @@ -113,19 +113,19 @@ contract Curation is AragonApp { }); // register used lock - NewApplication(applicationId, msg.sender); + NewApplication(entryId, msg.sender); } - function challengeApplication(bytes32 applicationId, uint256 lockId) isInitialized public returns(bytes32) { + function challengeApplication(bytes32 entryId, uint256 lockId) isInitialized public returns(bytes32) { // check application doesn't have an ongoing challenge - require(!challengeExists(applicationId)); + require(!challengeExists(entryId)); // check locked tokens uint256 amount = _checkLock(lockId, uint64(getTimestamp()).add(applyStageLen)); // touch-and-remove case - Application memory application = applications[applicationId]; + Application memory application = applications[entryId]; if (application.amount < minDeposit) { - registry.remove(applicationId); + registry.remove(entryId); staking.unlock(application.applicant, application.lockId); staking.unlock(msg.sender, lockId); return 0; @@ -136,7 +136,7 @@ contract Curation is AragonApp { // TODO: metadata uint256 voteId = voting.newVote("", ""); - challenges[applicationId] = Challenge({ + challenges[entryId] = Challenge({ challenger: msg.sender, date: uint64(getTimestamp()), resolved: false, @@ -147,14 +147,14 @@ contract Curation is AragonApp { }); // TODO: ids? - NewChallenge(applicationId, applicationId, msg.sender); + NewChallenge(entryId, msg.sender); - return applicationId; + return entryId; } - function resolveChallenge(bytes32 challengeId) isInitialized public { - Challenge storage challenge = challenges[challengeId]; - Application storage application = applications[challengeId]; + function resolveChallenge(bytes32 entryId) isInitialized public { + Challenge storage challenge = challenges[entryId]; + Application storage application = applications[entryId]; require(!challenge.resolved); // TODO: canExecute?? @@ -182,7 +182,7 @@ contract Curation is AragonApp { // it has been already registered if (application.registered) { // remove from Registry app - registry.remove(challengeId); + registry.remove(entryId); } // Remove challenger used lock delete(usedLocks[challenge.lockId]); @@ -194,13 +194,14 @@ contract Curation is AragonApp { } challenge.resolved = true; + ResolvedChallenge(entryId, voteResult); } - function claimReward(bytes32 challengeId) isInitialized public { - require(isChallengeResolved(challengeId)); + function claimReward(bytes32 entryId) isInitialized public { + require(isChallengeResolved(entryId)); - Challenge storage challenge = challenges[challengeId]; - Application memory application = applications[challengeId]; + Challenge storage challenge = challenges[entryId]; + Application memory application = applications[entryId]; // avoid claiming twice require(!challenge.claims[msg.sender]); @@ -235,7 +236,7 @@ contract Curation is AragonApp { delete(usedLocks[loserLockId]); // Remove application, if it lost, as redistribution is done if (voteResult == true) { - delete(applications[challengeId]); + delete(applications[entryId]); } } @@ -243,10 +244,10 @@ contract Curation is AragonApp { challenge.claims[msg.sender] = true; } - function registerApplication(bytes32 applicationId) isInitialized public { - require(canBeRegistered(applicationId)); + function registerApplication(bytes32 entryId) isInitialized public { + require(canBeRegistered(entryId)); - Application storage application = applications[applicationId]; + Application storage application = applications[entryId]; require(!application.registered); // insert in Registry app @@ -272,22 +273,22 @@ contract Curation is AragonApp { _setDispensationPct(_dispensationPct); } - function canBeRegistered(bytes32 applicationId) view public returns (bool) { + function canBeRegistered(bytes32 entryId) view public returns (bool) { // no challenges - if (uint64(getTimestamp()) > applications[applicationId].date.add(applyStageLen) - && challenges[applicationId].challenger == address(0) ) { + if (uint64(getTimestamp()) > applications[entryId].date.add(applyStageLen) + && challenges[entryId].challenger == address(0) ) { return true; } return false; } - function isChallengeResolved(bytes32 challengeId) view public returns (bool) { - return challenges[challengeId].resolved; + function isChallengeResolved(bytes32 entryId) view public returns (bool) { + return challenges[entryId].resolved; } function getApplication( - bytes32 applicationId + bytes32 entryId ) view external @@ -300,7 +301,7 @@ contract Curation is AragonApp { uint256 lockId ) { - Application memory application = applications[applicationId]; + Application memory application = applications[entryId]; return ( application.applicant, application.date, @@ -312,7 +313,7 @@ contract Curation is AragonApp { } function getChallenge( - bytes32 challengeId + bytes32 entryId ) view external @@ -326,7 +327,7 @@ contract Curation is AragonApp { uint256 dipsensationPct ) { - Challenge memory challenge = challenges[challengeId]; + Challenge memory challenge = challenges[entryId]; return ( challenge.challenger, challenge.date, @@ -379,12 +380,12 @@ contract Curation is AragonApp { dispensationPct = _dispensationPct; } - function applicationExists(bytes32 applicationId) view internal returns (bool) { - return applications[applicationId].data.length > 0; + function applicationExists(bytes32 entryId) view internal returns (bool) { + return applications[entryId].data.length > 0; } - function challengeExists(bytes32 challengeId) view internal returns (bool) { - return challenges[challengeId].challenger != address(0); + function challengeExists(bytes32 entryId) view internal returns (bool) { + return challenges[entryId].challenger != address(0); } function getTimestamp() view internal returns (uint256) { diff --git a/test/curation.js b/test/curation.js index 736bd31..b1c723e 100644 --- a/test/curation.js +++ b/test/curation.js @@ -55,8 +55,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r, "NewApplication", "applicationId") - const application = await curation.getApplication(applicationId) + const entryId = getEvent(r, "NewApplication", "entryId") + const application = await curation.getApplication(entryId) assert.equal(application[0], applicant, "Applicant should match") //assert.equal(application[1], , "Date should match") assert.equal(application[2], false, "Registered bool should match") @@ -112,22 +112,23 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r1, "NewApplication", "applicationId") + const entryId = getEvent(r1, "NewApplication", "entryId") // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge - const r2 = await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) - const challengeId = getEvent(r2, "NewChallenge", "challengeId") + const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + const challengeId = getEvent(r2, "NewChallenge", "entryId") + assert.equal(challengeId, entryId, "A NewChallenge event for the same entryId should have been generated") - return challengeId + return entryId } it('challenges application', async () => { - const challengeId = await applyAndChallenge() + const entryId = await applyAndChallenge() // checks - const challenge = await curation.getChallenge(challengeId) + const challenge = await curation.getChallenge(entryId) assert.equal(challenge[0], challenger, "Challenger should match") //assert.equal(challenge[1], , "Date should match") assert.equal(challenge[2], false, "Resolved bool should match") @@ -141,7 +142,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r1, "NewApplication", "applicationId") + const entryId = getEvent(r1, "NewApplication", "entryId") // increase minDeposit await curation.setMinDeposit(minDeposit + 1) @@ -149,8 +150,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock lock await staking.setLock(minDeposit + 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") // challenge - const r2 = await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) - const challenge = await curation.getChallenge(applicationId) + const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + const challenge = await curation.getChallenge(entryId) // no challenge has been created assert.equal(challenge[0], zeroAddress, "Challenger should be zero") assert.equal(challenge[1], 0, "Date should be zero") @@ -165,23 +166,23 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r1, "NewApplication", "applicationId") + const entryId = getEvent(r1, "NewApplication", "entryId") // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // mock vote Id await voting.setVoteId(voteId) return assertRevert(async () => { // challenge - const r2 = await curation.challengeApplication(applicationId, appLockId) + const r2 = await curation.challengeApplication(entryId, appLockId) }) }) it('fails challenging an already challenged application', async () => { - const applicationId = await applyAndChallenge() + const entryId = await applyAndChallenge() const newChallengeLockId = 3 // repeat return assertRevert(async () => { - await curation.challengeApplication(applicationId, newChallengeLockId, { from: challenger }) + await curation.challengeApplication(entryId, newChallengeLockId, { from: challenger }) }) }) @@ -213,26 +214,26 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { } const applyChallengeAndResolve = async (result) => { - const applicationId = await applyAndChallenge() + const entryId = await applyAndChallenge() // mock vote result await voting.setVoteClosed(voteId, true) await voting.setVoteResult(voteId, result, WINNING_STAKE, TOTAL_STAKE) // resolve - const receipt = await curation.resolveChallenge(applicationId) + const receipt = await curation.resolveChallenge(entryId) - return { applicationId: applicationId, receipt: receipt } + return { entryId: entryId, receipt: receipt } } it('resolves challenge, rejected', async () => { - const {applicationId, receipt} = await applyChallengeAndResolve(false) + const {entryId, receipt} = await applyChallengeAndResolve(false) // checks // registry - assert.isTrue(await registry.exists(applicationId), "Data should have been registered") + assert.isTrue(await registry.exists(entryId), "Data should have been registered") // application - const application = await curation.getApplication(applicationId) + const application = await curation.getApplication(entryId) assert.isTrue(application[2], "Registered should be true") // challenge - const challenge = await curation.getChallenge(applicationId) + const challenge = await curation.getChallenge(entryId) assert.isTrue(challenge[2], "Resolved should be true") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) @@ -246,16 +247,16 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('resolves challenge, accepted', async () => { - const {applicationId, receipt} = await applyChallengeAndResolve(true) + const {entryId, receipt} = await applyChallengeAndResolve(true) // checks // registry assert.isFalse(await registry.exists(data), "Data should not have been registered") // application - const application = await curation.getApplication(applicationId) + const application = await curation.getApplication(entryId) assert.isFalse(application[2], "Registered should be false") // challenge - const challenge = await curation.getChallenge(applicationId) + const challenge = await curation.getChallenge(entryId) assert.isTrue(challenge[2], "Resolved should be true") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) @@ -276,47 +277,47 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r1, "NewApplication", "applicationId") + const entryId = getEvent(r1, "NewApplication", "entryId") // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge - await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) // mock vote result await voting.setVoteClosed(voteId, false) // resolve return assertRevert(async () => { - await curation.resolveChallenge(applicationId) + await curation.resolveChallenge(entryId) }) }) // ----------- Claim rewards -------------- it('claims reward as voter in the winning party', async () => { - const {applicationId} = await applyChallengeAndResolve(true) + const {entryId} = await applyChallengeAndResolve(true) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) - const receipt = await curation.claimReward(applicationId, { from: voter }) + const receipt = await curation.claimReward(entryId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") }) it('fails claiming reward if not voter in the winning party', async () => { - const {applicationId} = await applyChallengeAndResolve(true) + const {entryId} = await applyChallengeAndResolve(true) await voting.setVoterWinningStake(voter, 0) return assertRevert(async () => { - await curation.claimReward(applicationId, { from: voter }) + await curation.claimReward(entryId, { from: voter }) }) }) it('claims reward and lock can be released, challenge rejected', async () => { - const {applicationId} = await applyChallengeAndResolve(false) + const {entryId} = await applyChallengeAndResolve(false) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) // mock Staking to pretend losing party tokens were already distributed await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") // claim reward - const receipt = await curation.claimReward(applicationId, { from: voter }) + const receipt = await curation.claimReward(entryId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) assert.isTrue(checkMovedTokens(receipt, challenger, voter, reward), "Reward should be payed") const appUsedLock = await curation.getUsedLock(appLockId) @@ -326,15 +327,15 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('claims reward and lock can be released, challenge accepted', async () => { - const {applicationId} = await applyChallengeAndResolve(true) + const {entryId} = await applyChallengeAndResolve(true) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) // mock Staking to pretend losing party tokens were already distributed await staking.setLock(0, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // claim reward - const receipt = await curation.claimReward(applicationId, { from: voter }) + const receipt = await curation.claimReward(entryId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") - const application = await curation.getApplication(applicationId) + const application = await curation.getApplication(entryId) assert.equal(application[0], zeroAddress, "Application should be empty") const appUsedLock = await curation.getUsedLock(appLockId) const challengeUsedLock = await curation.getUsedLock(challengeLockId) @@ -343,18 +344,18 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('fails claiming reward if challenge is not resolved', async () => { - const applicationId = await applyAndChallenge() + const entryId = await applyAndChallenge() return assertRevert(async () => { - await curation.claimReward(applicationId, { from: challenger }) + await curation.claimReward(entryId, { from: challenger }) }) }) it('fails claiming a reward twice', async () => { - const {applicationId} = await applyChallengeAndResolve(true) + const {entryId} = await applyChallengeAndResolve(true) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) - await curation.claimReward(applicationId, { from: voter }) + await curation.claimReward(entryId, { from: voter }) return assertRevert(async () => { - await curation.claimReward(applicationId, { from: voter }) + await curation.claimReward(entryId, { from: voter }) }) }) @@ -367,19 +368,19 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r, "NewApplication", "applicationId") + const entryId = getEvent(r, "NewApplication", "entryId") // time travel await curation.addTime(applyStageLen + 1) // register - await curation.registerApplication(applicationId) + await curation.registerApplication(entryId) // checks // registry - assert.isTrue(await registry.exists(applicationId), "Data should have been registered") + assert.isTrue(await registry.exists(entryId), "Data should have been registered") // application - const application = await curation.getApplication(applicationId) + const application = await curation.getApplication(entryId) assert.isTrue(application[2], "Registered should be true") }) @@ -390,15 +391,15 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r, "NewApplication", "applicationId") + const entryId = getEvent(r, "NewApplication", "entryId") // make sure time has not gone by - const application = await curation.getApplication(applicationId) + const application = await curation.getApplication(entryId) await curation.setTimestamp(application[1]) // register return assertRevert(async () => { - await curation.registerApplication(applicationId) + await curation.registerApplication(entryId) }) }) @@ -411,21 +412,21 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) - const applicationId = getEvent(r, "NewApplication", "applicationId") + const entryId = getEvent(r, "NewApplication", "entryId") // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge - const r2 = await curation.challengeApplication(applicationId, challengeLockId, { from: challenger }) + const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) // time travel await curation.addTime(applyStageLen + 1) // register return assertRevert(async () => { - await curation.registerApplication(applicationId) + await curation.registerApplication(entryId) }) }) @@ -488,31 +489,31 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('fails challenging', async () => { - const applicationId = 1 + const entryId = 1 const lockId = 1 return assertRevert(async () => { - await curation.challengeApplication(applicationId, lockId) + await curation.challengeApplication(entryId, lockId) }) }) it('fails resolving a challenge', async () => { return assertRevert(async () => { - const challengeId = 1 - await curation.resolveChallenge(challengeId) + const entryId = 1 + await curation.resolveChallenge(entryId) }) }) it('fails registering an application', async () => { return assertRevert(async () => { - const applicationId = 1 - await curation.registerApplication(applicationId) + const entryId = 1 + await curation.registerApplication(entryId) }) }) it('fails claiming reward', async () => { return assertRevert(async () => { - const challengeId = 1 - await curation.claimReward(challengeId) + const entryId = 1 + await curation.claimReward(entryId) }) }) From 0e4ff98a02388acd7b3442c6ceae337796f86f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Thu, 14 Jun 2018 20:45:14 +0200 Subject: [PATCH 03/22] Fix coverage --- contracts/Curation.sol | 6 +- test/curation.js | 156 ++++++++++++++++++++++++++++++++++------- 2 files changed, 134 insertions(+), 28 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index bd6389a..12bc0d4 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -177,12 +177,12 @@ contract Curation is AragonApp { staking.unlock(challenge.challenger, challenge.lockId); // Redistribute tokens staking.moveTokens(challenge.challenger, application.applicant, challenge.amount.mul(dispensationPct) / PCT_BASE); - // TODO: unlock?!! } else { // challenge accepted (application rejected) // it has been already registered if (application.registered) { // remove from Registry app registry.remove(entryId); + application.registered = false; } // Remove challenger used lock delete(usedLocks[challenge.lockId]); @@ -212,10 +212,10 @@ contract Curation is AragonApp { address loser; uint256 loserLockId; - if (voteResult == false) { // applicant and won + if (voteResult == false) { loser = challenge.challenger; loserLockId = challenge.lockId; - } else if (voteResult == true) { // challenger and won + } else { // voteResult == true loser = application.applicant; loserLockId = application.lockId; } diff --git a/test/curation.js b/test/curation.js index b1c723e..de21437 100644 --- a/test/curation.js +++ b/test/curation.js @@ -56,7 +56,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r, "NewApplication", "entryId") - const application = await curation.getApplication(entryId) + const application = await curation.getApplication.call(entryId) assert.equal(application[0], applicant, "Applicant should match") //assert.equal(application[1], , "Date should match") assert.equal(application[2], false, "Registered bool should match") @@ -114,7 +114,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const r1 = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r1, "NewApplication", "entryId") // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -128,7 +128,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('challenges application', async () => { const entryId = await applyAndChallenge() // checks - const challenge = await curation.getChallenge(entryId) + const challenge = await curation.getChallenge.call(entryId) assert.equal(challenge[0], challenger, "Challenger should match") //assert.equal(challenge[1], , "Date should match") assert.equal(challenge[2], false, "Resolved bool should match") @@ -148,10 +148,10 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await curation.setMinDeposit(minDeposit + 1) // mock lock - await staking.setLock(minDeposit + 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + await staking.setLock(minDeposit + 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // challenge const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) - const challenge = await curation.getChallenge(entryId) + const challenge = await curation.getChallenge.call(entryId) // no challenge has been created assert.equal(challenge[0], zeroAddress, "Challenger should be zero") assert.equal(challenge[1], 0, "Date should be zero") @@ -224,47 +224,121 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { return { entryId: entryId, receipt: receipt } } - it('resolves challenge, rejected', async () => { + it('resolves application challenge, rejected', async () => { const {entryId, receipt} = await applyChallengeAndResolve(false) // checks // registry assert.isTrue(await registry.exists(entryId), "Data should have been registered") // application - const application = await curation.getApplication(entryId) + const application = await curation.getApplication.call(entryId) assert.isTrue(application[2], "Registered should be true") // challenge - const challenge = await curation.getChallenge(entryId) + const challenge = await curation.getChallenge.call(entryId) assert.isTrue(challenge[2], "Resolved should be true") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) // used locks - const appUsedLock = await curation.getUsedLock(appLockId) - const challengeUsedLock = await curation.getUsedLock(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) assert.isFalse(appUsedLock) assert.isTrue(challengeUsedLock) }) - it('resolves challenge, accepted', async () => { + it('resolves application challenge, accepted', async () => { const {entryId, receipt} = await applyChallengeAndResolve(true) // checks // registry assert.isFalse(await registry.exists(data), "Data should not have been registered") // application - const application = await curation.getApplication(entryId) + const application = await curation.getApplication.call(entryId) assert.isFalse(application[2], "Registered should be false") // challenge - const challenge = await curation.getChallenge(entryId) + const challenge = await curation.getChallenge.call(entryId) assert.isTrue(challenge[2], "Resolved should be true") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) // used locks - const appUsedLock = await curation.getUsedLock(appLockId) - const challengeUsedLock = await curation.getUsedLock(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + assert.isTrue(appUsedLock) + assert.isFalse(challengeUsedLock) + }) + + const applyRegisterChallengeAndResolve = async (result) => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const r1 = await curation.newApplication(data, appLockId, { from: applicant }) + const entryId = getEvent(r1, "NewApplication", "entryId") + // time travel + await curation.addTime(applyStageLen + 1) + + // register + await curation.registerApplication(entryId) + + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + const challengeId = getEvent(r2, "NewChallenge", "entryId") + assert.equal(challengeId, entryId, "A NewChallenge event for the same entryId should have been generated") + + // mock vote result + await voting.setVoteClosed(voteId, true) + await voting.setVoteResult(voteId, result, WINNING_STAKE, TOTAL_STAKE) + // resolve + const receipt = await curation.resolveChallenge(entryId) + + return { entryId: entryId, receipt: receipt } + } + + it('resolves registry challenge, rejected', async () => { + const {entryId, receipt} = await applyRegisterChallengeAndResolve(false) + // checks + // registry + assert.isTrue(await registry.exists(entryId), "Data should still be registered") + // application + const application = await curation.getApplication.call(entryId) + assert.isTrue(application[2], "Registered should be true") + // challenge + const challenge = await curation.getChallenge.call(entryId) + assert.isTrue(challenge[2], "Resolved should be true") + // redistribution + const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) + assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) + assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) + // used locks + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + assert.isFalse(appUsedLock) + assert.isTrue(challengeUsedLock) + }) + + it('resolves registry challenge, accepted', async () => { + const {entryId, receipt} = await applyRegisterChallengeAndResolve(true) + + // checks + // registry + assert.isFalse(await registry.exists(data), "Data should have been removed from register") + // application + const application = await curation.getApplication.call(entryId) + assert.isFalse(application[2], "Registered should be false") + // challenge + const challenge = await curation.getChallenge.call(entryId) + assert.isTrue(challenge[2], "Resolved should be true") + // redistribution + const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) + assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) + assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) + // used locks + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) assert.isTrue(appUsedLock) assert.isFalse(challengeUsedLock) }) @@ -279,7 +353,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const r1 = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r1, "NewApplication", "entryId") // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -315,13 +389,13 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const {entryId} = await applyChallengeAndResolve(false) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) // mock Staking to pretend losing party tokens were already distributed - await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // claim reward const receipt = await curation.claimReward(entryId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) assert.isTrue(checkMovedTokens(receipt, challenger, voter, reward), "Reward should be payed") - const appUsedLock = await curation.getUsedLock(appLockId) - const challengeUsedLock = await curation.getUsedLock(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) assert.isFalse(appUsedLock) assert.isFalse(challengeUsedLock) }) @@ -335,10 +409,10 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const receipt = await curation.claimReward(entryId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") - const application = await curation.getApplication(entryId) + const application = await curation.getApplication.call(entryId) assert.equal(application[0], zeroAddress, "Application should be empty") - const appUsedLock = await curation.getUsedLock(appLockId) - const challengeUsedLock = await curation.getUsedLock(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) assert.isFalse(appUsedLock) assert.isFalse(challengeUsedLock) }) @@ -380,7 +454,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // registry assert.isTrue(await registry.exists(entryId), "Data should have been registered") // application - const application = await curation.getApplication(entryId) + const application = await curation.getApplication.call(entryId) assert.isTrue(application[2], "Registered should be true") }) @@ -394,7 +468,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const entryId = getEvent(r, "NewApplication", "entryId") // make sure time has not gone by - const application = await curation.getApplication(entryId) + const application = await curation.getApplication.call(entryId) await curation.setTimestamp(application[1]) // register @@ -415,7 +489,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const entryId = getEvent(r, "NewApplication", "entryId") // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt()).add(applyStageLen + 1000), curation.address, "") + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -535,4 +609,36 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) }) }) + + // just to call getTimestamp and be able to reach 100% coverage + context('Without Mock', async () => { + const appLockId = 1 + const data = "Test" + + beforeEach(async () => { + registry = await getContract('RegistryApp').new() + staking = await getContract('StakingMock').new() + voting = await getContract('VotingMock').new() + + curation = await getContract('Curation').new() + MAX_UINT64 = await curation.MAX_UINT64() + await curation.initialize(registry.address, staking.address, voting.address, minDeposit, applyStageLen, dispensationPct) + + }) + + it('creates new Application', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + const r = await curation.newApplication(data, appLockId, { from: applicant }) + const entryId = getEvent(r, "NewApplication", "entryId") + const application = await curation.getApplication.call(entryId) + assert.equal(application[0], applicant, "Applicant should match") + //assert.equal(application[1], , "Date should match") + assert.equal(application[2], false, "Registered bool should match") + assert.equal(application[3], web3.toHex(data), "Data should match") + assert.equal(application[4], minDeposit, "Amount should match") + assert.equal(application[5], appLockId, "LockId should match") + }) + }) }) From cb9dff7cfd3912118c170d7ee1b05320e84f2f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Fri, 15 Jun 2018 12:26:51 +0200 Subject: [PATCH 04/22] Increase coverage to 100% Closes #3. Besides, add CI. --- .travis.yml | 21 ++++ test/curation.js | 247 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 192 insertions(+), 76 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..463fa2e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +sudo: required +services: + - docker +language: node_js +cache: + directories: + - node_modules +notifications: + email: false +node_js: + - '8' +env: + - TASK=test + - TASK=lint + - TASK=coverage +before_script: + - npm prune +script: + - npm run $TASK +after_success: + - ./node_modules/.bin/lcov-result-merger 'apps/*/coverage/lcov.info' | ./node_modules/.bin/coveralls diff --git a/test/curation.js b/test/curation.js index de21437..706759e 100644 --- a/test/curation.js +++ b/test/curation.js @@ -50,12 +50,17 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // ----------- Create applications -------------- - it('creates new Application', async () => { + const createApplication = async () => { // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r, "NewApplication", "entryId") + + return entryId + } + + it('creates new Application', async () => { + const entryId = await createApplication() const application = await curation.getApplication.call(entryId) assert.equal(application[0], applicant, "Applicant should match") //assert.equal(application[1], , "Date should match") @@ -81,7 +86,6 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new Application with an ongoing application', async () => { const lockId1 = 1 const lockId2 = 2 - const data = "Test" // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // create application @@ -95,7 +99,6 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new Application with an already registered data', async () => { const lockId1 = 1 const lockId2 = 2 - const data = "Test" // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // register data - this won't happen with real app, as ACLs will be working! @@ -106,20 +109,67 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) }) + it('fails creating new Application with an empty data', async () => { + const lockId1 = 1 + const lockId2 = 2 + const emptyData = "" + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // register data - this won't happen with real app, as ACLs will be working! + await registry.add(data) + // create application + return assertRevert(async () => { + await curation.newApplication(emptyData, lockId2, { from: applicant }) + }) + }) + + it('fails creating new Application if Curation is not unlocker', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, owner, "") + // create application + return assertRevert(async () => { + await curation.newApplication(data, appLockId, { from: applicant }) + }) + }) + + it('fails creating new Application if lock deposit is not enough', async () => { + // mock lock + await staking.setLock(minDeposit - 1, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // create application + return assertRevert(async () => { + await curation.newApplication(data, appLockId, { from: applicant }) + }) + }) + + it('fails creating new Application if lock time unit is not seconds', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS + 1, MAX_UINT64, curation.address, "") + // create application + return assertRevert(async () => { + await curation.newApplication(data, appLockId, { from: applicant }) + }) + }) + + it('fails creating new Application if lock time is not enough', async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64 - 1, curation.address, "") + // create application + return assertRevert(async () => { + await curation.newApplication(data, appLockId, { from: applicant }) + }) + }) + // ----------- Challenge applications -------------- const applyAndChallenge = async () => { - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r1, "NewApplication", "entryId") + const entryId = await createApplication() // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge - const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) - const challengeId = getEvent(r2, "NewChallenge", "entryId") + const r = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + const challengeId = getEvent(r, "NewChallenge", "entryId") assert.equal(challengeId, entryId, "A NewChallenge event for the same entryId should have been generated") return entryId @@ -139,10 +189,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('challenges touch-and-remove application', async () => { - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r1, "NewApplication", "entryId") + const entryId = await createApplication() // increase minDeposit await curation.setMinDeposit(minDeposit + 1) @@ -150,7 +197,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock lock await staking.setLock(minDeposit + 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // challenge - const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) const challenge = await curation.getChallenge.call(entryId) // no challenge has been created assert.equal(challenge[0], zeroAddress, "Challenger should be zero") @@ -163,17 +210,14 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('fails challenging with an already used lock', async () => { - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r1, "NewApplication", "entryId") + const entryId = await createApplication() // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") // mock vote Id await voting.setVoteId(voteId) return assertRevert(async () => { // challenge - const r2 = await curation.challengeApplication(entryId, appLockId) + await curation.challengeApplication(entryId, appLockId) }) }) @@ -186,6 +230,54 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) }) + it('fails challenging application if Curation is not unlocker', async () => { + const entryId = await createApplication() + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), owner, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + return assertRevert(async () => { + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + }) + }) + + it('fails challenging application if lock deposit is not enough', async () => { + const entryId = await createApplication() + // mock lock + await staking.setLock(minDeposit - 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + return assertRevert(async () => { + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + }) + }) + + it('fails challenging application if lock time unit is not seconds', async () => { + const entryId = await createApplication() + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS + 1, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + return assertRevert(async () => { + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + }) + }) + + it('fails challenging application if lock time is not enough', async () => { + const entryId = await createApplication() + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen - 1), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + return assertRevert(async () => { + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + }) + }) + // ----------- Resolve challenges -------------- // checks if a log for moving tokens was generated with the given params @@ -270,10 +362,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) const applyRegisterChallengeAndResolve = async (result) => { - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r1, "NewApplication", "entryId") + const entryId = await createApplication() // time travel await curation.addTime(applyStageLen + 1) @@ -285,8 +374,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // mock vote Id await voting.setVoteId(voteId) // challenge - const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) - const challengeId = getEvent(r2, "NewChallenge", "entryId") + const r = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + const challengeId = getEvent(r, "NewChallenge", "entryId") assert.equal(challengeId, entryId, "A NewChallenge event for the same entryId should have been generated") // mock vote result @@ -344,14 +433,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('fails resolving challenge if vote has not ended', async () => { - const appLockId = 1 - const challengeLockId = 2 - const voteId = 1 - const data = "Test" - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - const r1 = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r1, "NewApplication", "entryId") + const entryId = await createApplication() // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // mock vote Id @@ -366,13 +448,40 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) }) + it('fails resolving application challenge twice', async () => { + const {entryId, receipt} = await applyChallengeAndResolve(false) + // mock vote result + await voting.setVoteClosed(voteId, true) + await voting.setVoteResult(voteId, false, WINNING_STAKE, TOTAL_STAKE) + // resolve again + return assertRevert(async () => { + await curation.resolveChallenge(entryId) + }) + }) + // ----------- Claim rewards -------------- - it('claims reward as voter in the winning party', async () => { - const {entryId} = await applyChallengeAndResolve(true) + const claimReward = async (result, lastClaim=false) => { + const {entryId} = await applyChallengeAndResolve(result) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) + + if (lastClaim) { + // mock Staking to pretend losing party tokens were already distributed + await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + } + + // claim reward const receipt = await curation.claimReward(entryId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) + return { + entryId: entryId, + receipt: receipt, + reward: reward + } + } + + it('claims reward as voter in the winning party', async () => { + const {receipt, reward} = await claimReward(true) assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") }) @@ -386,28 +495,20 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('claims reward and lock can be released, challenge rejected', async () => { - const {entryId} = await applyChallengeAndResolve(false) - await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) - // mock Staking to pretend losing party tokens were already distributed - await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") - // claim reward - const receipt = await curation.claimReward(entryId, { from: voter }) - const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) + const {receipt, reward} = await claimReward(false, true) + + // checks assert.isTrue(checkMovedTokens(receipt, challenger, voter, reward), "Reward should be payed") const appUsedLock = await curation.getUsedLock.call(appLockId) const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) - assert.isFalse(appUsedLock) - assert.isFalse(challengeUsedLock) + assert.isFalse(appUsedLock, "app lock should have been freed") + assert.isFalse(challengeUsedLock, "challenge lock should have been freed") }) it('claims reward and lock can be released, challenge accepted', async () => { - const {entryId} = await applyChallengeAndResolve(true) - await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) - // mock Staking to pretend losing party tokens were already distributed - await staking.setLock(0, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - // claim reward - const receipt = await curation.claimReward(entryId, { from: voter }) - const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) + const {entryId, receipt, reward} = await claimReward(true, true) + + // checks assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") const application = await curation.getApplication.call(entryId) assert.equal(application[0], zeroAddress, "Application should be empty") @@ -436,13 +537,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // ----------- Register applications -------------- it('registers application after stage period with no challenge', async () => { - const appLockId = 1 - const data = "Test" - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - // create application - const r = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r, "NewApplication", "entryId") + const entryId = await createApplication() // time travel await curation.addTime(applyStageLen + 1) @@ -459,13 +554,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('fails registering an application if time has not gone by', async () => { - const appLockId = 1 - const data = "Test" - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - // create application - const r = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r, "NewApplication", "entryId") + const entryId = await createApplication() // make sure time has not gone by const application = await curation.getApplication.call(entryId) @@ -478,27 +567,33 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) it('fails registering an application if it has a challenge', async () => { - const appLockId = 1 - const data = "Test" - const challengeLockId = 2 - const voteId = 1 - // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") - // create application - const r = await curation.newApplication(data, appLockId, { from: applicant }) - const entryId = getEvent(r, "NewApplication", "entryId") + const entryId = await createApplication() // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge - const r2 = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + + // time travel + await curation.addTime(applyStageLen + 1) + + // register + return assertRevert(async () => { + await curation.registerApplication(entryId) + }) + }) + + it('fails registering an application twice', async () => { + const entryId = await createApplication() // time travel await curation.addTime(applyStageLen + 1) // register + await curation.registerApplication(entryId) + return assertRevert(async () => { await curation.registerApplication(entryId) }) From 7114fe311bd7d98bbf1aa2faa9a9fbc8c5c2a4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Fri, 15 Jun 2018 17:35:35 +0200 Subject: [PATCH 05/22] Use partial unlock before moving tokens Closes #4. See: https://github.com/aragon/aragon-apps/pull/380 --- contracts/Curation.sol | 15 ++++++--------- contracts/interfaces/IStaking.sol | 2 +- test/mocks/StakingMock.sol | 6 +++--- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 12bc0d4..beab0f0 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -146,7 +146,6 @@ contract Curation is AragonApp { dispensationPct: dispensationPct }); - // TODO: ids? NewChallenge(entryId, msg.sender); return entryId; @@ -163,6 +162,7 @@ contract Curation is AragonApp { bool voteResult; (voteResult,,) = voting.getVoteResult(challenge.voteId); + uint256 reward; if (voteResult == false) { // challenge not accepted (application remains) // it's still in application phase (not registered yet) if (!application.registered) { @@ -173,10 +173,9 @@ contract Curation is AragonApp { // Remove applicant used lock delete(usedLocks[application.lockId]); // Unlock challenger tokens from Staking app - // TODO: unlock partially only! - staking.unlock(challenge.challenger, challenge.lockId); + reward = challenge.amount.mul(dispensationPct) / PCT_BASE; // Redistribute tokens - staking.moveTokens(challenge.challenger, application.applicant, challenge.amount.mul(dispensationPct) / PCT_BASE); + staking.unlockAndMoveTokens(challenge.lockId, challenge.challenger, application.applicant, reward); } else { // challenge accepted (application rejected) // it has been already registered if (application.registered) { @@ -187,10 +186,9 @@ contract Curation is AragonApp { // Remove challenger used lock delete(usedLocks[challenge.lockId]); // Unlock applicant tokens from Staking app - // TODO: unlock partially only! - staking.unlock(application.applicant, application.lockId); + reward = application.amount.mul(dispensationPct) / PCT_BASE; // Redistribute tokens - staking.moveTokens(application.applicant, challenge.challenger, application.amount.mul(dispensationPct) / PCT_BASE); + staking.unlockAndMoveTokens(application.lockId, application.applicant, challenge.challenger, reward); } challenge.resolved = true; @@ -225,9 +223,8 @@ contract Curation is AragonApp { require(voterWinningStake > 0); // amount * (voter / total) * (1 - dispensationPct) uint256 reward = challenge.amount.mul(voterWinningStake).mul(PCT_BASE.sub(dispensationPct)) / (totalWinningStake * PCT_BASE); - // TODO: partial unlock // Redistribute tokens - staking.moveTokens(loser, msg.sender, reward); + staking.unlockAndMoveTokens(loserLockId, loser, msg.sender, reward); // check if lock can be released uint256 amount; diff --git a/contracts/interfaces/IStaking.sol b/contracts/interfaces/IStaking.sol index 717c83c..6211ab1 100644 --- a/contracts/interfaces/IStaking.sol +++ b/contracts/interfaces/IStaking.sol @@ -3,7 +3,7 @@ pragma solidity ^0.4.18; interface IStaking { function unlock(address acct, uint256 lockId) public; - function moveTokens(address from, address to, uint256 amount) external; + function unlockAndMoveTokens(uint256 lockId, address from, address to, uint256 amount) external; function getLock(address acct, uint256 lockId) public view returns (uint256 amount, uint8 lockUnit, uint64 lockEnds, address unlocker, bytes32 metadata); } diff --git a/test/mocks/StakingMock.sol b/test/mocks/StakingMock.sol index 87eced4..2558822 100644 --- a/test/mocks/StakingMock.sol +++ b/test/mocks/StakingMock.sol @@ -23,11 +23,11 @@ contract StakingMock is IStaking { // do nothing } - function moveTokens(address from, address to, uint256 amount) external { - MovedTokens(from, to, amount); + function unlockAndMoveTokens(uint256 _lockId, address _from, address _to, uint256 _amount) external { + MovedTokens(_from, _to, _amount); } - function getLock(address acct, uint256 lockId) public view returns (uint256, uint8, uint64, address, bytes32) { + function getLock(address _acct, uint256 _lockId) public view returns (uint256, uint8, uint64, address, bytes32) { return (amount, lockUnit, lockEnds, unlocker, metadata); } From a00e6065b456a2df8c07165320c69b8240875435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Fri, 15 Jun 2018 18:09:55 +0200 Subject: [PATCH 06/22] Fix lint --- .soliumrc.json | 3 ++- contracts/Curation.sol | 14 +++++++++----- contracts/interfaces/IRegistry.sol | 5 ++++- contracts/interfaces/IStaking.sol | 17 ++++++++++++++++- contracts/interfaces/IVoting.sol | 3 +++ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/.soliumrc.json b/.soliumrc.json index f69c670..d162230 100644 --- a/.soliumrc.json +++ b/.soliumrc.json @@ -17,6 +17,7 @@ "deprecated-suicide": ["error"], "arg-overflow": ["error", 8], "pragma-on-top": ["error"], - "security/enforce-explicit-visibility": ["error"] + "security/enforce-explicit-visibility": ["error"], + "emit": 0 } } diff --git a/contracts/Curation.sol b/contracts/Curation.sol index beab0f0..174c0d4 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -264,7 +264,10 @@ contract Curation is AragonApp { _setApplyStageLen(_applyStageLen); } - function setDispensationPct(uint256 _dispensationPct) authP(CHANGE_PARAMS_ROLE, arr(uint256(DISPENSATION_PCT_PARAM), _dispensationPct)) public { + function setDispensationPct(uint256 _dispensationPct) + authP(CHANGE_PARAMS_ROLE, arr(uint256(DISPENSATION_PCT_PARAM), _dispensationPct)) + public + { require(_dispensationPct <= PCT_BASE); _setDispensationPct(_dispensationPct); @@ -272,8 +275,9 @@ contract Curation is AragonApp { function canBeRegistered(bytes32 entryId) view public returns (bool) { // no challenges - if (uint64(getTimestamp()) > applications[entryId].date.add(applyStageLen) - && challenges[entryId].challenger == address(0) ) { + if (uint64(getTimestamp()) > applications[entryId].date.add(applyStageLen) && + challenges[entryId].challenger == address(0)) + { return true; } @@ -288,7 +292,7 @@ contract Curation is AragonApp { bytes32 entryId ) view - external + public returns ( address applicant, uint64 date, @@ -313,7 +317,7 @@ contract Curation is AragonApp { bytes32 entryId ) view - external + public returns ( address challenger, uint64 date, diff --git a/contracts/interfaces/IRegistry.sol b/contracts/interfaces/IRegistry.sol index da5b4a3..99af3a4 100644 --- a/contracts/interfaces/IRegistry.sol +++ b/contracts/interfaces/IRegistry.sol @@ -2,7 +2,7 @@ pragma solidity ^0.4.18; interface IRegistry { - function exists(bytes32 _id) public constant returns (bool); + function exists(bytes32 _id) public view returns (bool); function add(bytes _data) public returns (bytes32 _id); function remove(bytes32 _id) public; } @@ -10,4 +10,7 @@ interface IRegistry { contract FakeRegistry { // to work around coverage issue + function fake() public { + // for lint + } } diff --git a/contracts/interfaces/IStaking.sol b/contracts/interfaces/IStaking.sol index 6211ab1..638bab4 100644 --- a/contracts/interfaces/IStaking.sol +++ b/contracts/interfaces/IStaking.sol @@ -4,10 +4,25 @@ pragma solidity ^0.4.18; interface IStaking { function unlock(address acct, uint256 lockId) public; function unlockAndMoveTokens(uint256 lockId, address from, address to, uint256 amount) external; - function getLock(address acct, uint256 lockId) public view returns (uint256 amount, uint8 lockUnit, uint64 lockEnds, address unlocker, bytes32 metadata); + function getLock( + address acct, + uint256 lockId + ) + public + view + returns ( + uint256 amount, + uint8 lockUnit, + uint64 lockEnds, + address unlocker, + bytes32 metadata + ); } contract FakeStaking { // to work around coverage issue + function fake() public { + // for lint + } } diff --git a/contracts/interfaces/IVoting.sol b/contracts/interfaces/IVoting.sol index 3ea00e0..dfd3f25 100644 --- a/contracts/interfaces/IVoting.sol +++ b/contracts/interfaces/IVoting.sol @@ -13,4 +13,7 @@ interface IVoting { contract FakeVoting { // to work around coverage issue + function fake() public { + // for lint + } } From fe07f6dfc0484cfad0a58617fb4a33b1ed551d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 19 Jun 2018 14:03:52 +0200 Subject: [PATCH 07/22] Add EVMScripts for resolving challenge Now Voting app can resolve challenge when vote is over without the need for another call from Curation app. --- contracts/Curation.sol | 22 +++++- test/TestCuration.sol | 3 + test/mocks/VotingMock.sol | 30 ++++++-- test/script.js | 158 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 11 deletions(-) create mode 100644 test/script.js diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 174c0d4..8c79d11 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -1,7 +1,6 @@ pragma solidity 0.4.18; import "@aragon/os/contracts/apps/AragonApp.sol"; -import "@aragon/os/contracts/common/IsContract.sol"; import "@aragon/os/contracts/lib/misc/Migrations.sol"; import "@aragon/os/contracts/lib/zeppelin/math/SafeMath.sol"; import "@aragon/os/contracts/lib/zeppelin/math/SafeMath64.sol"; @@ -132,9 +131,26 @@ contract Curation is AragonApp { } // create vote - // TODO: script // TODO: metadata - uint256 voteId = voting.newVote("", ""); + // script to call `resolveChallenge(entryId)` + uint256 scriptLength = 64; // 4 (spec) + 20 (address) + 4 (calldataLength) + 4 (signature) + 32 (input) + bytes4 spec = bytes4(0x01); + address target = address(this); + bytes memory targetBytes = new bytes(32); + bytes4 calldataLength = bytes4(0x24); // 4 + 32 + bytes4 signature = this.resolveChallenge.selector; + bytes memory executionScript = new bytes(scriptLength); + // concatenate spec + address(this) + calldataLength + calldata + // TODO: should we put this somewhere in aragonOS to be able ti reuse? (if it's not already there) + assembly { + mstore(add(executionScript, 0x20), spec) + mstore(add(targetBytes, 0x20), target) + mstore(add(executionScript, 0x24), mload(add(targetBytes, 0x2C))) + mstore(add(executionScript, 0x38), calldataLength) + mstore(add(executionScript, 0x3C), signature) + mstore(add(executionScript, 0x40), entryId) + } + uint256 voteId = voting.newVote(executionScript, ""); challenges[entryId] = Challenge({ challenger: msg.sender, diff --git a/test/TestCuration.sol b/test/TestCuration.sol index e12b1ca..111195a 100644 --- a/test/TestCuration.sol +++ b/test/TestCuration.sol @@ -1,6 +1,9 @@ pragma solidity 0.4.18; import "@aragon/apps-registry/contracts/RegistryApp.sol"; +import "@aragon/os/contracts/factory/EVMScriptRegistryFactory.sol"; +import "@aragon/os/contracts/factory/DAOFactory.sol"; + // You might think this file is a bit odd, but let me explain. // We only use these contracts in our tests, which diff --git a/test/mocks/VotingMock.sol b/test/mocks/VotingMock.sol index 5e35d2c..e9411be 100644 --- a/test/mocks/VotingMock.sol +++ b/test/mocks/VotingMock.sol @@ -1,25 +1,33 @@ pragma solidity 0.4.18; import "../../contracts/interfaces/IVoting.sol"; +import "@aragon/os/contracts/apps/AragonApp.sol"; -contract VotingMock is IVoting { +contract VotingMock is IVoting, AragonApp { uint256 voteId; struct Vote { + bytes script; + bool closed; // TODO bool result; uint256 winningStake; uint256 totalStake; } - mapping(uint256 => Vote) results; - mapping(uint256 => bool) closed; // TODO + mapping(uint256 => Vote) votes; mapping(address => uint256) voterWinningStake; + function VotingMock() public { + voteId = 0; + } + function newVote(bytes _executionScript, string _metadata) external returns (uint256) { + votes[voteId] = Vote(_executionScript, false, false, 0, 0); + return voteId; } function setVoteClosed(uint256 _voteId, bool _closed) public { - closed[_voteId] = _closed; + votes[_voteId].closed = _closed; } function setVoteId(uint256 _voteId) public { @@ -27,20 +35,26 @@ contract VotingMock is IVoting { } function setVoteResult(uint256 _voteId, bool _result, uint256 _winningStake, uint256 _totalStake) public { - results[_voteId] = Vote(_result, _winningStake, _totalStake); + votes[_voteId].result = _result; + votes[_voteId].winningStake = _winningStake; + votes[_voteId].totalStake = _totalStake; } - function setVoterWinningStake(address _voter, uint256 _stake) { + function setVoterWinningStake(address _voter, uint256 _stake) public { voterWinningStake[_voter] = _stake; } + function execute(uint256 _voteId) public { + runScript(votes[_voteId].script, new bytes(0), new address[](0)); + } + // TODO: canExecute or isClosed?? function isClosed(uint256 _voteId) view public returns (bool) { - return closed[_voteId]; + return votes[_voteId].closed; } function getVoteResult(uint256 _voteId) view public returns (bool _result, uint256 _winningStake, uint256 _totalStake) { - return (results[_voteId].result, results[_voteId].winningStake, results[_voteId].totalStake); + return (votes[_voteId].result, votes[_voteId].winningStake, votes[_voteId].totalStake); } function getVoterWinningStake(uint256 _voteId, address _voter) view public returns (uint256) { diff --git a/test/script.js b/test/script.js new file mode 100644 index 0000000..296cabe --- /dev/null +++ b/test/script.js @@ -0,0 +1,158 @@ +const { assertRevert } = require('@aragon/test-helpers/assertThrow') + +const getContract = name => artifacts.require(name) +const getEvent = (receipt, event, arg) => { return receipt.logs.filter(l => l.event == event)[0].args[arg] } +const pct16 = x => new web3.BigNumber(x).times(new web3.BigNumber(10).toPower(16)) + +contract('Curation', ([owner, applicant, challenger, voter, _]) => { + let curation, registry, staking, voting, MAX_UINT64 + const minDeposit = 100 + const applyStageLen = 1000 + const dispensationPct = pct16(60) + const WINNING_STAKE = 70 + const TOTAL_STAKE = 100 + const VOTER_WINNING_STAKE = 10 + + const zeroAddress = "0x0000000000000000000000000000000000000000" + const TIME_UNIT_BLOCKS = 0 + const TIME_UNIT_SECONDS = 1 + + const appLockId = 1 + const challengeLockId = 2 + const voteId = 1 + const data = "Test" + + const createApplication = async () => { + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const r = await curation.newApplication(data, appLockId, { from: applicant }) + const entryId = getEvent(r, "NewApplication", "entryId") + + return entryId + } + + const applyAndChallenge = async () => { + const entryId = await createApplication() + // mock lock + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + // mock vote Id + await voting.setVoteId(voteId) + // challenge + const r = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) + const challengeId = getEvent(r, "NewChallenge", "entryId") + assert.equal(challengeId, entryId, "A NewChallenge event for the same entryId should have been generated") + + return entryId + } + + const applyChallengeAndResolve = async (result) => { + const entryId = await applyAndChallenge() + // mock vote result + await voting.setVoteClosed(voteId, true) + await voting.setVoteResult(voteId, result, WINNING_STAKE, TOTAL_STAKE) + // resolve + const receipt = await curation.resolveChallenge(entryId) + + return { entryId: entryId, receipt: receipt } + } + + const applyChallengeAndExecute = async(result) => { + const entryId = await applyAndChallenge() + // mock vote result + await voting.setVoteClosed(voteId, true) + await voting.setVoteResult(voteId, result, WINNING_STAKE, TOTAL_STAKE) + // execute vote + const receipt = await voting.execute(voteId) + + return { entryId: entryId, receipt: receipt } + } + + const checkMovedTokens = (receipt, from, to, amount) => { + const logs = receipt.receipt.logs.filter( + l => + l.topics[0] == web3.sha3('MovedTokens(address,address,uint256)') && + '0x' + l.topics[1].slice(26) == from && + '0x' + l.topics[2].slice(26) == to && + (web3.toDecimal(l.data) == amount || amount == 0) + ) + return logs.length == 1 || (amount == 0 && logs.length >= 1) + } + + context('Using voting script', async () => { + let daoFact + + before(async () => { + const kernelBase = await getContract('Kernel').new() + const aclBase = await getContract('ACL').new() + const regFact = await getContract('EVMScriptRegistryFactory').new() + daoFact = await getContract('DAOFactory').new(kernelBase.address, aclBase.address, regFact.address) + }) + + beforeEach(async () => { + registry = await getContract('RegistryApp').new() + staking = await getContract('StakingMock').new() + + // DAO + const r = await daoFact.newDAO(owner) + const dao = getContract('Kernel').at(r.logs.filter(l => l.event == 'DeployDAO')[0].args.dao) + const acl = getContract('ACL').at(await dao.acl()) + + await acl.createPermission(owner, dao.address, await dao.APP_MANAGER_ROLE(), owner, { from: owner }) + + // Voting + const receiptVoting = await dao.newAppInstance('0x5678', (await getContract('VotingMock').new()).address, { from: owner }) + voting = getContract('VotingMock').at(receiptVoting.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy) + + // Curation + const receipt = await dao.newAppInstance('0x1234', (await getContract('CurationMock').new()).address, { from: owner }) + curation = getContract('CurationMock').at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy) + MAX_UINT64 = await curation.MAX_UINT64() + + await curation.initialize(registry.address, staking.address, voting.address, minDeposit, applyStageLen, dispensationPct) + }) + + it('challenges application and executes, challenge rejected', async () => { + const {entryId, receipt} = await applyChallengeAndExecute(false) + // checks + // registry + assert.isTrue(await registry.exists(entryId), "Data should have been registered") + // application + const application = await curation.getApplication.call(entryId) + assert.isTrue(application[2], "Registered should be true") + // challenge + const challenge = await curation.getChallenge.call(entryId) + assert.isTrue(challenge[2], "Resolved should be true") + // redistribution + const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) + assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) + assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) + // used locks + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + assert.isFalse(appUsedLock) + assert.isTrue(challengeUsedLock) + }) + + it('challenges application and executes, challenge accepted', async () => { + const {entryId, receipt} = await applyChallengeAndExecute(true) + // checks + // registry + assert.isFalse(await registry.exists(data), "Data should not have been registered") + // application + const application = await curation.getApplication.call(entryId) + assert.isFalse(application[2], "Registered should be false") + // challenge + const challenge = await curation.getChallenge.call(entryId) + assert.isTrue(challenge[2], "Resolved should be true") + // redistribution + const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) + assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) + assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) + // used locks + const appUsedLock = await curation.getUsedLock.call(appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + assert.isTrue(appUsedLock) + assert.isFalse(challengeUsedLock) + }) + }) +}) From 0973f1a6d3c97c5ed034f7f70b994f6c0de96e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 19 Jun 2018 14:04:59 +0200 Subject: [PATCH 08/22] Skip interfaces in coverage --- .solcover.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.solcover.js b/.solcover.js index 2169f75..ae9fcf7 100644 --- a/.solcover.js +++ b/.solcover.js @@ -3,4 +3,5 @@ module.exports = { // rsync is needed so symlinks are resolved on copy of lerna packages testCommand: 'rsync --copy-links -r ../node_modules/@aragon node_modules && node --max-old-space-size=4096 ../node_modules/.bin/truffle test --network coverage', copyNodeModules: true, + skipFiles: ['interfaces/IRegistry.sol', 'interfaces/IStaking.sol', 'interfaces/IVoting.sol'], } From af54e755dbae6ee7287d223fc394109e3f411ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 19 Jun 2018 20:40:11 +0200 Subject: [PATCH 09/22] Add config files `manifest.json` and `arapp.json` --- arapp.json | 9 +++++++++ manifest.json | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 arapp.json create mode 100644 manifest.json diff --git a/arapp.json b/arapp.json new file mode 100644 index 0000000..ebcaebb --- /dev/null +++ b/arapp.json @@ -0,0 +1,9 @@ +{ + "appName": "curation.aragonpm.eth", + "version": "1.0.0", + "roles": [ + { "name": "Change parameters", "id": "CHANGE_PARAMS_ROLE", "params": ["Param id", "Value"] }, + { "name": "Change Voting app", "id": "CHANGE_VOTING_APP_ROLE", "params": ["Old Voting app", "New Voting app"] } + ], + "path": "contracts/Curation.sol" +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..3634cf5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,8 @@ +{ + "name": "Curation", + "description": "Curation component of the TCR stack", + "icons": [{ + "src": "images/icon.png", + "sizes": "192x192" + }] +} From cff565a8ae115b0f8416f2223c89efdddfc8d48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 19 Jun 2018 20:49:00 +0200 Subject: [PATCH 10/22] Move reward condition assignments close to checks --- contracts/Curation.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 8c79d11..088ba64 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -172,6 +172,8 @@ contract Curation is AragonApp { Application storage application = applications[entryId]; require(!challenge.resolved); + // to avoid resolving and redistributing twice + challenge.resolved = true; // TODO: canExecute?? require(voting.isClosed(challenge.voteId)); @@ -207,7 +209,6 @@ contract Curation is AragonApp { staking.unlockAndMoveTokens(application.lockId, application.applicant, challenge.challenger, reward); } - challenge.resolved = true; ResolvedChallenge(entryId, voteResult); } @@ -220,6 +221,9 @@ contract Curation is AragonApp { // avoid claiming twice require(!challenge.claims[msg.sender]); + // register claim to avoid claiming it again + challenge.claims[msg.sender] = true; + bool voteResult; uint256 totalWinningStake; (voteResult, totalWinningStake,) = voting.getVoteResult(challenge.voteId); @@ -252,9 +256,6 @@ contract Curation is AragonApp { delete(applications[entryId]); } } - - // register claim to avoid claiming it again - challenge.claims[msg.sender] = true; } function registerApplication(bytes32 entryId) isInitialized public { From 8e962329831559817a19de8413bd8985947c5945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Thu, 21 Jun 2018 12:08:30 +0200 Subject: [PATCH 11/22] Remove mock function from Voting interface --- contracts/interfaces/IVoting.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/interfaces/IVoting.sol b/contracts/interfaces/IVoting.sol index dfd3f25..ca0a8c6 100644 --- a/contracts/interfaces/IVoting.sol +++ b/contracts/interfaces/IVoting.sol @@ -3,10 +3,8 @@ pragma solidity ^0.4.18; interface IVoting { function newVote(bytes _executionScript, string _metadata) external returns (uint256 voteId); - function setVoteResult(uint256 voteId, bool result, uint256 winningStake, uint256 totalStake) public; - // TODO: canExecute or isClosed?? function isClosed(uint256 voteId) view public returns (bool); - function getVoteResult(uint256 voteId) view public returns (bool, uint256, uint256); + function getVoteResult(uint256 voteId) view public returns (bool result, uint256 winningStake, uint256 totalStake); function getVoterWinningStake(uint256 voteId, address voter) view public returns (uint256); } From 8bf66517ab0e961531e36541d49f5f68412731b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Thu, 21 Jun 2018 12:23:36 +0200 Subject: [PATCH 12/22] Move uint64 cast to getTimestamp --- contracts/Curation.sol | 12 ++++++------ test/mocks/CurationMock.sol | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 088ba64..7a9e777 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -104,7 +104,7 @@ contract Curation is AragonApp { applications[entryId] = Application({ applicant: msg.sender, - date: uint64(getTimestamp()), + date: getTimestamp(), registered: false, data: data, amount: amount, @@ -119,7 +119,7 @@ contract Curation is AragonApp { // check application doesn't have an ongoing challenge require(!challengeExists(entryId)); // check locked tokens - uint256 amount = _checkLock(lockId, uint64(getTimestamp()).add(applyStageLen)); + uint256 amount = _checkLock(lockId, getTimestamp().add(applyStageLen)); // touch-and-remove case Application memory application = applications[entryId]; @@ -154,7 +154,7 @@ contract Curation is AragonApp { challenges[entryId] = Challenge({ challenger: msg.sender, - date: uint64(getTimestamp()), + date: getTimestamp(), resolved: false, amount: amount, lockId: lockId, @@ -292,7 +292,7 @@ contract Curation is AragonApp { function canBeRegistered(bytes32 entryId) view public returns (bool) { // no challenges - if (uint64(getTimestamp()) > applications[entryId].date.add(applyStageLen) && + if (getTimestamp() > applications[entryId].date.add(applyStageLen) && challenges[entryId].challenger == address(0)) { return true; @@ -406,7 +406,7 @@ contract Curation is AragonApp { return challenges[entryId].challenger != address(0); } - function getTimestamp() view internal returns (uint256) { - return now; + function getTimestamp() view internal returns (uint64) { + return uint64(now); } } diff --git a/test/mocks/CurationMock.sol b/test/mocks/CurationMock.sol index d9b3b34..0c66561 100644 --- a/test/mocks/CurationMock.sol +++ b/test/mocks/CurationMock.sol @@ -4,21 +4,21 @@ import "../../contracts/Curation.sol"; contract CurationMock is Curation { - uint256 _mockTime = now; + uint64 _mockTime = uint64(now); - function getTimestampExt() external view returns (uint256) { + function getTimestampExt() external view returns (uint64) { return getTimestamp(); } - function setTimestamp(uint i) public { + function setTimestamp(uint64 i) public { _mockTime = i; } - function addTime(uint i) public { + function addTime(uint64 i) public { _mockTime += i; } - function getTimestamp() internal view returns (uint256) { + function getTimestamp() internal view returns (uint64) { return _mockTime; } From e32a4a9c32f39b4c8dc8f0834d26dfc3afef3752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Thu, 21 Jun 2018 15:13:14 +0200 Subject: [PATCH 13/22] Change parameters order in Staking unlockAndMoveTokens function --- contracts/Curation.sol | 6 +++--- contracts/interfaces/IStaking.sol | 2 +- test/mocks/StakingMock.sol | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 7a9e777..493535d 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -193,7 +193,7 @@ contract Curation is AragonApp { // Unlock challenger tokens from Staking app reward = challenge.amount.mul(dispensationPct) / PCT_BASE; // Redistribute tokens - staking.unlockAndMoveTokens(challenge.lockId, challenge.challenger, application.applicant, reward); + staking.unlockAndMoveTokens(challenge.challenger, challenge.lockId, application.applicant, reward); } else { // challenge accepted (application rejected) // it has been already registered if (application.registered) { @@ -206,7 +206,7 @@ contract Curation is AragonApp { // Unlock applicant tokens from Staking app reward = application.amount.mul(dispensationPct) / PCT_BASE; // Redistribute tokens - staking.unlockAndMoveTokens(application.lockId, application.applicant, challenge.challenger, reward); + staking.unlockAndMoveTokens(application.applicant, application.lockId, challenge.challenger, reward); } ResolvedChallenge(entryId, voteResult); @@ -244,7 +244,7 @@ contract Curation is AragonApp { // amount * (voter / total) * (1 - dispensationPct) uint256 reward = challenge.amount.mul(voterWinningStake).mul(PCT_BASE.sub(dispensationPct)) / (totalWinningStake * PCT_BASE); // Redistribute tokens - staking.unlockAndMoveTokens(loserLockId, loser, msg.sender, reward); + staking.unlockAndMoveTokens(loser, loserLockId, msg.sender, reward); // check if lock can be released uint256 amount; diff --git a/contracts/interfaces/IStaking.sol b/contracts/interfaces/IStaking.sol index 638bab4..ccdc6ce 100644 --- a/contracts/interfaces/IStaking.sol +++ b/contracts/interfaces/IStaking.sol @@ -3,7 +3,7 @@ pragma solidity ^0.4.18; interface IStaking { function unlock(address acct, uint256 lockId) public; - function unlockAndMoveTokens(uint256 lockId, address from, address to, uint256 amount) external; + function unlockAndMoveTokens(address from, uint256 lockId, address to, uint256 amount) external; function getLock( address acct, uint256 lockId diff --git a/test/mocks/StakingMock.sol b/test/mocks/StakingMock.sol index 2558822..3c466ef 100644 --- a/test/mocks/StakingMock.sol +++ b/test/mocks/StakingMock.sol @@ -23,7 +23,7 @@ contract StakingMock is IStaking { // do nothing } - function unlockAndMoveTokens(uint256 _lockId, address _from, address _to, uint256 _amount) external { + function unlockAndMoveTokens(address _from, uint256 _lockId, address _to, uint256 _amount) external { MovedTokens(_from, _to, _amount); } From b0563d7633642b394b35f4246c8295954e04cec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Mon, 25 Jun 2018 16:36:12 +0200 Subject: [PATCH 14/22] Fix test assert descriptions --- test/curation.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/curation.js b/test/curation.js index 706759e..9772a0c 100644 --- a/test/curation.js +++ b/test/curation.js @@ -37,9 +37,9 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.equal(await curation.registry(), registry.address, "Registry address should match") assert.equal(await curation.staking(), staking.address, "Staking address should match") assert.equal(await curation.voting(), voting.address, "Voting address should match") - assert.equal(await curation.minDeposit(), minDeposit, "minDeposit address should match") - assert.equal(await curation.applyStageLen(), applyStageLen, "applyStageLen address should match") - assert.equal((await curation.dispensationPct()).toString(), dispensationPct.toString(), "dispensationPct address should match") + assert.equal(await curation.minDeposit(), minDeposit, "minDeposit should match") + assert.equal(await curation.applyStageLen(), applyStageLen, "applyStageLen should match") + assert.equal((await curation.dispensationPct()).toString(), dispensationPct.toString(), "dispensationPct should match") }) it('fails on reinitialization', async () => { From 7ea22045da92860e4106ee09357fdbf83170eb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Mon, 25 Jun 2018 20:14:06 +0200 Subject: [PATCH 15/22] Unify interfaces Move IStaking to @aragon/apps-staking --- contracts/Curation.sol | 2 +- contracts/interfaces/IVoting.sol | 4 ++-- package-lock.json | 2 +- package.json | 2 +- test/mocks/StakingMock.sol | 6 +++++- test/mocks/VotingMock.sol | 5 ++--- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 493535d..e5f4414 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -5,8 +5,8 @@ import "@aragon/os/contracts/lib/misc/Migrations.sol"; import "@aragon/os/contracts/lib/zeppelin/math/SafeMath.sol"; import "@aragon/os/contracts/lib/zeppelin/math/SafeMath64.sol"; +import "@aragon/apps-staking/contracts/interfaces/IStaking.sol"; import "./interfaces/IRegistry.sol"; -import "./interfaces/IStaking.sol"; import "./interfaces/IVoting.sol"; diff --git a/contracts/interfaces/IVoting.sol b/contracts/interfaces/IVoting.sol index ca0a8c6..1d6be8a 100644 --- a/contracts/interfaces/IVoting.sol +++ b/contracts/interfaces/IVoting.sol @@ -4,8 +4,8 @@ pragma solidity ^0.4.18; interface IVoting { function newVote(bytes _executionScript, string _metadata) external returns (uint256 voteId); function isClosed(uint256 voteId) view public returns (bool); - function getVoteResult(uint256 voteId) view public returns (bool result, uint256 winningStake, uint256 totalStake); - function getVoterWinningStake(uint256 voteId, address voter) view public returns (uint256); + function getVoteResult(uint256 voteId) public returns (bool result, uint256 winningStake, uint256 totalStake); + function getVoterWinningStake(uint256 voteId, address voter) public returns (uint256); } diff --git a/package-lock.json b/package-lock.json index 04ace05..62dcfea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "curation", + "name": "@aragon/apps-curation", "version": "1.0.0", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 8954bfd..645b7eb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@aragon/apps-curation", "version": "1.0.0", "description": "Curation App for Aragon TCR", - "main": "index.js", + "main": "truffle.js", "scripts": { "compile": "truffle compile", "lint": "solium --dir ./contracts", diff --git a/test/mocks/StakingMock.sol b/test/mocks/StakingMock.sol index 3c466ef..6835b83 100644 --- a/test/mocks/StakingMock.sol +++ b/test/mocks/StakingMock.sol @@ -1,6 +1,6 @@ pragma solidity 0.4.18; -import "../../contracts/interfaces/IStaking.sol"; +import "@aragon/apps-staking/contracts/interfaces/IStaking.sol"; contract StakingMock is IStaking { @@ -23,6 +23,10 @@ contract StakingMock is IStaking { // do nothing } + function moveTokens(address _from, address _to, uint256 _amount) public { + MovedTokens(_from, _to, _amount); + } + function unlockAndMoveTokens(address _from, uint256 _lockId, address _to, uint256 _amount) external { MovedTokens(_from, _to, _amount); } diff --git a/test/mocks/VotingMock.sol b/test/mocks/VotingMock.sol index e9411be..bcede76 100644 --- a/test/mocks/VotingMock.sol +++ b/test/mocks/VotingMock.sol @@ -48,16 +48,15 @@ contract VotingMock is IVoting, AragonApp { runScript(votes[_voteId].script, new bytes(0), new address[](0)); } - // TODO: canExecute or isClosed?? function isClosed(uint256 _voteId) view public returns (bool) { return votes[_voteId].closed; } - function getVoteResult(uint256 _voteId) view public returns (bool _result, uint256 _winningStake, uint256 _totalStake) { + function getVoteResult(uint256 _voteId) public returns (bool _result, uint256 _winningStake, uint256 _totalStake) { return (votes[_voteId].result, votes[_voteId].winningStake, votes[_voteId].totalStake); } - function getVoterWinningStake(uint256 _voteId, address _voter) view public returns (uint256) { + function getVoterWinningStake(uint256 _voteId, address _voter) public returns (uint256) { if (!isClosed(_voteId)) { return 0; } From aa887f350f98bde7d9596cd065d9f61a4f9d9cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Wed, 4 Jul 2018 13:45:27 +0200 Subject: [PATCH 16/22] Fix wrong used locks management Staking app registers locks per user, not globally. --- contracts/Curation.sol | 18 +++++++++--------- test/curation.js | 30 ++++++++++++++++-------------- test/mocks/CurationMock.sol | 4 ++-- test/script.js | 8 ++++---- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index e5f4414..16c8e57 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -55,7 +55,7 @@ contract Curation is AragonApp { mapping(bytes32 => Application) applications; mapping(bytes32 => Challenge) challenges; - mapping(uint256 => bool) usedLocks; + mapping(address => mapping(uint256 => bool)) usedLocks; event NewApplication(bytes32 entryId, address applicant); event NewChallenge(bytes32 entryId, address challenger); @@ -100,7 +100,7 @@ contract Curation is AragonApp { require(!registry.exists(entryId)); // check locked tokens - uint256 amount = _checkLock(lockId, MAX_UINT64); + uint256 amount = _checkLock(msg.sender, lockId, MAX_UINT64); applications[entryId] = Application({ applicant: msg.sender, @@ -119,7 +119,7 @@ contract Curation is AragonApp { // check application doesn't have an ongoing challenge require(!challengeExists(entryId)); // check locked tokens - uint256 amount = _checkLock(lockId, getTimestamp().add(applyStageLen)); + uint256 amount = _checkLock(msg.sender, lockId, getTimestamp().add(applyStageLen)); // touch-and-remove case Application memory application = applications[entryId]; @@ -189,7 +189,7 @@ contract Curation is AragonApp { application.registered = true; } // Remove applicant used lock - delete(usedLocks[application.lockId]); + delete(usedLocks[application.applicant][application.lockId]); // Unlock challenger tokens from Staking app reward = challenge.amount.mul(dispensationPct) / PCT_BASE; // Redistribute tokens @@ -202,7 +202,7 @@ contract Curation is AragonApp { application.registered = false; } // Remove challenger used lock - delete(usedLocks[challenge.lockId]); + delete(usedLocks[challenge.challenger][challenge.lockId]); // Unlock applicant tokens from Staking app reward = application.amount.mul(dispensationPct) / PCT_BASE; // Redistribute tokens @@ -250,7 +250,7 @@ contract Curation is AragonApp { uint256 amount; (amount, ) = staking.getLock(loser, loserLockId); if (amount == 0) { // TODO: with truncating, this may never happen!! - delete(usedLocks[loserLockId]); + delete(usedLocks[loser][loserLockId]); // Remove application, if it lost, as redistribution is done if (voteResult == true) { delete(applications[entryId]); @@ -357,9 +357,9 @@ contract Curation is AragonApp { ); } - function _checkLock(uint256 lockId, uint64 date) internal returns (uint256) { + function _checkLock(address user, uint256 lockId, uint64 date) internal returns (uint256) { // check lockId was not used before - require(!usedLocks[lockId]); + require(!usedLocks[user][lockId]); // get the lock uint256 amount; uint8 lockUnit; @@ -375,7 +375,7 @@ contract Curation is AragonApp { require(lockEnds >= date); // mark it as used - usedLocks[lockId] = true; + usedLocks[user][lockId] = true; return amount; } diff --git a/test/curation.js b/test/curation.js index 9772a0c..8589847 100644 --- a/test/curation.js +++ b/test/curation.js @@ -213,11 +213,13 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const entryId = await createApplication() // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + // use challenger's lock for an application + await curation.newApplication("test 2", appLockId, { from: challenger }) // mock vote Id await voting.setVoteId(voteId) return assertRevert(async () => { - // challenge - await curation.challengeApplication(entryId, appLockId) + // challenge, using the same lock as for the application + await curation.challengeApplication(entryId, appLockId, { from: challenger }) }) }) @@ -332,8 +334,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) // used locks - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isFalse(appUsedLock) assert.isTrue(challengeUsedLock) }) @@ -355,8 +357,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) // used locks - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isTrue(appUsedLock) assert.isFalse(challengeUsedLock) }) @@ -403,8 +405,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) // used locks - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isFalse(appUsedLock) assert.isTrue(challengeUsedLock) }) @@ -426,8 +428,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) // used locks - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isTrue(appUsedLock) assert.isFalse(challengeUsedLock) }) @@ -499,8 +501,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // checks assert.isTrue(checkMovedTokens(receipt, challenger, voter, reward), "Reward should be payed") - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isFalse(appUsedLock, "app lock should have been freed") assert.isFalse(challengeUsedLock, "challenge lock should have been freed") }) @@ -512,8 +514,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") const application = await curation.getApplication.call(entryId) assert.equal(application[0], zeroAddress, "Application should be empty") - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isFalse(appUsedLock) assert.isFalse(challengeUsedLock) }) diff --git a/test/mocks/CurationMock.sol b/test/mocks/CurationMock.sol index 0c66561..0ce5289 100644 --- a/test/mocks/CurationMock.sol +++ b/test/mocks/CurationMock.sol @@ -22,7 +22,7 @@ contract CurationMock is Curation { return _mockTime; } - function getUsedLock(uint256 lockId) view public returns (bool) { - return usedLocks[lockId]; + function getUsedLock(address user, uint256 lockId) view public returns (bool) { + return usedLocks[user][lockId]; } } diff --git a/test/script.js b/test/script.js index 296cabe..74bf4c8 100644 --- a/test/script.js +++ b/test/script.js @@ -127,8 +127,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) // used locks - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) assert.isFalse(appUsedLock) assert.isTrue(challengeUsedLock) }) @@ -149,8 +149,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) // used locks - const appUsedLock = await curation.getUsedLock.call(appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challengeLockId) + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + const challengeUsedLock = await curation.getUsedLock.call(challenger,challengeLockId) assert.isTrue(appUsedLock) assert.isFalse(challengeUsedLock) }) From 0cc46976d8afe128400e3cc211ebc2b00f17b85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 10 Jul 2018 17:55:50 +0200 Subject: [PATCH 17/22] Fix bug computing reward Challenge amount was always being used. Although it's usually going to be the same (min deposit), it was not correct. --- contracts/Curation.sol | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 16c8e57..2cbce58 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -188,7 +188,7 @@ contract Curation is AragonApp { registry.add(application.data); application.registered = true; } - // Remove applicant used lock + // Remove applicant (winner) used lock delete(usedLocks[application.applicant][application.lockId]); // Unlock challenger tokens from Staking app reward = challenge.amount.mul(dispensationPct) / PCT_BASE; @@ -201,7 +201,7 @@ contract Curation is AragonApp { registry.remove(entryId); application.registered = false; } - // Remove challenger used lock + // Remove challenger (winner) used lock delete(usedLocks[challenge.challenger][challenge.lockId]); // Unlock applicant tokens from Staking app reward = application.amount.mul(dispensationPct) / PCT_BASE; @@ -230,26 +230,29 @@ contract Curation is AragonApp { address loser; uint256 loserLockId; + uint256 amount; if (voteResult == false) { loser = challenge.challenger; loserLockId = challenge.lockId; + amount = challenge.amount; } else { // voteResult == true loser = application.applicant; loserLockId = application.lockId; + amount = application.amount; } // reward as a voter uint256 voterWinningStake = voting.getVoterWinningStake(challenge.voteId, msg.sender); require(voterWinningStake > 0); // amount * (voter / total) * (1 - dispensationPct) - uint256 reward = challenge.amount.mul(voterWinningStake).mul(PCT_BASE.sub(dispensationPct)) / (totalWinningStake * PCT_BASE); + uint256 reward = amount.mul(voterWinningStake).mul(PCT_BASE.sub(dispensationPct)) / (totalWinningStake * PCT_BASE); // Redistribute tokens staking.unlockAndMoveTokens(loser, loserLockId, msg.sender, reward); // check if lock can be released - uint256 amount; - (amount, ) = staking.getLock(loser, loserLockId); - if (amount == 0) { // TODO: with truncating, this may never happen!! + uint256 remainingLockAmount; + (remainingLockAmount, ) = staking.getLock(loser, loserLockId); + if (remainingLockAmount == 0) { // TODO: with truncating, this may never happen!! delete(usedLocks[loser][loserLockId]); // Remove application, if it lost, as redistribution is done if (voteResult == true) { From 7d9be49be392909c2f26fa0f6a233aba85ed4cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Fri, 13 Jul 2018 20:02:22 +0200 Subject: [PATCH 18/22] Address PR #13 comments Fixes #12 too. --- contracts/Curation.sol | 215 +++++++++++++++++++++---------------- package.json | 1 + test/curation.js | 211 ++++++++++++++++++------------------ test/helpers.js | 26 +++++ test/mocks/StakingMock.sol | 7 +- test/script.js | 27 ++--- 6 files changed, 268 insertions(+), 219 deletions(-) create mode 100644 test/helpers.js diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 2cbce58..ff041ca 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -45,21 +45,28 @@ contract Curation is AragonApp { struct Challenge { address challenger; uint64 date; - bool resolved; uint256 amount; uint256 lockId; uint256 voteId; uint256 dispensationPct; + } + + struct Vote { + bool closed; + bool result; + uint256 votersRewardPool; + uint256 totalWinningStake; mapping(address => bool) claims; // participants who already claimed their reward } mapping(bytes32 => Application) applications; mapping(bytes32 => Challenge) challenges; + mapping(uint256 => Vote) votes; mapping(address => mapping(uint256 => bool)) usedLocks; - event NewApplication(bytes32 entryId, address applicant); - event NewChallenge(bytes32 entryId, address challenger); - event ResolvedChallenge(bytes32 entryId, bool result); + event NewApplication(bytes32 indexed entryId, address applicant); + event NewChallenge(bytes32 indexed entryId, address challenger); + event ResolvedChallenge(bytes32 indexed entryId, bool result); /** * @notice Initializes Curation app with @@ -118,158 +125,168 @@ contract Curation is AragonApp { function challengeApplication(bytes32 entryId, uint256 lockId) isInitialized public returns(bytes32) { // check application doesn't have an ongoing challenge require(!challengeExists(entryId)); - // check locked tokens - uint256 amount = _checkLock(msg.sender, lockId, getTimestamp().add(applyStageLen)); // touch-and-remove case Application memory application = applications[entryId]; if (application.amount < minDeposit) { - registry.remove(entryId); staking.unlock(application.applicant, application.lockId); - staking.unlock(msg.sender, lockId); + delete(applications[entryId]); + registry.remove(entryId); return 0; } + // check locked tokens + uint256 amount = _checkLock(msg.sender, lockId, getTimestamp().add(applyStageLen)); + // create vote // TODO: metadata // script to call `resolveChallenge(entryId)` uint256 scriptLength = 64; // 4 (spec) + 20 (address) + 4 (calldataLength) + 4 (signature) + 32 (input) bytes4 spec = bytes4(0x01); - address target = address(this); - bytes memory targetBytes = new bytes(32); bytes4 calldataLength = bytes4(0x24); // 4 + 32 bytes4 signature = this.resolveChallenge.selector; bytes memory executionScript = new bytes(scriptLength); // concatenate spec + address(this) + calldataLength + calldata - // TODO: should we put this somewhere in aragonOS to be able ti reuse? (if it's not already there) + // TODO: should we put this somewhere in aragonOS to be able to reuse it? (if it's not already there) assembly { mstore(add(executionScript, 0x20), spec) - mstore(add(targetBytes, 0x20), target) - mstore(add(executionScript, 0x24), mload(add(targetBytes, 0x2C))) + mstore(add(executionScript, 0x24), mul(address, exp(2,96))) mstore(add(executionScript, 0x38), calldataLength) mstore(add(executionScript, 0x3C), signature) mstore(add(executionScript, 0x40), entryId) } + uint256 voteId = voting.newVote(executionScript, ""); challenges[entryId] = Challenge({ challenger: msg.sender, date: getTimestamp(), - resolved: false, amount: amount, lockId: lockId, voteId: voteId, dispensationPct: dispensationPct }); + votes[voteId] = Vote({ + closed: false, + result: false, + totalWinningStake: 0, + votersRewardPool: 0 + }); + NewChallenge(entryId, msg.sender); return entryId; } function resolveChallenge(bytes32 entryId) isInitialized public { + require(challengeExists(entryId)); Challenge storage challenge = challenges[entryId]; Application storage application = applications[entryId]; + Vote storage vote = votes[challenge.voteId]; - require(!challenge.resolved); - // to avoid resolving and redistributing twice - challenge.resolved = true; - // TODO: canExecute?? require(voting.isClosed(challenge.voteId)); + vote.closed = true; + (vote.result, vote.totalWinningStake,) = voting.getVoteResult(challenge.voteId); - bool voteResult; - (voteResult,,) = voting.getVoteResult(challenge.voteId); + address winner; + address loser; + uint256 loserLockId; + uint256 amount; + if (vote.result == false) { // challenge not accepted (application remains) + winner = application.applicant; + loser = challenge.challenger; + loserLockId = challenge.lockId; + amount = challenge.amount; - uint256 reward; - if (voteResult == false) { // challenge not accepted (application remains) // it's still in application phase (not registered yet) if (!application.registered) { + application.registered = true; // insert in Registry app registry.add(application.data); - application.registered = true; } - // Remove applicant (winner) used lock - delete(usedLocks[application.applicant][application.lockId]); - // Unlock challenger tokens from Staking app - reward = challenge.amount.mul(dispensationPct) / PCT_BASE; - // Redistribute tokens - staking.unlockAndMoveTokens(challenge.challenger, challenge.lockId, application.applicant, reward); } else { // challenge accepted (application rejected) - // it has been already registered - if (application.registered) { - // remove from Registry app - registry.remove(entryId); - application.registered = false; - } - // Remove challenger (winner) used lock - delete(usedLocks[challenge.challenger][challenge.lockId]); - // Unlock applicant tokens from Staking app - reward = application.amount.mul(dispensationPct) / PCT_BASE; - // Redistribute tokens - staking.unlockAndMoveTokens(application.applicant, application.lockId, challenge.challenger, reward); + winner = challenge.challenger; + loser = application.applicant; + loserLockId = application.lockId; + amount = application.amount; + + // Remove from Registry app + application.registered = false; + registry.remove(entryId); + } + // compute rewards + uint256 reward = amount.mul(dispensationPct) / PCT_BASE; + vote.votersRewardPool = amount - reward; + + // unlock tokens from Staking app + staking.unlock(application.applicant, application.lockId); + staking.unlock(challenge.challenger, challenge.lockId); + + // redistribute tokens + staking.moveTokens(loser, winner, reward); + staking.moveTokens(loser, address(this), vote.votersRewardPool); + + // Remove used locks + delete(usedLocks[application.applicant][application.lockId]); + delete(usedLocks[challenge.challenger][challenge.lockId]); + + // Remove challenge, and application if needed + if (vote.result == true) { + delete(applications[entryId]); } + delete(challenges[entryId]); - ResolvedChallenge(entryId, voteResult); + ResolvedChallenge(entryId, vote.result); } - function claimReward(bytes32 entryId) isInitialized public { - require(isChallengeResolved(entryId)); + function claimReward(uint256 voteId) isInitialized public { + require(votes[voteId].closed); - Challenge storage challenge = challenges[entryId]; - Application memory application = applications[entryId]; + Vote storage vote = votes[voteId]; // avoid claiming twice - require(!challenge.claims[msg.sender]); + require(!vote.claims[msg.sender]); // register claim to avoid claiming it again - challenge.claims[msg.sender] = true; - - bool voteResult; - uint256 totalWinningStake; - (voteResult, totalWinningStake,) = voting.getVoteResult(challenge.voteId); - - address loser; - uint256 loserLockId; - uint256 amount; - if (voteResult == false) { - loser = challenge.challenger; - loserLockId = challenge.lockId; - amount = challenge.amount; - } else { // voteResult == true - loser = application.applicant; - loserLockId = application.lockId; - amount = application.amount; - } + vote.claims[msg.sender] = true; // reward as a voter - uint256 voterWinningStake = voting.getVoterWinningStake(challenge.voteId, msg.sender); + uint256 voterWinningStake = voting.getVoterWinningStake(voteId, msg.sender); require(voterWinningStake > 0); - // amount * (voter / total) * (1 - dispensationPct) - uint256 reward = amount.mul(voterWinningStake).mul(PCT_BASE.sub(dispensationPct)) / (totalWinningStake * PCT_BASE); + // rewardPool * (voter / total) + uint256 reward = vote.votersRewardPool.mul(voterWinningStake) / vote.totalWinningStake; // Redistribute tokens - staking.unlockAndMoveTokens(loser, loserLockId, msg.sender, reward); - - // check if lock can be released - uint256 remainingLockAmount; - (remainingLockAmount, ) = staking.getLock(loser, loserLockId); - if (remainingLockAmount == 0) { // TODO: with truncating, this may never happen!! - delete(usedLocks[loser][loserLockId]); - // Remove application, if it lost, as redistribution is done - if (voteResult == true) { - delete(applications[entryId]); - } - } + staking.moveTokens(address(this), msg.sender, reward); } - function registerApplication(bytes32 entryId) isInitialized public { + function registerUnchallengedApplication(bytes32 entryId) isInitialized public { require(canBeRegistered(entryId)); Application storage application = applications[entryId]; require(!application.registered); + application.registered = true; // insert in Registry app registry.add(application.data); - application.registered = true; + } + + function removeApplication(bytes32 entryId) isInitialized public { + // check application doesn't have an ongoing challenge + require(!challengeExists(entryId)); + + Application memory application = applications[entryId]; + // check sender is owner + require(application.applicant == msg.sender); + + // unlock applicant lock + staking.unlock(application.applicant, application.lockId); + // remove applicant used lock + delete(usedLocks[application.applicant][application.lockId]); + // delete application + delete(applications[entryId]); + // remove from registry + registry.remove(entryId); } function setVotingApp(IVoting _voting) authP(CHANGE_VOTING_APP_ROLE, arr(voting, _voting)) public { @@ -294,9 +311,8 @@ contract Curation is AragonApp { } function canBeRegistered(bytes32 entryId) view public returns (bool) { - // no challenges if (getTimestamp() > applications[entryId].date.add(applyStageLen) && - challenges[entryId].challenger == address(0)) + !challengeExists(entryId)) { return true; } @@ -304,10 +320,6 @@ contract Curation is AragonApp { return false; } - function isChallengeResolved(bytes32 entryId) view public returns (bool) { - return challenges[entryId].resolved; - } - function getApplication( bytes32 entryId ) @@ -341,7 +353,6 @@ contract Curation is AragonApp { returns ( address challenger, uint64 date, - bool resolved, uint256 amount, uint256 lockId, uint256 voteId, @@ -352,7 +363,6 @@ contract Curation is AragonApp { return ( challenge.challenger, challenge.date, - challenge.resolved, challenge.amount, challenge.lockId, challenge.voteId, @@ -360,15 +370,36 @@ contract Curation is AragonApp { ); } + function getVote( + uint256 voteId + ) + view + public + returns ( + bool closed, + bool result, + uint256 totalWinningStake, + uint256 votersRewardPool + ) + { + Vote memory vote = votes[voteId]; + return ( + vote.closed, + vote.result, + vote.totalWinningStake, + vote.votersRewardPool + ); + } + function _checkLock(address user, uint256 lockId, uint64 date) internal returns (uint256) { - // check lockId was not used before - require(!usedLocks[user][lockId]); // get the lock uint256 amount; uint8 lockUnit; uint64 lockEnds; address unlocker; (amount, lockUnit, lockEnds, unlocker, ) = staking.getLock(msg.sender, lockId); + // check lockId was not used before + require(!usedLocks[user][lockId]); // check unlocker require(unlocker == address(this)); // check enough amount diff --git a/package.json b/package.json index 645b7eb..728f5b8 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "homepage": "https://github.com/aragonlabs/curation#readme", "devDependencies": { "@aragon/apps-registry": "^1.0.0", + "@aragon/apps-staking": "^1.0.0", "@aragon/test-helpers": "^1.0.0", "eth-gas-reporter": "^0.1.5", "ganache-cli": "^6.1.0", diff --git a/test/curation.js b/test/curation.js index 8589847..7bf3fd6 100644 --- a/test/curation.js +++ b/test/curation.js @@ -1,5 +1,7 @@ const { assertRevert } = require('@aragon/test-helpers/assertThrow') +const { checkUnlocked, checkMovedTokens } = require('./helpers.js') + const getContract = name => artifacts.require(name) const getEvent = (receipt, event, arg) => { return receipt.logs.filter(l => l.event == event)[0].args[arg] } const pct16 = x => new web3.BigNumber(x).times(new web3.BigNumber(10).toPower(16)) @@ -17,6 +19,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const TIME_UNIT_BLOCKS = 0 const TIME_UNIT_SECONDS = 1 + context('Regular App', async () => { const appLockId = 1 const challengeLockId = 2 @@ -27,6 +30,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { registry = await getContract('RegistryApp').new() staking = await getContract('StakingMock').new() voting = await getContract('VotingMock').new() + await voting.setVoteId(voteId) curation = await getContract('CurationMock').new() MAX_UINT64 = await curation.MAX_UINT64() @@ -181,11 +185,16 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const challenge = await curation.getChallenge.call(entryId) assert.equal(challenge[0], challenger, "Challenger should match") //assert.equal(challenge[1], , "Date should match") - assert.equal(challenge[2], false, "Resolved bool should match") - assert.equal(challenge[3], minDeposit, "Amount should match") - assert.equal(challenge[4], challengeLockId, "LockId should match") - assert.equal(challenge[5], voteId, "Vote Id should match") - assert.equal(challenge[6].toString(), dispensationPct.toString(), "Dipsensation Pct should match") + assert.equal(challenge[2], minDeposit, "Amount should match") + assert.equal(challenge[3], challengeLockId, "LockId should match") + assert.equal(challenge[4], voteId, "Vote Id should match") + assert.equal(challenge[5].toString(), dispensationPct.toString(), "Dispensation Pct should match") + // vote + const vote = await curation.getVote.call(entryId) + assert.equal(vote[0], false, "Closed bool should match") + assert.equal(vote[1], false, "Result bool should match") + assert.equal(vote[2], 0, "Total winning stake Pct should match") + assert.equal(vote[3], 0, "Voters reward pool Pct should match") }) it('challenges touch-and-remove application', async () => { @@ -194,19 +203,18 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // increase minDeposit await curation.setMinDeposit(minDeposit + 1) - // mock lock - await staking.setLock(minDeposit + 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + // mock lock - no need for lock + await staking.setLock(0, TIME_UNIT_SECONDS, 0, zeroAddress, "") // challenge - await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) - const challenge = await curation.getChallenge.call(entryId) + const receipt = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) // no challenge has been created - assert.equal(challenge[0], zeroAddress, "Challenger should be zero") - assert.equal(challenge[1], 0, "Date should be zero") - assert.equal(challenge[2], false, "Resolved should be false") - assert.equal(challenge[3], 0, "Amount should be zero") - assert.equal(challenge[4], 0, "LockId should be zero") - assert.equal(challenge[5], 0, "Vote Id should be zero") - assert.equal(challenge[6], 0, "Dipsensation Pct should be zero") + const challenge = await curation.getChallenge.call(entryId) + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") + // application has been removed + const application = await curation.getApplication.call(entryId) + assert.equal(application[0], zeroAddress, "Applicant should be empty") + // applicant lock has been unlocked + assert.isTrue(checkUnlocked(receipt, applicant, curation.address, appLockId), "Applicant lock should have been unlocked") }) it('fails challenging with an already used lock', async () => { @@ -282,31 +290,6 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // ----------- Resolve challenges -------------- - // checks if a log for moving tokens was generated with the given params - // if amount is 0, it will check for any - /* this doesn't work, only shows called contract logs - const checkMovedTokens = (receipt, from, to, amount) => { - const logs = receipt.logs.filter( - l => - l.event == 'MovedTokens' && - l.args['from'] == from && - l.args['to'] == to && - (l.args['amount'] == amount || amount == 0) - ) - return logs.length == 1 || (amount == 0 && logs.length >= 1) - } - */ - const checkMovedTokens = (receipt, from, to, amount) => { - const logs = receipt.receipt.logs.filter( - l => - l.topics[0] == web3.sha3('MovedTokens(address,address,uint256)') && - '0x' + l.topics[1].slice(26) == from && - '0x' + l.topics[2].slice(26) == to && - (web3.toDecimal(l.data) == amount || amount == 0) - ) - return logs.length == 1 || (amount == 0 && logs.length >= 1) - } - const applyChallengeAndResolve = async (result) => { const entryId = await applyAndChallenge() // mock vote result @@ -328,7 +311,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isTrue(application[2], "Registered should be true") // challenge const challenge = await curation.getChallenge.call(entryId) - assert.isTrue(challenge[2], "Resolved should be true") + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) @@ -336,8 +319,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // used locks const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isFalse(appUsedLock) - assert.isTrue(challengeUsedLock) + assert.isFalse(appUsedLock, "There should be no lock for application") + assert.isFalse(challengeUsedLock, "There should be no lock for challenge") }) it('resolves application challenge, accepted', async () => { @@ -348,19 +331,23 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(await registry.exists(data), "Data should not have been registered") // application const application = await curation.getApplication.call(entryId) - assert.isFalse(application[2], "Registered should be false") + assert.equal(application[0], zeroAddress, "Application should be empty") // challenge const challenge = await curation.getChallenge.call(entryId) - assert.isTrue(challenge[2], "Resolved should be true") + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) - assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) - assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) + const votersRewardPool = new web3.BigNumber(minDeposit).minus(amount) + assert.isTrue(checkUnlocked(receipt, applicant, curation.address, appLockId), "Applicant lock should have been unlocked") + assert.isTrue(checkUnlocked(receipt, challenger, curation.address, challengeLockId), "Challenger lock should have been unlocked") + assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0), "No challenger tokens should have been moved") + assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount), "Applicant tokens should have been moved to challenger") + assert.isTrue(checkMovedTokens(receipt, applicant, curation.address, votersRewardPool), "Applicant tokens should have been moved to Curation app") // used locks const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isTrue(appUsedLock) - assert.isFalse(challengeUsedLock) + assert.isFalse(appUsedLock, "There should be no lock for application") + assert.isFalse(challengeUsedLock, "There should be no lock for challenge") }) const applyRegisterChallengeAndResolve = async (result) => { @@ -369,7 +356,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await curation.addTime(applyStageLen + 1) // register - await curation.registerApplication(entryId) + await curation.registerUnchallengedApplication(entryId) // mock lock await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") @@ -399,16 +386,20 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isTrue(application[2], "Registered should be true") // challenge const challenge = await curation.getChallenge.call(entryId) - assert.isTrue(challenge[2], "Resolved should be true") + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) - assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) - assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount)) + const votersRewardPool = new web3.BigNumber(minDeposit).minus(amount) + assert.isTrue(checkUnlocked(receipt, applicant, curation.address, appLockId), "Applicant lock should have been unlocked") + assert.isTrue(checkUnlocked(receipt, challenger, curation.address, challengeLockId), "Challenger lock should have been unlocked") + assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0), "No Applicant tokens should have been moved") + assert.isTrue(checkMovedTokens(receipt, challenger, applicant, amount), "Challenger tokens should have been moved to Applicant") + assert.isTrue(checkMovedTokens(receipt, challenger, curation.address, votersRewardPool), "Challenger tokens should have been moved to Curation app") // used locks const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isFalse(appUsedLock) - assert.isTrue(challengeUsedLock) + assert.isFalse(appUsedLock, "There should be no lock for application") + assert.isFalse(challengeUsedLock, "There should be no lock for challenge") }) it('resolves registry challenge, accepted', async () => { @@ -419,19 +410,19 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(await registry.exists(data), "Data should have been removed from register") // application const application = await curation.getApplication.call(entryId) - assert.isFalse(application[2], "Registered should be false") + assert.equal(application[0], zeroAddress, "Application should be empty") // challenge const challenge = await curation.getChallenge.call(entryId) - assert.isTrue(challenge[2], "Resolved should be true") + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) - assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) - assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount)) + assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0), "challenger tokens should have been moved") + assert.isTrue(checkMovedTokens(receipt, applicant, challenger, amount, "applicant tokens should have been moved")) // used locks const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isTrue(appUsedLock) - assert.isFalse(challengeUsedLock) + assert.isFalse(appUsedLock, "There should be no lock for application") + assert.isFalse(challengeUsedLock, "There should be no lock for challenge") }) it('fails resolving challenge if vote has not ended', async () => { @@ -463,17 +454,12 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // ----------- Claim rewards -------------- - const claimReward = async (result, lastClaim=false) => { + const claimReward = async (result) => { const {entryId} = await applyChallengeAndResolve(result) await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) - if (lastClaim) { - // mock Staking to pretend losing party tokens were already distributed - await staking.setLock(0, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") - } - // claim reward - const receipt = await curation.claimReward(entryId, { from: voter }) + const receipt = await curation.claimReward(voteId, { from: voter }) const reward = new web3.BigNumber(minDeposit).mul(VOTER_WINNING_STAKE).mul(1e18 - dispensationPct).dividedToIntegerBy(WINNING_STAKE).dividedToIntegerBy(1e18) return { entryId: entryId, @@ -484,55 +470,29 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('claims reward as voter in the winning party', async () => { const {receipt, reward} = await claimReward(true) - assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") + assert.isTrue(checkMovedTokens(receipt, curation.address, voter, reward), "Reward should be payed") }) it('fails claiming reward if not voter in the winning party', async () => { const {entryId} = await applyChallengeAndResolve(true) await voting.setVoterWinningStake(voter, 0) return assertRevert(async () => { - await curation.claimReward(entryId, { from: voter }) + await curation.claimReward(voteId, { from: voter }) }) }) - it('claims reward and lock can be released, challenge rejected', async () => { - const {receipt, reward} = await claimReward(false, true) - - // checks - assert.isTrue(checkMovedTokens(receipt, challenger, voter, reward), "Reward should be payed") - const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isFalse(appUsedLock, "app lock should have been freed") - assert.isFalse(challengeUsedLock, "challenge lock should have been freed") - }) - - it('claims reward and lock can be released, challenge accepted', async () => { - const {entryId, receipt, reward} = await claimReward(true, true) - - // checks - assert.isTrue(checkMovedTokens(receipt, applicant, voter, reward), "Reward should be payed") - const application = await curation.getApplication.call(entryId) - assert.equal(application[0], zeroAddress, "Application should be empty") - const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) - const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isFalse(appUsedLock) - assert.isFalse(challengeUsedLock) - }) - it('fails claiming reward if challenge is not resolved', async () => { const entryId = await applyAndChallenge() return assertRevert(async () => { - await curation.claimReward(entryId, { from: challenger }) + await curation.claimReward(voteId, { from: challenger }) }) }) it('fails claiming a reward twice', async () => { - const {entryId} = await applyChallengeAndResolve(true) - await voting.setVoterWinningStake(voter, VOTER_WINNING_STAKE) - await curation.claimReward(entryId, { from: voter }) + const {entryId} = await claimReward(true) return assertRevert(async () => { - await curation.claimReward(entryId, { from: voter }) + await curation.claimReward(voteId, { from: voter }) }) }) @@ -545,7 +505,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await curation.addTime(applyStageLen + 1) // register - await curation.registerApplication(entryId) + await curation.registerUnchallengedApplication(entryId) // checks // registry @@ -564,7 +524,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // register return assertRevert(async () => { - await curation.registerApplication(entryId) + await curation.registerUnchallengedApplication(entryId) }) }) @@ -583,7 +543,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // register return assertRevert(async () => { - await curation.registerApplication(entryId) + await curation.registerUnchallengedApplication(entryId) }) }) @@ -594,10 +554,38 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await curation.addTime(applyStageLen + 1) // register - await curation.registerApplication(entryId) + await curation.registerUnchallengedApplication(entryId) + + return assertRevert(async () => { + await curation.registerUnchallengedApplication(entryId) + }) + }) + + // ----------- Remove application by applicant -------------- + it('removes application', async () => { + const entryId = await createApplication() + + const receipt = await curation.removeApplication(entryId, { from: applicant }) + // tokens have been unlocked + assert.isTrue(checkUnlocked(receipt, applicant, curation.address, appLockId), "Applicant lock in Staking app should have been unlocked") + // used lock has been removed + const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) + assert.isFalse(appUsedLock, "Applicant used lock should have been freed") + }) + + it('fails removing application with an ongoing challenge', async () => { + const entryId = await applyAndChallenge() + + return assertRevert(async () => { + await curation.removeApplication(entryId) + }) + }) + + it('fails removing application by non-applicant', async () => { + const entryId = await createApplication() return assertRevert(async () => { - await curation.registerApplication(entryId) + await curation.removeApplication(entryId, { from: challenger }) }) }) @@ -642,10 +630,12 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { }) context('Without init', async () => { + const voteId = 1 beforeEach(async () => { registry = await getContract('RegistryApp').new() staking = await getContract('StakingMock').new() voting = await getContract('VotingMock').new() + await voting.setVoteId(voteId) curation = await getContract('Curation').new() }) @@ -677,14 +667,21 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails registering an application', async () => { return assertRevert(async () => { const entryId = 1 - await curation.registerApplication(entryId) + await curation.registerUnchallengedApplication(entryId) }) }) it('fails claiming reward', async () => { return assertRevert(async () => { const entryId = 1 - await curation.claimReward(entryId) + await curation.claimReward(voteId) + }) + }) + + it('fails trying to remove entry', async () => { + return assertRevert(async () => { + const entryId = 1 + await curation.removeApplication(entryId) }) }) diff --git a/test/helpers.js b/test/helpers.js new file mode 100644 index 0000000..77e0199 --- /dev/null +++ b/test/helpers.js @@ -0,0 +1,26 @@ +module.exports = { + // checks if a log for unlocking tokens was generated with the given params + checkUnlocked: (receipt, account, unlocker, lockId) => { + const logs = receipt.receipt.logs.filter( + l => + l.topics[0] == web3.sha3('Unlocked(address,address,uint256)') && + '0x' + l.topics[1].slice(26) == account && + '0x' + l.topics[2].slice(26) == unlocker && + web3.toDecimal(l.data) == lockId + ) + return logs.length == 1 + }, + + // checks if a log for moving tokens was generated with the given params + // if amount is 0, it will check for any + checkMovedTokens: (receipt, from, to, amount) => { + const logs = receipt.receipt.logs.filter( + l => + l.topics[0] == web3.sha3('MovedTokens(address,address,uint256)') && + '0x' + l.topics[1].slice(26) == from && + '0x' + l.topics[2].slice(26) == to && + (web3.toDecimal(l.data) == amount || amount == 0) + ) + return logs.length == 1 || (amount == 0 && logs.length >= 1) + } +} diff --git a/test/mocks/StakingMock.sol b/test/mocks/StakingMock.sol index 6835b83..c4ca63a 100644 --- a/test/mocks/StakingMock.sol +++ b/test/mocks/StakingMock.sol @@ -10,6 +10,8 @@ contract StakingMock is IStaking { address unlocker; bytes32 metadata; + event Unlocked(address indexed account, address indexed unlocker, uint256 oldLockId); + event UnlockedPartial(address indexed account, address indexed unlocker, uint256 indexed lockId, uint256 amount); event MovedTokens(address indexed from, address indexed to, uint256 amount); function setLock(uint256 _amount, uint8 _lockUnit, uint64 _lockEnds, address _unlocker, bytes32 _metadata) public { @@ -20,14 +22,15 @@ contract StakingMock is IStaking { } function unlock(address acct, uint256 lockId) public { - // do nothing + Unlocked(acct, msg.sender, lockId); } function moveTokens(address _from, address _to, uint256 _amount) public { MovedTokens(_from, _to, _amount); } - function unlockAndMoveTokens(address _from, uint256 _lockId, address _to, uint256 _amount) external { + function unlockPartialAndMoveTokens(address _from, uint256 _lockId, address _to, uint256 _amount) external { + UnlockedPartial(_from, msg.sender, _lockId, amount); MovedTokens(_from, _to, _amount); } diff --git a/test/script.js b/test/script.js index 74bf4c8..da40527 100644 --- a/test/script.js +++ b/test/script.js @@ -1,5 +1,7 @@ const { assertRevert } = require('@aragon/test-helpers/assertThrow') +const { checkMovedTokens } = require('./helpers.js') + const getContract = name => artifacts.require(name) const getEvent = (receipt, event, arg) => { return receipt.logs.filter(l => l.event == event)[0].args[arg] } const pct16 = x => new web3.BigNumber(x).times(new web3.BigNumber(10).toPower(16)) @@ -67,17 +69,6 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { return { entryId: entryId, receipt: receipt } } - const checkMovedTokens = (receipt, from, to, amount) => { - const logs = receipt.receipt.logs.filter( - l => - l.topics[0] == web3.sha3('MovedTokens(address,address,uint256)') && - '0x' + l.topics[1].slice(26) == from && - '0x' + l.topics[2].slice(26) == to && - (web3.toDecimal(l.data) == amount || amount == 0) - ) - return logs.length == 1 || (amount == 0 && logs.length >= 1) - } - context('Using voting script', async () => { let daoFact @@ -121,7 +112,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isTrue(application[2], "Registered should be true") // challenge const challenge = await curation.getChallenge.call(entryId) - assert.isTrue(challenge[2], "Resolved should be true") + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) assert.isFalse(checkMovedTokens(receipt, applicant, challenger, 0)) @@ -129,8 +120,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // used locks const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) const challengeUsedLock = await curation.getUsedLock.call(challenger, challengeLockId) - assert.isFalse(appUsedLock) - assert.isTrue(challengeUsedLock) + assert.isFalse(appUsedLock, "There should be no lock for application") + assert.isFalse(challengeUsedLock, "There should be no lock for challenge") }) it('challenges application and executes, challenge accepted', async () => { @@ -140,10 +131,10 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { assert.isFalse(await registry.exists(data), "Data should not have been registered") // application const application = await curation.getApplication.call(entryId) - assert.isFalse(application[2], "Registered should be false") + assert.equal(application[0], zeroAddress, "Application should be empty") // challenge const challenge = await curation.getChallenge.call(entryId) - assert.isTrue(challenge[2], "Resolved should be true") + assert.equal(challenge[0], zeroAddress, "Challenge should be empty") // redistribution const amount = new web3.BigNumber(minDeposit).mul(dispensationPct).dividedToIntegerBy(1e18) assert.isFalse(checkMovedTokens(receipt, challenger, applicant, 0)) @@ -151,8 +142,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { // used locks const appUsedLock = await curation.getUsedLock.call(applicant, appLockId) const challengeUsedLock = await curation.getUsedLock.call(challenger,challengeLockId) - assert.isTrue(appUsedLock) - assert.isFalse(challengeUsedLock) + assert.isFalse(appUsedLock, "There should be no lock for application") + assert.isFalse(challengeUsedLock, "There should be no lock for challenge") }) }) }) From 6285b4e338c1e367cc5a03c6645fc3460e75555f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 17 Jul 2018 20:37:15 +0200 Subject: [PATCH 19/22] Remove external interfaces --- contracts/Curation.sol | 2 +- contracts/interfaces/IRegistry.sol | 16 ---------------- contracts/interfaces/IStaking.sol | 28 ---------------------------- 3 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 contracts/interfaces/IRegistry.sol delete mode 100644 contracts/interfaces/IStaking.sol diff --git a/contracts/Curation.sol b/contracts/Curation.sol index ff041ca..7be36a4 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -6,7 +6,7 @@ import "@aragon/os/contracts/lib/zeppelin/math/SafeMath.sol"; import "@aragon/os/contracts/lib/zeppelin/math/SafeMath64.sol"; import "@aragon/apps-staking/contracts/interfaces/IStaking.sol"; -import "./interfaces/IRegistry.sol"; +import "@aragon/apps-registry/contracts/interfaces/IRegistry.sol"; import "./interfaces/IVoting.sol"; diff --git a/contracts/interfaces/IRegistry.sol b/contracts/interfaces/IRegistry.sol deleted file mode 100644 index 99af3a4..0000000 --- a/contracts/interfaces/IRegistry.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma solidity ^0.4.18; - - -interface IRegistry { - function exists(bytes32 _id) public view returns (bool); - function add(bytes _data) public returns (bytes32 _id); - function remove(bytes32 _id) public; -} - - -contract FakeRegistry { - // to work around coverage issue - function fake() public { - // for lint - } -} diff --git a/contracts/interfaces/IStaking.sol b/contracts/interfaces/IStaking.sol deleted file mode 100644 index ccdc6ce..0000000 --- a/contracts/interfaces/IStaking.sol +++ /dev/null @@ -1,28 +0,0 @@ -pragma solidity ^0.4.18; - - -interface IStaking { - function unlock(address acct, uint256 lockId) public; - function unlockAndMoveTokens(address from, uint256 lockId, address to, uint256 amount) external; - function getLock( - address acct, - uint256 lockId - ) - public - view - returns ( - uint256 amount, - uint8 lockUnit, - uint64 lockEnds, - address unlocker, - bytes32 metadata - ); -} - - -contract FakeStaking { - // to work around coverage issue - function fake() public { - // for lint - } -} From 3e0a007ec37b2e030825e258e5c62fd885bfc1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Mon, 23 Jul 2018 20:22:24 +0200 Subject: [PATCH 20/22] Add function doc headers Closes #6. --- contracts/Curation.sol | 85 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 7be36a4..2c993ee 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -70,7 +70,12 @@ contract Curation is AragonApp { /** * @notice Initializes Curation app with - * @param _registry TODO + * @param _registry Registry app to be used for registering accepted entries + * @param _staking Staking app to be used for staking and locking tokens + * @param _voting Voting app to be used for Challenges + * @param _minDeposit Minimum amount of tokens needed for Applications and Challenges + * @param _applyStageLen Duration after which an application gets registered if it doesn't receive any challenge + * @param _dispensationPct Percentage of deposited tokens awarded to the winning party (applicant or challenger). The rest will be distributed among voters */ function initialize( IRegistry _registry, @@ -97,6 +102,12 @@ contract Curation is AragonApp { _setDispensationPct(_dispensationPct); } + /** + * @notice Submit new application for "`data`" using lock `lockId` + * @param data Content of the application + * @param lockId Id of the lock from Staking app used for the application + * @return Id of the new entry + */ function newApplication(bytes data, uint256 lockId) isInitialized public returns (bytes32 entryId) { entryId = keccak256(data); @@ -122,6 +133,12 @@ contract Curation is AragonApp { NewApplication(entryId, msg.sender); } + /** + * @notice Challenge application for entry with id `entryId` using lock wiht id `lockId` + * @param entryId Id of the application being challenged + * @param lockId Id of the lock from Staking app used for the application + * @return Id of the Challenge, which is the same as the Application one + */ function challengeApplication(bytes32 entryId, uint256 lockId) isInitialized public returns(bytes32) { // check application doesn't have an ongoing challenge require(!challengeExists(entryId)); @@ -179,6 +196,10 @@ contract Curation is AragonApp { return entryId; } + /** + * @notice Resolve Challenge for entry with id `entryId` + * @param entryId Id of the Application/Challenge + */ function resolveChallenge(bytes32 entryId) isInitialized public { require(challengeExists(entryId)); Challenge storage challenge = challenges[entryId]; @@ -240,6 +261,10 @@ contract Curation is AragonApp { ResolvedChallenge(entryId, vote.result); } + /** + * @notice Claim reward for a Challenge as a voter for vote with id `voteId` + * @param voteId Id of the Vote + */ function claimReward(uint256 voteId) isInitialized public { require(votes[voteId].closed); @@ -260,6 +285,10 @@ contract Curation is AragonApp { staking.moveTokens(address(this), msg.sender, reward); } + /** + * @notice Register unchallenged application with id `entryId` + * @param entryId Id of the Application + */ function registerUnchallengedApplication(bytes32 entryId) isInitialized public { require(canBeRegistered(entryId)); @@ -271,6 +300,10 @@ contract Curation is AragonApp { registry.add(application.data); } + /** + * @notice Remove Application with id `entryId` by applicant, and unlock deposit + * @param entryId Id of the Application + */ function removeApplication(bytes32 entryId) isInitialized public { // check application doesn't have an ongoing challenge require(!challengeExists(entryId)); @@ -289,18 +322,34 @@ contract Curation is AragonApp { registry.remove(entryId); } + /** + * @notice Set Voting app + * @param _voting New Voting app + */ function setVotingApp(IVoting _voting) authP(CHANGE_VOTING_APP_ROLE, arr(voting, _voting)) public { _setVotingApp(_voting); } + /** + * @notice Set minimum deposit for Applications and Challenges to `_minDeposit`. It's the minimum amount of tokens needed for Applications and Challenges. + * @param _minDeposit New minimum amount + */ function setMinDeposit(uint256 _minDeposit) authP(CHANGE_PARAMS_ROLE, arr(uint256(MIN_DEPOSIT_PARAM), _minDeposit)) public { _setMinDeposit(_minDeposit); } + /** + * @notice Set apply stage length for Applications to `_applyStageLen`. It's the duration after which an application gets registered if it doesn't receive any challenge + * @param _applyStageLen New apply stage length + */ function setApplyStageLen(uint64 _applyStageLen) authP(CHANGE_PARAMS_ROLE, arr(uint256(APPLY_STAGE_LEN_PARAM), _applyStageLen)) public { _setApplyStageLen(_applyStageLen); } + /** + * @notice Set dispensation percetage parameter for Applications and Challenges to `_dispensationPct`. It's the percentage of deposited tokens awarded to the winning party (applicant or challenger). The rest will be distributed among voters. + * @param _dispensationPct New dispensation percentage + */ function setDispensationPct(uint256 _dispensationPct) authP(CHANGE_PARAMS_ROLE, arr(uint256(DISPENSATION_PCT_PARAM), _dispensationPct)) public @@ -310,6 +359,10 @@ contract Curation is AragonApp { _setDispensationPct(_dispensationPct); } + /** + * @notice Check if application for entry with id `entryId` has gone through apply stage period without any challenge and therefore can be registered. + * @param entryId Id of the Application + */ function canBeRegistered(bytes32 entryId) view public returns (bool) { if (getTimestamp() > applications[entryId].date.add(applyStageLen) && !challengeExists(entryId)) @@ -320,6 +373,16 @@ contract Curation is AragonApp { return false; } + /** + * @notice Get Application details + * @param entryId Id of the Application + * @return applicant Address of applicant + * @return date Date of Application + * @return registered Whether has been already registered or not + * @return data Content of the Application + * @return amount Diposited (staked and locked) amount + * @return lockId Id of the lock for the deposit in Staking app + */ function getApplication( bytes32 entryId ) @@ -345,6 +408,16 @@ contract Curation is AragonApp { ); } + /** + * @notice Get Challenge details for entry with id `entryId` + * @param entryId Id of the Application + * @return challenger Address of challenger + * @return date Date of Challenge + * @return amount Diposited (staked and locked) amount + * @return lockId Id of the lock for the deposit in Staking app + * @return voteId Id of the Vote for the Challenge in Voting app + * @return dispensationPct Dispensation Percentage parameter at the time of challenging + */ function getChallenge( bytes32 entryId ) @@ -356,7 +429,7 @@ contract Curation is AragonApp { uint256 amount, uint256 lockId, uint256 voteId, - uint256 dipsensationPct + uint256 dispensationPct ) { Challenge memory challenge = challenges[entryId]; @@ -370,6 +443,14 @@ contract Curation is AragonApp { ); } + /** + * @notice Get Vote details for Vote with id `voteId` + * @param voteId Id of the Vote + * @return closed Wheter the Vote has been already closed or not + * @return result The result of the Vote + * @return totalWinningStake Amount of tokens on the winning side + * @return votersRewardPool The total amount that will be redistributed to the voters on the winning side. + */ function getVote( uint256 voteId ) From 9e179dcb7f85c6ada46de06025e4b17148180b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 24 Jul 2018 18:53:21 +0200 Subject: [PATCH 21/22] Adapt to last changes in Registry app Registry app must now be initialized. --- test/curation.js | 1 + test/script.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/curation.js b/test/curation.js index 7bf3fd6..271a33d 100644 --- a/test/curation.js +++ b/test/curation.js @@ -28,6 +28,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { beforeEach(async () => { registry = await getContract('RegistryApp').new() + await registry.initialize() staking = await getContract('StakingMock').new() voting = await getContract('VotingMock').new() await voting.setVoteId(voteId) diff --git a/test/script.js b/test/script.js index da40527..b0c5119 100644 --- a/test/script.js +++ b/test/script.js @@ -81,6 +81,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { beforeEach(async () => { registry = await getContract('RegistryApp').new() + await registry.initialize() staking = await getContract('StakingMock').new() // DAO From db8d13f281552fa76cafe6dd220279d0e28edf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Tue, 24 Jul 2018 18:54:28 +0200 Subject: [PATCH 22/22] Adapt to last changes in Staking app Locks now have start date too. --- contracts/Curation.sol | 12 +++++--- test/curation.js | 63 +++++++++++++++++++++++++------------- test/mocks/StakingMock.sol | 30 ++++++++++++++---- test/script.js | 6 ++-- 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/contracts/Curation.sol b/contracts/Curation.sol index 2c993ee..4d10427 100644 --- a/contracts/Curation.sol +++ b/contracts/Curation.sol @@ -118,7 +118,7 @@ contract Curation is AragonApp { require(!registry.exists(entryId)); // check locked tokens - uint256 amount = _checkLock(msg.sender, lockId, MAX_UINT64); + uint256 amount = _checkLock(msg.sender, lockId, getTimestamp(), MAX_UINT64); applications[entryId] = Application({ applicant: msg.sender, @@ -153,7 +153,7 @@ contract Curation is AragonApp { } // check locked tokens - uint256 amount = _checkLock(msg.sender, lockId, getTimestamp().add(applyStageLen)); + uint256 amount = _checkLock(msg.sender, lockId, getTimestamp(), getTimestamp().add(applyStageLen)); // create vote // TODO: metadata @@ -472,13 +472,14 @@ contract Curation is AragonApp { ); } - function _checkLock(address user, uint256 lockId, uint64 date) internal returns (uint256) { + function _checkLock(address user, uint256 lockId, uint64 startDate, uint64 endDate) internal returns (uint256) { // get the lock uint256 amount; uint8 lockUnit; + uint64 lockStarts; uint64 lockEnds; address unlocker; - (amount, lockUnit, lockEnds, unlocker, ) = staking.getLock(msg.sender, lockId); + (amount, lockUnit, lockStarts, lockEnds, unlocker, ) = staking.getLock(msg.sender, lockId); // check lockId was not used before require(!usedLocks[user][lockId]); // check unlocker @@ -487,7 +488,8 @@ contract Curation is AragonApp { require(amount >= minDeposit); // check time require(lockUnit == uint8(TimeUnit.Seconds)); - require(lockEnds >= date); + require(lockStarts <= startDate); + require(lockEnds >= endDate); // mark it as used usedLocks[user][lockId] = true; diff --git a/test/curation.js b/test/curation.js index 271a33d..98c0605 100644 --- a/test/curation.js +++ b/test/curation.js @@ -1,4 +1,5 @@ const { assertRevert } = require('@aragon/test-helpers/assertThrow') +const getTimestamp = async () => await web3.eth.getBlock(web3.eth.blockNumber).timestamp const { checkUnlocked, checkMovedTokens } = require('./helpers.js') @@ -57,7 +58,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const createApplication = async () => { // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") const r = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r, "NewApplication", "entryId") @@ -79,7 +81,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const data1 = "Test 1" const data2 = "Test 2" // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // create application await curation.newApplication(data1, appLockId, { from: applicant }) // repeat @@ -92,7 +95,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const lockId1 = 1 const lockId2 = 2 // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // create application await curation.newApplication(data, lockId1, { from: applicant }) // repeat @@ -105,7 +109,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const lockId1 = 1 const lockId2 = 2 // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // register data - this won't happen with real app, as ACLs will be working! await registry.add(data) // create application @@ -119,7 +124,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const lockId2 = 2 const emptyData = "" // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // register data - this won't happen with real app, as ACLs will be working! await registry.add(data) // create application @@ -130,7 +136,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new Application if Curation is not unlocker', async () => { // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, owner, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, owner, "") // create application return assertRevert(async () => { await curation.newApplication(data, appLockId, { from: applicant }) @@ -139,7 +146,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new Application if lock deposit is not enough', async () => { // mock lock - await staking.setLock(minDeposit - 1, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit - 1, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // create application return assertRevert(async () => { await curation.newApplication(data, appLockId, { from: applicant }) @@ -148,7 +156,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new Application if lock time unit is not seconds', async () => { // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS + 1, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS + 1, startLock, MAX_UINT64, curation.address, "") // create application return assertRevert(async () => { await curation.newApplication(data, appLockId, { from: applicant }) @@ -157,7 +166,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new Application if lock time is not enough', async () => { // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64 - 1, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64 - 1, curation.address, "") // create application return assertRevert(async () => { await curation.newApplication(data, appLockId, { from: applicant }) @@ -169,7 +179,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const applyAndChallenge = async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -205,7 +216,7 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await curation.setMinDeposit(minDeposit + 1) // mock lock - no need for lock - await staking.setLock(0, TIME_UNIT_SECONDS, 0, zeroAddress, "") + await staking.setLock(0, TIME_UNIT_SECONDS, 0, 0, zeroAddress, "") // challenge const receipt = await curation.challengeApplication(entryId, challengeLockId, { from: challenger }) // no challenge has been created @@ -221,7 +232,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails challenging with an already used lock', async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // use challenger's lock for an application await curation.newApplication("test 2", appLockId, { from: challenger }) // mock vote Id @@ -244,7 +256,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails challenging application if Curation is not unlocker', async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), owner, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), owner, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -256,7 +269,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails challenging application if lock deposit is not enough', async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit - 1, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit - 1, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -268,7 +282,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails challenging application if lock time unit is not seconds', async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS + 1, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS + 1, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -280,7 +295,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails challenging application if lock time is not enough', async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen - 1), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen - 1), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -360,7 +376,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { await curation.registerUnchallengedApplication(entryId) // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -429,7 +446,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails resolving challenge if vote has not ended', async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -533,7 +551,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge @@ -644,7 +663,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('fails creating new application', async () => { const lockId = 1 // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await getTimestamp() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") return assertRevert(async () => { await curation.newApplication("test", lockId) }) @@ -723,7 +743,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { it('creates new Application', async () => { // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await getTimestamp() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") // create application const r = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r, "NewApplication", "entryId") diff --git a/test/mocks/StakingMock.sol b/test/mocks/StakingMock.sol index c4ca63a..443320a 100644 --- a/test/mocks/StakingMock.sol +++ b/test/mocks/StakingMock.sol @@ -6,6 +6,7 @@ import "@aragon/apps-staking/contracts/interfaces/IStaking.sol"; contract StakingMock is IStaking { uint256 amount; uint8 lockUnit; + uint64 lockStarts; uint64 lockEnds; address unlocker; bytes32 metadata; @@ -14,15 +15,16 @@ contract StakingMock is IStaking { event UnlockedPartial(address indexed account, address indexed unlocker, uint256 indexed lockId, uint256 amount); event MovedTokens(address indexed from, address indexed to, uint256 amount); - function setLock(uint256 _amount, uint8 _lockUnit, uint64 _lockEnds, address _unlocker, bytes32 _metadata) public { + function setLock(uint256 _amount, uint8 _lockUnit, uint64 _lockStarts, uint64 _lockEnds, address _unlocker, bytes32 _metadata) public { amount = _amount; lockUnit = _lockUnit; + lockStarts = _lockStarts; lockEnds = _lockEnds; unlocker = _unlocker; } - function unlock(address acct, uint256 lockId) public { - Unlocked(acct, msg.sender, lockId); + function unlock(address _acct, uint256 _lockId) public { + Unlocked(_acct, msg.sender, _lockId); } function moveTokens(address _from, address _to, uint256 _amount) public { @@ -30,12 +32,28 @@ contract StakingMock is IStaking { } function unlockPartialAndMoveTokens(address _from, uint256 _lockId, address _to, uint256 _amount) external { - UnlockedPartial(_from, msg.sender, _lockId, amount); + UnlockedPartial(_from, msg.sender, _lockId, _amount); MovedTokens(_from, _to, _amount); } - function getLock(address _acct, uint256 _lockId) public view returns (uint256, uint8, uint64, address, bytes32) { - return (amount, lockUnit, lockEnds, unlocker, metadata); + function getLock( + address acct, + uint256 lockId + ) + public + view + returns ( + uint256 _amount, + uint8 _lockUnit, + uint64 _lockStarts, + uint64 _lockEnds, + address _unlocker, + bytes32 _metadata, + uint256 _prevUnlockerLockId, + uint256 _nextUnlockerLockId + ) + { + return (amount, lockUnit, lockStarts, lockEnds, unlocker, metadata, 0, 0); } diff --git a/test/script.js b/test/script.js index b0c5119..d756c3a 100644 --- a/test/script.js +++ b/test/script.js @@ -26,7 +26,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const createApplication = async () => { // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, MAX_UINT64, curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, MAX_UINT64, curation.address, "") const r = await curation.newApplication(data, appLockId, { from: applicant }) const entryId = getEvent(r, "NewApplication", "entryId") @@ -36,7 +37,8 @@ contract('Curation', ([owner, applicant, challenger, voter, _]) => { const applyAndChallenge = async () => { const entryId = await createApplication() // mock lock - await staking.setLock(minDeposit, TIME_UNIT_SECONDS, (await curation.getTimestampExt.call()).add(applyStageLen + 1000), curation.address, "") + const startLock = await curation.getTimestampExt.call() + await staking.setLock(minDeposit, TIME_UNIT_SECONDS, startLock, startLock.add(applyStageLen + 1000), curation.address, "") // mock vote Id await voting.setVoteId(voteId) // challenge